icbm_test.go 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600
  1. package handler
  2. import (
  3. "testing"
  4. "github.com/mkaminski/goaim/oscar"
  5. "github.com/mkaminski/goaim/state"
  6. "github.com/stretchr/testify/assert"
  7. "github.com/stretchr/testify/mock"
  8. )
  9. func TestSendAndReceiveChannelMsgToHost(t *testing.T) {
  10. cases := []struct {
  11. // name is the unit test name
  12. name string
  13. // blockedState is the response to the sender/recipient block check
  14. blockedState state.BlockedState
  15. // recipRetrieveErr is the error returned by the recipient session
  16. // lookup
  17. recipRetrieveErr error
  18. senderSession *state.Session
  19. recipientSession *state.Session
  20. // inputSNAC is the SNAC sent by the sender client
  21. inputSNAC oscar.SNACMessage
  22. // expectSNACToClient is the SNAC sent from the server to the
  23. // recipient client
  24. expectSNACToClient oscar.SNACMessage
  25. // inputSNAC is the SNAC frame sent from the server to the recipient
  26. // client
  27. expectOutput *oscar.SNACMessage
  28. }{
  29. {
  30. name: "transmit message from sender to recipient, ack message back to sender",
  31. blockedState: state.BlockedNo,
  32. senderSession: newTestSession("sender-screen-name", sessOptWarning(10)),
  33. recipientSession: newTestSession("recipient-screen-name", sessOptWarning(20)),
  34. inputSNAC: oscar.SNACMessage{
  35. Frame: oscar.SNACFrame{
  36. RequestID: 1234,
  37. },
  38. Body: oscar.SNAC_0x04_0x06_ICBMChannelMsgToHost{
  39. ScreenName: "recipient-screen-name",
  40. TLVRestBlock: oscar.TLVRestBlock{
  41. TLVList: oscar.TLVList{
  42. {
  43. TType: oscar.ICBMTLVTagRequestHostAck,
  44. Val: []byte{},
  45. },
  46. },
  47. },
  48. },
  49. },
  50. expectSNACToClient: oscar.SNACMessage{
  51. Frame: oscar.SNACFrame{
  52. FoodGroup: oscar.ICBM,
  53. SubGroup: oscar.ICBMChannelMsgToClient,
  54. },
  55. Body: oscar.SNAC_0x04_0x07_ICBMChannelMsgToClient{
  56. TLVUserInfo: oscar.TLVUserInfo{
  57. ScreenName: "sender-screen-name",
  58. WarningLevel: 10,
  59. },
  60. TLVRestBlock: oscar.TLVRestBlock{
  61. TLVList: oscar.TLVList{
  62. {
  63. TType: oscar.ICBMTLVTagsWantEvents,
  64. Val: []byte{},
  65. },
  66. {
  67. TType: oscar.ICBMTLVTagRequestHostAck,
  68. Val: []byte{},
  69. },
  70. },
  71. },
  72. },
  73. },
  74. expectOutput: &oscar.SNACMessage{
  75. Frame: oscar.SNACFrame{
  76. FoodGroup: oscar.ICBM,
  77. SubGroup: oscar.ICBMHostAck,
  78. RequestID: 1234,
  79. },
  80. Body: oscar.SNAC_0x04_0x0C_ICBMHostAck{
  81. ScreenName: "recipient-screen-name",
  82. },
  83. },
  84. },
  85. {
  86. name: "transmit message from sender to recipient, don't ack message back to sender",
  87. blockedState: state.BlockedNo,
  88. senderSession: newTestSession("sender-screen-name", sessOptWarning(10)),
  89. recipientSession: newTestSession("recipient-screen-name", sessOptWarning(20)),
  90. inputSNAC: oscar.SNACMessage{
  91. Frame: oscar.SNACFrame{
  92. RequestID: 1234,
  93. },
  94. Body: oscar.SNAC_0x04_0x06_ICBMChannelMsgToHost{
  95. ScreenName: "recipient-screen-name",
  96. TLVRestBlock: oscar.TLVRestBlock{
  97. TLVList: oscar.TLVList{},
  98. },
  99. },
  100. },
  101. expectSNACToClient: oscar.SNACMessage{
  102. Frame: oscar.SNACFrame{
  103. FoodGroup: oscar.ICBM,
  104. SubGroup: oscar.ICBMChannelMsgToClient,
  105. },
  106. Body: oscar.SNAC_0x04_0x07_ICBMChannelMsgToClient{
  107. TLVUserInfo: oscar.TLVUserInfo{
  108. ScreenName: "sender-screen-name",
  109. WarningLevel: 10,
  110. },
  111. TLVRestBlock: oscar.TLVRestBlock{
  112. TLVList: oscar.TLVList{
  113. {
  114. TType: oscar.ICBMTLVTagsWantEvents,
  115. Val: []byte{},
  116. },
  117. },
  118. },
  119. },
  120. },
  121. expectOutput: nil,
  122. },
  123. {
  124. name: "don't transmit message from sender to recipient because sender has blocked recipient",
  125. blockedState: state.BlockedA,
  126. senderSession: newTestSession("sender-screen-name", sessOptWarning(10)),
  127. recipientSession: newTestSession("recipient-screen-name", sessOptWarning(20)),
  128. inputSNAC: oscar.SNACMessage{
  129. Frame: oscar.SNACFrame{
  130. RequestID: 1234,
  131. },
  132. Body: oscar.SNAC_0x04_0x06_ICBMChannelMsgToHost{
  133. ScreenName: "recipient-screen-name",
  134. TLVRestBlock: oscar.TLVRestBlock{
  135. TLVList: oscar.TLVList{
  136. {
  137. TType: oscar.ICBMTLVTagRequestHostAck,
  138. Val: []byte{},
  139. },
  140. },
  141. },
  142. },
  143. },
  144. expectOutput: &oscar.SNACMessage{
  145. Frame: oscar.SNACFrame{
  146. FoodGroup: oscar.ICBM,
  147. SubGroup: oscar.ICBMErr,
  148. RequestID: 1234,
  149. },
  150. Body: oscar.SNACError{
  151. Code: oscar.ErrorCodeInLocalPermitDeny,
  152. },
  153. },
  154. },
  155. {
  156. name: "don't transmit message from sender to recipient because recipient has blocked sender",
  157. blockedState: state.BlockedB,
  158. senderSession: newTestSession("sender-screen-name", sessOptWarning(10)),
  159. recipientSession: newTestSession("recipient-screen-name", sessOptWarning(20)),
  160. inputSNAC: oscar.SNACMessage{
  161. Frame: oscar.SNACFrame{
  162. RequestID: 1234,
  163. },
  164. Body: oscar.SNAC_0x04_0x06_ICBMChannelMsgToHost{
  165. ScreenName: "recipient-screen-name",
  166. TLVRestBlock: oscar.TLVRestBlock{
  167. TLVList: oscar.TLVList{
  168. {
  169. TType: oscar.ICBMTLVTagRequestHostAck,
  170. Val: []byte{},
  171. },
  172. },
  173. },
  174. },
  175. },
  176. expectOutput: &oscar.SNACMessage{
  177. Frame: oscar.SNACFrame{
  178. FoodGroup: oscar.ICBM,
  179. SubGroup: oscar.ICBMErr,
  180. RequestID: 1234,
  181. },
  182. Body: oscar.SNACError{
  183. Code: oscar.ErrorCodeNotLoggedOn,
  184. },
  185. },
  186. },
  187. {
  188. name: "don't transmit message from sender to recipient because recipient doesn't exist",
  189. blockedState: state.BlockedNo,
  190. senderSession: newTestSession("sender-screen-name", sessOptWarning(10)),
  191. recipientSession: nil,
  192. inputSNAC: oscar.SNACMessage{
  193. Frame: oscar.SNACFrame{
  194. RequestID: 1234,
  195. },
  196. Body: oscar.SNAC_0x04_0x06_ICBMChannelMsgToHost{
  197. ScreenName: "recipient-screen-name",
  198. TLVRestBlock: oscar.TLVRestBlock{
  199. TLVList: oscar.TLVList{
  200. {
  201. TType: oscar.ICBMTLVTagRequestHostAck,
  202. Val: []byte{},
  203. },
  204. },
  205. },
  206. },
  207. },
  208. expectOutput: &oscar.SNACMessage{
  209. Frame: oscar.SNACFrame{
  210. FoodGroup: oscar.ICBM,
  211. SubGroup: oscar.ICBMErr,
  212. RequestID: 1234,
  213. },
  214. Body: oscar.SNACError{
  215. Code: oscar.ErrorCodeNotLoggedOn,
  216. },
  217. },
  218. },
  219. }
  220. for _, tc := range cases {
  221. t.Run(tc.name, func(t *testing.T) {
  222. //
  223. // initialize dependencies
  224. //
  225. feedbagManager := newMockFeedbagManager(t)
  226. feedbagManager.EXPECT().
  227. Blocked(tc.senderSession.ScreenName(),
  228. tc.inputSNAC.Body.(oscar.SNAC_0x04_0x06_ICBMChannelMsgToHost).ScreenName).
  229. Return(tc.blockedState, nil).
  230. Maybe()
  231. messageRelayer := newMockMessageRelayer(t)
  232. messageRelayer.EXPECT().
  233. RetrieveByScreenName(tc.inputSNAC.Body.(oscar.SNAC_0x04_0x06_ICBMChannelMsgToHost).ScreenName).
  234. Return(tc.recipientSession).
  235. Maybe()
  236. if tc.recipientSession != nil {
  237. messageRelayer.EXPECT().
  238. SendToScreenName(mock.Anything, tc.recipientSession.ScreenName(), tc.expectSNACToClient).
  239. Maybe()
  240. }
  241. //
  242. // send input SNAC
  243. //
  244. svc := ICBMService{
  245. messageRelayer: messageRelayer,
  246. feedbagManager: feedbagManager,
  247. }
  248. outputSNAC, err := svc.ChannelMsgToHostHandler(nil, tc.senderSession, tc.inputSNAC.Frame,
  249. tc.inputSNAC.Body.(oscar.SNAC_0x04_0x06_ICBMChannelMsgToHost))
  250. assert.NoError(t, err)
  251. //
  252. // verify output
  253. //
  254. assert.Equal(t, tc.expectOutput, outputSNAC)
  255. })
  256. }
  257. }
  258. func TestSendAndReceiveClientEvent(t *testing.T) {
  259. cases := []struct {
  260. // name is the unit test name
  261. name string
  262. // blockedState is the response to the sender/recipient block check
  263. blockedState state.BlockedState
  264. // senderScreenName is the screen name of the user sending the event
  265. senderScreenName string
  266. // inputSNAC is the SNAC sent by the sender client
  267. inputSNAC oscar.SNACMessage
  268. // expectSNACToClient is the SNAC sent from the server to the
  269. // recipient client
  270. expectSNACToClient oscar.SNACMessage
  271. }{
  272. {
  273. name: "transmit message from sender to recipient",
  274. blockedState: state.BlockedNo,
  275. senderScreenName: "sender-screen-name",
  276. inputSNAC: oscar.SNACMessage{
  277. Frame: oscar.SNACFrame{
  278. RequestID: 1234,
  279. },
  280. Body: oscar.SNAC_0x04_0x14_ICBMClientEvent{
  281. Cookie: [8]byte{1, 2, 3, 4, 5, 6, 7, 8},
  282. ChannelID: 42,
  283. ScreenName: "recipient-screen-name",
  284. Event: 12,
  285. },
  286. },
  287. expectSNACToClient: oscar.SNACMessage{
  288. Frame: oscar.SNACFrame{
  289. FoodGroup: oscar.ICBM,
  290. SubGroup: oscar.ICBMClientEvent,
  291. RequestID: 1234,
  292. },
  293. Body: oscar.SNAC_0x04_0x14_ICBMClientEvent{
  294. Cookie: [8]byte{1, 2, 3, 4, 5, 6, 7, 8},
  295. ChannelID: 42,
  296. ScreenName: "sender-screen-name",
  297. Event: 12,
  298. },
  299. },
  300. },
  301. {
  302. name: "don't transmit message from sender to recipient because sender has blocked recipient",
  303. blockedState: state.BlockedA,
  304. senderScreenName: "sender-screen-name",
  305. inputSNAC: oscar.SNACMessage{
  306. Frame: oscar.SNACFrame{
  307. RequestID: 1234,
  308. },
  309. Body: oscar.SNAC_0x04_0x14_ICBMClientEvent{
  310. ScreenName: "recipient-screen-name",
  311. },
  312. },
  313. },
  314. }
  315. for _, tc := range cases {
  316. t.Run(tc.name, func(t *testing.T) {
  317. //
  318. // initialize dependencies
  319. //
  320. feedbagManager := newMockFeedbagManager(t)
  321. feedbagManager.EXPECT().
  322. Blocked(tc.senderScreenName, tc.inputSNAC.Body.(oscar.SNAC_0x04_0x14_ICBMClientEvent).ScreenName).
  323. Return(tc.blockedState, nil).
  324. Maybe()
  325. messageRelayer := newMockMessageRelayer(t)
  326. if tc.blockedState == state.BlockedNo {
  327. messageRelayer.EXPECT().
  328. SendToScreenName(mock.Anything, tc.inputSNAC.Body.(oscar.SNAC_0x04_0x14_ICBMClientEvent).ScreenName,
  329. tc.expectSNACToClient)
  330. }
  331. //
  332. // send input SNAC
  333. //
  334. senderSession := newTestSession(tc.senderScreenName)
  335. svc := ICBMService{
  336. messageRelayer: messageRelayer,
  337. feedbagManager: feedbagManager,
  338. }
  339. assert.NoError(t, svc.ClientEventHandler(nil, senderSession, tc.inputSNAC.Frame,
  340. tc.inputSNAC.Body.(oscar.SNAC_0x04_0x14_ICBMClientEvent)))
  341. })
  342. }
  343. }
  344. func TestSendAndReceiveEvilRequest(t *testing.T) {
  345. cases := []struct {
  346. // name is the unit test name
  347. name string
  348. // blockedState is the response to the sender/recipient block check
  349. blockedState state.BlockedState
  350. // recipRetrieveErr is the error returned by the recipient session
  351. // lookup
  352. recipRetrieveErr error
  353. // senderScreenName is the session name of the user sending the IM
  354. senderSession *state.Session
  355. // recipientScreenName is the screen name of the user receiving the IM
  356. recipientScreenName string
  357. // recipientBuddies is a list of the recipient's buddies that get
  358. // updated warning level
  359. recipientBuddies []string
  360. broadcastMessage oscar.SNACMessage
  361. // inputSNAC is the SNAC sent by the sender client
  362. inputSNAC oscar.SNACMessage
  363. // expectSNACToClient is the SNAC sent from the server to the
  364. // recipient client
  365. expectSNACToClient oscar.SNACMessage
  366. expectOutput oscar.SNACMessage
  367. }{
  368. {
  369. name: "transmit anonymous warning from sender to recipient",
  370. blockedState: state.BlockedNo,
  371. senderSession: newTestSession("sender-screen-name"),
  372. recipientScreenName: "recipient-screen-name",
  373. broadcastMessage: oscar.SNACMessage{
  374. Frame: oscar.SNACFrame{
  375. FoodGroup: oscar.Buddy,
  376. SubGroup: oscar.BuddyArrived,
  377. },
  378. Body: oscar.SNAC_0x03_0x0B_BuddyArrived{
  379. TLVUserInfo: oscar.TLVUserInfo{
  380. ScreenName: "recipient-screen-name",
  381. WarningLevel: evilDeltaAnon,
  382. TLVBlock: oscar.TLVBlock{
  383. TLVList: newTestSession("", sessOptCannedSignonTime).UserInfo(),
  384. },
  385. },
  386. },
  387. },
  388. recipientBuddies: []string{"buddy1", "buddy2"},
  389. inputSNAC: oscar.SNACMessage{
  390. Frame: oscar.SNACFrame{
  391. RequestID: 1234,
  392. },
  393. Body: oscar.SNAC_0x04_0x08_ICBMEvilRequest{
  394. SendAs: 1, // make it anonymous
  395. ScreenName: "recipient-screen-name",
  396. },
  397. },
  398. expectSNACToClient: oscar.SNACMessage{
  399. Frame: oscar.SNACFrame{
  400. FoodGroup: oscar.OService,
  401. SubGroup: oscar.OServiceEvilNotification,
  402. },
  403. Body: oscar.SNAC_0x01_0x10_OServiceEvilNotificationAnon{
  404. NewEvil: evilDeltaAnon,
  405. },
  406. },
  407. expectOutput: oscar.SNACMessage{
  408. Frame: oscar.SNACFrame{
  409. FoodGroup: oscar.ICBM,
  410. SubGroup: oscar.ICBMEvilReply,
  411. RequestID: 1234,
  412. },
  413. Body: oscar.SNAC_0x04_0x09_ICBMEvilReply{
  414. EvilDeltaApplied: 30,
  415. UpdatedEvilValue: 30,
  416. },
  417. },
  418. },
  419. {
  420. name: "transmit non-anonymous warning from sender to recipient",
  421. blockedState: state.BlockedNo,
  422. senderSession: newTestSession("sender-screen-name"),
  423. recipientScreenName: "recipient-screen-name",
  424. recipientBuddies: []string{"buddy1", "buddy2"},
  425. broadcastMessage: oscar.SNACMessage{
  426. Frame: oscar.SNACFrame{
  427. FoodGroup: oscar.Buddy,
  428. SubGroup: oscar.BuddyArrived,
  429. },
  430. Body: oscar.SNAC_0x03_0x0B_BuddyArrived{
  431. TLVUserInfo: oscar.TLVUserInfo{
  432. ScreenName: "recipient-screen-name",
  433. WarningLevel: evilDelta,
  434. TLVBlock: oscar.TLVBlock{
  435. TLVList: newTestSession("", sessOptCannedSignonTime).UserInfo(),
  436. },
  437. },
  438. },
  439. },
  440. inputSNAC: oscar.SNACMessage{
  441. Frame: oscar.SNACFrame{
  442. RequestID: 1234,
  443. },
  444. Body: oscar.SNAC_0x04_0x08_ICBMEvilRequest{
  445. SendAs: 0, // make it identified
  446. ScreenName: "recipient-screen-name",
  447. },
  448. },
  449. expectSNACToClient: oscar.SNACMessage{
  450. Frame: oscar.SNACFrame{
  451. FoodGroup: oscar.OService,
  452. SubGroup: oscar.OServiceEvilNotification,
  453. },
  454. Body: oscar.SNAC_0x01_0x10_OServiceEvilNotification{
  455. NewEvil: evilDelta,
  456. TLVUserInfo: oscar.TLVUserInfo{
  457. ScreenName: "sender-screen-name",
  458. WarningLevel: 100,
  459. },
  460. },
  461. },
  462. expectOutput: oscar.SNACMessage{
  463. Frame: oscar.SNACFrame{
  464. FoodGroup: oscar.ICBM,
  465. SubGroup: oscar.ICBMEvilReply,
  466. RequestID: 1234,
  467. },
  468. Body: oscar.SNAC_0x04_0x09_ICBMEvilReply{
  469. EvilDeltaApplied: 100,
  470. UpdatedEvilValue: 100,
  471. },
  472. },
  473. },
  474. {
  475. name: "don't transmit non-anonymous warning from sender to recipient because sender has blocked recipient",
  476. blockedState: state.BlockedA,
  477. senderSession: newTestSession("sender-screen-name"),
  478. recipientScreenName: "recipient-screen-name",
  479. recipientBuddies: []string{"buddy1", "buddy2"},
  480. inputSNAC: oscar.SNACMessage{
  481. Frame: oscar.SNACFrame{
  482. RequestID: 1234,
  483. },
  484. Body: oscar.SNAC_0x04_0x08_ICBMEvilRequest{
  485. SendAs: 0, // make it identified
  486. ScreenName: "recipient-screen-name",
  487. },
  488. },
  489. expectOutput: oscar.SNACMessage{
  490. Frame: oscar.SNACFrame{
  491. FoodGroup: oscar.ICBM,
  492. SubGroup: oscar.ICBMErr,
  493. RequestID: 1234,
  494. },
  495. Body: oscar.SNACError{
  496. Code: oscar.ErrorCodeNotLoggedOn,
  497. },
  498. },
  499. },
  500. {
  501. name: "don't transmit non-anonymous warning from sender to recipient because recipient has blocked sender",
  502. blockedState: state.BlockedB,
  503. senderSession: newTestSession("sender-screen-name"),
  504. recipientScreenName: "recipient-screen-name",
  505. recipientBuddies: []string{"buddy1", "buddy2"},
  506. inputSNAC: oscar.SNACMessage{
  507. Frame: oscar.SNACFrame{
  508. RequestID: 1234,
  509. },
  510. Body: oscar.SNAC_0x04_0x08_ICBMEvilRequest{
  511. SendAs: 0, // make it identified
  512. ScreenName: "recipient-screen-name",
  513. },
  514. },
  515. expectOutput: oscar.SNACMessage{
  516. Frame: oscar.SNACFrame{
  517. FoodGroup: oscar.ICBM,
  518. SubGroup: oscar.ICBMErr,
  519. RequestID: 1234,
  520. },
  521. Body: oscar.SNACError{
  522. Code: oscar.ErrorCodeNotLoggedOn,
  523. },
  524. },
  525. },
  526. {
  527. name: "don't let users block themselves",
  528. senderSession: newTestSession("sender-screen-name"),
  529. recipientScreenName: "sender-screen-name",
  530. inputSNAC: oscar.SNACMessage{
  531. Frame: oscar.SNACFrame{
  532. RequestID: 1234,
  533. },
  534. Body: oscar.SNAC_0x04_0x08_ICBMEvilRequest{
  535. SendAs: 0, // make it identified
  536. ScreenName: "sender-screen-name",
  537. },
  538. },
  539. expectOutput: oscar.SNACMessage{
  540. Frame: oscar.SNACFrame{
  541. FoodGroup: oscar.ICBM,
  542. SubGroup: oscar.ICBMErr,
  543. RequestID: 1234,
  544. },
  545. Body: oscar.SNACError{
  546. Code: oscar.ErrorCodeNotSupportedByHost,
  547. },
  548. },
  549. },
  550. }
  551. for _, tc := range cases {
  552. t.Run(tc.name, func(t *testing.T) {
  553. //
  554. // initialize dependencies
  555. //
  556. feedbagManager := newMockFeedbagManager(t)
  557. feedbagManager.EXPECT().
  558. Blocked(tc.senderSession.ScreenName(), tc.recipientScreenName).
  559. Return(tc.blockedState, nil).
  560. Maybe()
  561. feedbagManager.EXPECT().
  562. InterestedUsers(tc.recipientScreenName).
  563. Return(tc.recipientBuddies, nil).
  564. Maybe()
  565. recipSess := newTestSession(tc.recipientScreenName, sessOptCannedSignonTime)
  566. messageRelayer := newMockMessageRelayer(t)
  567. messageRelayer.EXPECT().
  568. RetrieveByScreenName(tc.recipientScreenName).
  569. Return(recipSess).
  570. Maybe()
  571. messageRelayer.EXPECT().
  572. SendToScreenName(mock.Anything, tc.recipientScreenName, tc.expectSNACToClient).
  573. Maybe()
  574. messageRelayer.EXPECT().
  575. BroadcastToScreenNames(mock.Anything, tc.recipientBuddies, tc.broadcastMessage).
  576. Maybe()
  577. //
  578. // send input SNAC
  579. //
  580. senderSession := newTestSession(tc.senderSession.ScreenName())
  581. svc := ICBMService{
  582. messageRelayer: messageRelayer,
  583. feedbagManager: feedbagManager,
  584. }
  585. outputSNAC, err := svc.EvilRequestHandler(nil, senderSession, tc.inputSNAC.Frame,
  586. tc.inputSNAC.Body.(oscar.SNAC_0x04_0x08_ICBMEvilRequest))
  587. assert.NoError(t, err)
  588. assert.Equal(t, tc.expectOutput, outputSNAC)
  589. })
  590. }
  591. }