feedbag_test.go 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338
  1. package handler
  2. import (
  3. "testing"
  4. "time"
  5. "github.com/mk6i/retro-aim-server/oscar"
  6. "github.com/mk6i/retro-aim-server/state"
  7. "github.com/stretchr/testify/assert"
  8. "github.com/stretchr/testify/mock"
  9. )
  10. func TestFeedbagService_QueryHandler(t *testing.T) {
  11. cases := []struct {
  12. // name is the unit test name
  13. name string
  14. // userSession is the session of the user adding to feedbag
  15. userSession *state.Session
  16. // inputSNAC is the SNAC sent from the client to the server
  17. inputSNAC oscar.SNACMessage
  18. // mockParams is the list of params sent to mocks that satisfy this
  19. // method's dependencies
  20. mockParams mockParams
  21. // expectOutput is the SNAC sent from the server to client
  22. expectOutput oscar.SNACMessage
  23. }{
  24. {
  25. name: "retrieve empty feedbag",
  26. userSession: newTestSession("user_screen_name"),
  27. inputSNAC: oscar.SNACMessage{
  28. Frame: oscar.SNACFrame{
  29. RequestID: 1234,
  30. },
  31. },
  32. mockParams: mockParams{
  33. feedbagManagerParams: feedbagManagerParams{
  34. feedbagParams: feedbagParams{
  35. {
  36. screenName: "user_screen_name",
  37. results: []oscar.FeedbagItem{},
  38. },
  39. },
  40. feedbagLastModifiedParams: feedbagLastModifiedParams{},
  41. },
  42. },
  43. expectOutput: oscar.SNACMessage{
  44. Frame: oscar.SNACFrame{
  45. FoodGroup: oscar.Feedbag,
  46. SubGroup: oscar.FeedbagReply,
  47. RequestID: 1234,
  48. },
  49. Body: oscar.SNAC_0x13_0x06_FeedbagReply{
  50. Items: []oscar.FeedbagItem{},
  51. },
  52. },
  53. },
  54. {
  55. name: "retrieve feedbag with items",
  56. userSession: newTestSession("user_screen_name"),
  57. inputSNAC: oscar.SNACMessage{
  58. Frame: oscar.SNACFrame{
  59. RequestID: 1234,
  60. },
  61. },
  62. mockParams: mockParams{
  63. feedbagManagerParams: feedbagManagerParams{
  64. feedbagParams: feedbagParams{
  65. {
  66. screenName: "user_screen_name",
  67. results: []oscar.FeedbagItem{
  68. {
  69. Name: "buddy_1",
  70. },
  71. {
  72. Name: "buddy_2",
  73. },
  74. },
  75. },
  76. },
  77. feedbagLastModifiedParams: feedbagLastModifiedParams{
  78. {
  79. screenName: "user_screen_name",
  80. result: time.UnixMilli(1696472198082),
  81. },
  82. },
  83. },
  84. },
  85. expectOutput: oscar.SNACMessage{
  86. Frame: oscar.SNACFrame{
  87. FoodGroup: oscar.Feedbag,
  88. SubGroup: oscar.FeedbagReply,
  89. RequestID: 1234,
  90. },
  91. Body: oscar.SNAC_0x13_0x06_FeedbagReply{
  92. Version: 0,
  93. Items: []oscar.FeedbagItem{
  94. {
  95. Name: "buddy_1",
  96. },
  97. {
  98. Name: "buddy_2",
  99. },
  100. },
  101. LastUpdate: uint32(time.UnixMilli(1696472198082).Unix()),
  102. },
  103. },
  104. },
  105. }
  106. for _, tc := range cases {
  107. t.Run(tc.name, func(t *testing.T) {
  108. feedbagManager := newMockFeedbagManager(t)
  109. for _, params := range tc.mockParams.feedbagParams {
  110. feedbagManager.EXPECT().
  111. Feedbag(params.screenName).
  112. Return(params.results, nil)
  113. }
  114. for _, params := range tc.mockParams.feedbagLastModifiedParams {
  115. feedbagManager.EXPECT().
  116. FeedbagLastModified(params.screenName).
  117. Return(params.result, nil)
  118. }
  119. svc := FeedbagService{
  120. feedbagManager: feedbagManager,
  121. }
  122. outputSNAC, err := svc.QueryHandler(nil, tc.userSession, tc.inputSNAC.Frame)
  123. assert.NoError(t, err)
  124. assert.Equal(t, tc.expectOutput, outputSNAC)
  125. })
  126. }
  127. }
  128. func TestFeedbagService_QueryIfModifiedHandler(t *testing.T) {
  129. cases := []struct {
  130. // name is the unit test name
  131. name string
  132. // userSession is the session of the user adding to feedbag
  133. userSession *state.Session
  134. // inputSNAC is the SNAC sent from the client to the server
  135. inputSNAC oscar.SNACMessage
  136. // mockParams is the list of params sent to mocks that satisfy this
  137. // method's dependencies
  138. mockParams mockParams
  139. // expectOutput is the SNAC sent from the server to client
  140. expectOutput oscar.SNACMessage
  141. }{
  142. {
  143. name: "retrieve empty feedbag",
  144. userSession: newTestSession("user_screen_name"),
  145. inputSNAC: oscar.SNACMessage{
  146. Frame: oscar.SNACFrame{
  147. RequestID: 1234,
  148. },
  149. Body: oscar.SNAC_0x13_0x05_FeedbagQueryIfModified{
  150. LastUpdate: uint32(time.UnixMilli(100000).Unix()),
  151. },
  152. },
  153. mockParams: mockParams{
  154. feedbagManagerParams: feedbagManagerParams{
  155. feedbagParams: feedbagParams{
  156. {
  157. screenName: "user_screen_name",
  158. results: []oscar.FeedbagItem{},
  159. },
  160. },
  161. },
  162. },
  163. expectOutput: oscar.SNACMessage{
  164. Frame: oscar.SNACFrame{
  165. FoodGroup: oscar.Feedbag,
  166. SubGroup: oscar.FeedbagReply,
  167. RequestID: 1234,
  168. },
  169. Body: oscar.SNAC_0x13_0x06_FeedbagReply{
  170. Items: []oscar.FeedbagItem{},
  171. },
  172. },
  173. },
  174. {
  175. name: "retrieve feedbag with items",
  176. userSession: newTestSession("user_screen_name"),
  177. inputSNAC: oscar.SNACMessage{
  178. Frame: oscar.SNACFrame{
  179. RequestID: 1234,
  180. },
  181. Body: oscar.SNAC_0x13_0x05_FeedbagQueryIfModified{
  182. LastUpdate: uint32(time.UnixMilli(100000).Unix()),
  183. },
  184. },
  185. mockParams: mockParams{
  186. feedbagManagerParams: feedbagManagerParams{
  187. feedbagParams: feedbagParams{
  188. {
  189. screenName: "user_screen_name",
  190. results: []oscar.FeedbagItem{
  191. {
  192. Name: "buddy_1",
  193. },
  194. {
  195. Name: "buddy_2",
  196. },
  197. },
  198. },
  199. },
  200. feedbagLastModifiedParams: feedbagLastModifiedParams{
  201. {
  202. screenName: "user_screen_name",
  203. result: time.UnixMilli(200000),
  204. },
  205. },
  206. },
  207. },
  208. expectOutput: oscar.SNACMessage{
  209. Frame: oscar.SNACFrame{
  210. FoodGroup: oscar.Feedbag,
  211. SubGroup: oscar.FeedbagReply,
  212. RequestID: 1234,
  213. },
  214. Body: oscar.SNAC_0x13_0x06_FeedbagReply{
  215. Version: 0,
  216. Items: []oscar.FeedbagItem{
  217. {
  218. Name: "buddy_1",
  219. },
  220. {
  221. Name: "buddy_2",
  222. },
  223. },
  224. LastUpdate: uint32(time.UnixMilli(200000).Unix()),
  225. },
  226. },
  227. },
  228. {
  229. name: "retrieve not-modified response",
  230. userSession: newTestSession("user_screen_name"),
  231. inputSNAC: oscar.SNACMessage{
  232. Frame: oscar.SNACFrame{
  233. RequestID: 1234,
  234. },
  235. Body: oscar.SNAC_0x13_0x05_FeedbagQueryIfModified{
  236. LastUpdate: uint32(time.UnixMilli(200000).Unix()),
  237. },
  238. },
  239. mockParams: mockParams{
  240. feedbagManagerParams: feedbagManagerParams{
  241. feedbagParams: feedbagParams{
  242. {
  243. screenName: "user_screen_name",
  244. results: []oscar.FeedbagItem{
  245. {
  246. Name: "buddy_1",
  247. },
  248. {
  249. Name: "buddy_2",
  250. },
  251. },
  252. },
  253. },
  254. feedbagLastModifiedParams: feedbagLastModifiedParams{
  255. {
  256. screenName: "user_screen_name",
  257. result: time.UnixMilli(100000),
  258. },
  259. },
  260. },
  261. },
  262. expectOutput: oscar.SNACMessage{
  263. Frame: oscar.SNACFrame{
  264. FoodGroup: oscar.Feedbag,
  265. SubGroup: oscar.FeedbagReplyNotModified,
  266. RequestID: 1234,
  267. },
  268. Body: oscar.SNAC_0x13_0x05_FeedbagQueryIfModified{
  269. LastUpdate: uint32(time.UnixMilli(100000).Unix()),
  270. Count: 2,
  271. },
  272. },
  273. },
  274. }
  275. for _, tc := range cases {
  276. t.Run(tc.name, func(t *testing.T) {
  277. //
  278. // initialize dependencies
  279. //
  280. feedbagManager := newMockFeedbagManager(t)
  281. for _, params := range tc.mockParams.feedbagParams {
  282. feedbagManager.EXPECT().
  283. Feedbag(params.screenName).
  284. Return(params.results, nil)
  285. }
  286. for _, params := range tc.mockParams.feedbagLastModifiedParams {
  287. feedbagManager.EXPECT().
  288. FeedbagLastModified(params.screenName).
  289. Return(params.result, nil)
  290. }
  291. //
  292. // send input SNAC
  293. //
  294. svc := FeedbagService{
  295. feedbagManager: feedbagManager,
  296. }
  297. outputSNAC, err := svc.QueryIfModifiedHandler(nil, tc.userSession, tc.inputSNAC.Frame,
  298. tc.inputSNAC.Body.(oscar.SNAC_0x13_0x05_FeedbagQueryIfModified))
  299. assert.NoError(t, err)
  300. //
  301. // verify output
  302. //
  303. assert.Equal(t, tc.expectOutput, outputSNAC)
  304. })
  305. }
  306. }
  307. func TestFeedbagService_RightsQueryHandler(t *testing.T) {
  308. svc := NewFeedbagService(nil, nil)
  309. outputSNAC := svc.RightsQueryHandler(nil, oscar.SNACFrame{RequestID: 1234})
  310. expectSNAC := oscar.SNACMessage{
  311. Frame: oscar.SNACFrame{
  312. FoodGroup: oscar.Feedbag,
  313. SubGroup: oscar.FeedbagRightsReply,
  314. RequestID: 1234,
  315. },
  316. Body: oscar.SNAC_0x13_0x03_FeedbagRightsReply{
  317. TLVRestBlock: oscar.TLVRestBlock{
  318. TLVList: oscar.TLVList{
  319. oscar.NewTLV(oscar.FeedbagRightsMaxItemAttrs, uint16(200)),
  320. oscar.NewTLV(oscar.FeedbagRightsMaxItemsByClass, []uint16{
  321. 0x3D,
  322. 0x3D,
  323. 0x64,
  324. 0x64,
  325. 0x01,
  326. 0x01,
  327. 0x32,
  328. 0x00,
  329. 0x00,
  330. 0x03,
  331. 0x00,
  332. 0x00,
  333. 0x00,
  334. 0x80,
  335. 0xFF,
  336. 0x14,
  337. 0xC8,
  338. 0x01,
  339. 0x00,
  340. 0x01,
  341. 0x00,
  342. }),
  343. oscar.NewTLV(oscar.FeedbagRightsMaxClientItems, uint16(200)),
  344. oscar.NewTLV(oscar.FeedbagRightsMaxItemNameLen, uint16(200)),
  345. oscar.NewTLV(oscar.FeedbagRightsMaxRecentBuddies, uint16(200)),
  346. oscar.NewTLV(oscar.FeedbagRightsInteractionBuddies, uint16(200)),
  347. oscar.NewTLV(oscar.FeedbagRightsInteractionHalfLife, uint16(200)),
  348. oscar.NewTLV(oscar.FeedbagRightsInteractionMaxScore, uint16(200)),
  349. oscar.NewTLV(oscar.FeedbagRightsMaxBuddiesPerGroup, uint16(200)),
  350. oscar.NewTLV(oscar.FeedbagRightsMaxMegaBots, uint16(200)),
  351. oscar.NewTLV(oscar.FeedbagRightsMaxSmartGroups, uint16(100)),
  352. },
  353. },
  354. },
  355. }
  356. assert.Equal(t, expectSNAC, outputSNAC)
  357. }
  358. func TestFeedbagService_InsertItemHandler(t *testing.T) {
  359. cases := []struct {
  360. // name is the unit test name
  361. name string
  362. // userSession is the session of the user adding to feedbag
  363. userSession *state.Session
  364. // inputSNAC is the SNAC sent from the client to the server
  365. inputSNAC oscar.SNACMessage
  366. // mockParams is the list of params sent to mocks that satisfy this
  367. // method's dependencies
  368. mockParams mockParams
  369. // expectOutput is the SNAC sent from the server to client
  370. expectOutput oscar.SNACMessage
  371. }{
  372. {
  373. name: "user adds online buddies to feedbag, receives buddy arrival notifications",
  374. userSession: newTestSession("user_screen_name"),
  375. inputSNAC: oscar.SNACMessage{
  376. Frame: oscar.SNACFrame{
  377. RequestID: 1234,
  378. },
  379. Body: oscar.SNAC_0x13_0x08_FeedbagInsertItem{
  380. Items: []oscar.FeedbagItem{
  381. {
  382. ClassID: oscar.FeedbagClassIDPermit,
  383. Name: "buddy_1_online",
  384. },
  385. {
  386. ClassID: oscar.FeedbagClassIDPermit,
  387. Name: "buddy_2_online",
  388. },
  389. },
  390. },
  391. },
  392. mockParams: mockParams{
  393. feedbagManagerParams: feedbagManagerParams{
  394. feedbagUpsertParams: feedbagUpsertParams{
  395. {
  396. screenName: "user_screen_name",
  397. items: []oscar.FeedbagItem{
  398. {
  399. ClassID: oscar.FeedbagClassIDPermit,
  400. Name: "buddy_1_online",
  401. },
  402. {
  403. ClassID: oscar.FeedbagClassIDPermit,
  404. Name: "buddy_2_online",
  405. },
  406. },
  407. },
  408. },
  409. },
  410. messageRelayerParams: messageRelayerParams{
  411. retrieveByScreenNameParams: retrieveByScreenNameParams{
  412. {
  413. screenName: "buddy_1_online",
  414. sess: newTestSession("buddy_1_online", sessOptCannedSignonTime),
  415. },
  416. {
  417. screenName: "buddy_2_online",
  418. sess: newTestSession("buddy_2_online", sessOptCannedSignonTime),
  419. },
  420. },
  421. sendToScreenNameParams: sendToScreenNameParams{
  422. {
  423. screenName: "user_screen_name",
  424. message: oscar.SNACMessage{
  425. Frame: oscar.SNACFrame{
  426. FoodGroup: oscar.Buddy,
  427. SubGroup: oscar.BuddyArrived,
  428. },
  429. Body: oscar.SNAC_0x03_0x0B_BuddyArrived{
  430. TLVUserInfo: newTestSession("buddy_1_online", sessOptCannedSignonTime).TLVUserInfo(),
  431. },
  432. },
  433. },
  434. {
  435. screenName: "user_screen_name",
  436. message: oscar.SNACMessage{
  437. Frame: oscar.SNACFrame{
  438. FoodGroup: oscar.Buddy,
  439. SubGroup: oscar.BuddyArrived,
  440. },
  441. Body: oscar.SNAC_0x03_0x0B_BuddyArrived{
  442. TLVUserInfo: newTestSession("buddy_2_online", sessOptCannedSignonTime).TLVUserInfo(),
  443. },
  444. },
  445. },
  446. },
  447. },
  448. },
  449. expectOutput: oscar.SNACMessage{
  450. Frame: oscar.SNACFrame{
  451. FoodGroup: oscar.Feedbag,
  452. SubGroup: oscar.FeedbagStatus,
  453. RequestID: 1234,
  454. },
  455. Body: oscar.SNAC_0x13_0x0E_FeedbagStatus{
  456. Results: []uint16{0x0000, 0x0000},
  457. },
  458. },
  459. },
  460. {
  461. name: "user adds offline buddy to feedbag, receives no buddy arrival notification",
  462. userSession: newTestSession("user_screen_name"),
  463. inputSNAC: oscar.SNACMessage{
  464. Frame: oscar.SNACFrame{
  465. RequestID: 1234,
  466. },
  467. Body: oscar.SNAC_0x13_0x08_FeedbagInsertItem{
  468. Items: []oscar.FeedbagItem{
  469. {
  470. ClassID: oscar.FeedbagClassIDPermit,
  471. Name: "buddy_offline",
  472. },
  473. },
  474. },
  475. },
  476. mockParams: mockParams{
  477. feedbagManagerParams: feedbagManagerParams{
  478. feedbagUpsertParams: feedbagUpsertParams{
  479. {
  480. screenName: "user_screen_name",
  481. items: []oscar.FeedbagItem{
  482. {
  483. ClassID: oscar.FeedbagClassIDPermit,
  484. Name: "buddy_offline",
  485. },
  486. },
  487. },
  488. },
  489. },
  490. messageRelayerParams: messageRelayerParams{
  491. retrieveByScreenNameParams: retrieveByScreenNameParams{
  492. {
  493. screenName: "buddy_offline",
  494. sess: nil,
  495. },
  496. },
  497. },
  498. },
  499. expectOutput: oscar.SNACMessage{
  500. Frame: oscar.SNACFrame{
  501. FoodGroup: oscar.Feedbag,
  502. SubGroup: oscar.FeedbagStatus,
  503. RequestID: 1234,
  504. },
  505. Body: oscar.SNAC_0x13_0x0E_FeedbagStatus{
  506. Results: []uint16{0x0000},
  507. },
  508. },
  509. },
  510. {
  511. name: "user adds invisible buddy to feedbag, receives no buddy arrival notification",
  512. userSession: newTestSession("user_screen_name"),
  513. inputSNAC: oscar.SNACMessage{
  514. Frame: oscar.SNACFrame{
  515. RequestID: 1234,
  516. },
  517. Body: oscar.SNAC_0x13_0x08_FeedbagInsertItem{
  518. Items: []oscar.FeedbagItem{
  519. {
  520. ClassID: oscar.FeedbagClassIDPermit,
  521. Name: "invisible_buddy_online",
  522. },
  523. },
  524. },
  525. },
  526. mockParams: mockParams{
  527. feedbagManagerParams: feedbagManagerParams{
  528. feedbagUpsertParams: feedbagUpsertParams{
  529. {
  530. screenName: "user_screen_name",
  531. items: []oscar.FeedbagItem{
  532. {
  533. ClassID: oscar.FeedbagClassIDPermit,
  534. Name: "invisible_buddy_online",
  535. },
  536. },
  537. },
  538. },
  539. },
  540. messageRelayerParams: messageRelayerParams{
  541. retrieveByScreenNameParams: retrieveByScreenNameParams{
  542. {
  543. screenName: "invisible_buddy_online",
  544. sess: newTestSession("invisible_buddy_online", sessOptInvisible),
  545. },
  546. },
  547. },
  548. },
  549. expectOutput: oscar.SNACMessage{
  550. Frame: oscar.SNACFrame{
  551. FoodGroup: oscar.Feedbag,
  552. SubGroup: oscar.FeedbagStatus,
  553. RequestID: 1234,
  554. },
  555. Body: oscar.SNAC_0x13_0x0E_FeedbagStatus{
  556. Results: []uint16{0x0000},
  557. },
  558. },
  559. },
  560. {
  561. name: "user blocks online buddy, buddy receives buddy departure notification",
  562. userSession: newTestSession("user_screen_name"),
  563. inputSNAC: oscar.SNACMessage{
  564. Frame: oscar.SNACFrame{
  565. RequestID: 1234,
  566. },
  567. Body: oscar.SNAC_0x13_0x08_FeedbagInsertItem{
  568. Items: []oscar.FeedbagItem{
  569. {
  570. ClassID: oscar.FeedbagClassIDDeny,
  571. Name: "buddy_1",
  572. },
  573. },
  574. },
  575. },
  576. mockParams: mockParams{
  577. feedbagManagerParams: feedbagManagerParams{
  578. feedbagUpsertParams: feedbagUpsertParams{
  579. {
  580. screenName: "user_screen_name",
  581. items: []oscar.FeedbagItem{
  582. {
  583. ClassID: oscar.FeedbagClassIDDeny,
  584. Name: "buddy_1",
  585. },
  586. },
  587. },
  588. },
  589. },
  590. messageRelayerParams: messageRelayerParams{
  591. retrieveByScreenNameParams: retrieveByScreenNameParams{
  592. {
  593. screenName: "buddy_1",
  594. sess: newTestSession("buddy_1"),
  595. },
  596. },
  597. sendToScreenNameParams: sendToScreenNameParams{
  598. {
  599. screenName: "buddy_1",
  600. message: oscar.SNACMessage{
  601. Frame: oscar.SNACFrame{
  602. FoodGroup: oscar.Buddy,
  603. SubGroup: oscar.BuddyDeparted,
  604. },
  605. Body: oscar.SNAC_0x03_0x0C_BuddyDeparted{
  606. TLVUserInfo: oscar.TLVUserInfo{
  607. ScreenName: "user_screen_name",
  608. WarningLevel: 0,
  609. },
  610. },
  611. },
  612. },
  613. },
  614. },
  615. },
  616. expectOutput: oscar.SNACMessage{
  617. Frame: oscar.SNACFrame{
  618. FoodGroup: oscar.Feedbag,
  619. SubGroup: oscar.FeedbagStatus,
  620. RequestID: 1234,
  621. },
  622. Body: oscar.SNAC_0x13_0x0E_FeedbagStatus{
  623. Results: []uint16{0x0000},
  624. },
  625. },
  626. },
  627. {
  628. name: "user blocks offline buddy, no buddy departure notification sent",
  629. userSession: newTestSession("user_screen_name"),
  630. inputSNAC: oscar.SNACMessage{
  631. Frame: oscar.SNACFrame{
  632. RequestID: 1234,
  633. },
  634. Body: oscar.SNAC_0x13_0x08_FeedbagInsertItem{
  635. Items: []oscar.FeedbagItem{
  636. {
  637. ClassID: oscar.FeedbagClassIDDeny,
  638. Name: "buddy_1",
  639. },
  640. },
  641. },
  642. },
  643. mockParams: mockParams{
  644. feedbagManagerParams: feedbagManagerParams{
  645. feedbagUpsertParams: feedbagUpsertParams{
  646. {
  647. screenName: "user_screen_name",
  648. items: []oscar.FeedbagItem{
  649. {
  650. ClassID: oscar.FeedbagClassIDDeny,
  651. Name: "buddy_1",
  652. },
  653. },
  654. },
  655. },
  656. },
  657. messageRelayerParams: messageRelayerParams{
  658. retrieveByScreenNameParams: retrieveByScreenNameParams{
  659. {
  660. screenName: "buddy_1",
  661. sess: nil,
  662. },
  663. },
  664. },
  665. },
  666. expectOutput: oscar.SNACMessage{
  667. Frame: oscar.SNACFrame{
  668. FoodGroup: oscar.Feedbag,
  669. SubGroup: oscar.FeedbagStatus,
  670. RequestID: 1234,
  671. },
  672. Body: oscar.SNAC_0x13_0x0E_FeedbagStatus{
  673. Results: []uint16{0x0000},
  674. },
  675. },
  676. },
  677. {
  678. name: "invisible user blocks online buddy, no buddy departure notification sent",
  679. userSession: newTestSession("user_screen_name", sessOptInvisible),
  680. inputSNAC: oscar.SNACMessage{
  681. Frame: oscar.SNACFrame{
  682. RequestID: 1234,
  683. },
  684. Body: oscar.SNAC_0x13_0x08_FeedbagInsertItem{
  685. Items: []oscar.FeedbagItem{
  686. {
  687. ClassID: oscar.FeedbagClassIDDeny,
  688. Name: "buddy_1",
  689. },
  690. },
  691. },
  692. },
  693. mockParams: mockParams{
  694. feedbagManagerParams: feedbagManagerParams{
  695. feedbagUpsertParams: feedbagUpsertParams{
  696. {
  697. screenName: "user_screen_name",
  698. items: []oscar.FeedbagItem{
  699. {
  700. ClassID: oscar.FeedbagClassIDDeny,
  701. Name: "buddy_1",
  702. },
  703. },
  704. },
  705. },
  706. },
  707. },
  708. expectOutput: oscar.SNACMessage{
  709. Frame: oscar.SNACFrame{
  710. FoodGroup: oscar.Feedbag,
  711. SubGroup: oscar.FeedbagStatus,
  712. RequestID: 1234,
  713. },
  714. Body: oscar.SNAC_0x13_0x0E_FeedbagStatus{
  715. Results: []uint16{0x0000},
  716. },
  717. },
  718. },
  719. {
  720. name: "user blocks themselves, receives error",
  721. userSession: newTestSession("user_screen_name"),
  722. inputSNAC: oscar.SNACMessage{
  723. Frame: oscar.SNACFrame{
  724. RequestID: 1234,
  725. },
  726. Body: oscar.SNAC_0x13_0x08_FeedbagInsertItem{
  727. Items: []oscar.FeedbagItem{
  728. {
  729. ClassID: oscar.FeedbagClassIDDeny,
  730. Name: "user_screen_name",
  731. },
  732. },
  733. },
  734. },
  735. expectOutput: oscar.SNACMessage{
  736. Frame: oscar.SNACFrame{
  737. FoodGroup: oscar.Feedbag,
  738. SubGroup: oscar.FeedbagErr,
  739. RequestID: 1234,
  740. },
  741. Body: oscar.SNACError{
  742. Code: oscar.ErrorCodeNotSupportedByHost,
  743. },
  744. },
  745. },
  746. }
  747. for _, tc := range cases {
  748. t.Run(tc.name, func(t *testing.T) {
  749. feedbagManager := newMockFeedbagManager(t)
  750. for _, params := range tc.mockParams.feedbagManagerParams.feedbagUpsertParams {
  751. feedbagManager.EXPECT().
  752. FeedbagUpsert(params.screenName, params.items).
  753. Return(nil)
  754. }
  755. messageRelayer := newMockMessageRelayer(t)
  756. for _, params := range tc.mockParams.messageRelayerParams.retrieveByScreenNameParams {
  757. messageRelayer.EXPECT().
  758. RetrieveByScreenName(params.screenName).
  759. Return(params.sess)
  760. }
  761. for _, params := range tc.mockParams.messageRelayerParams.sendToScreenNameParams {
  762. messageRelayer.EXPECT().
  763. RelayToScreenName(mock.Anything, params.screenName, params.message)
  764. }
  765. svc := FeedbagService{
  766. feedbagManager: feedbagManager,
  767. messageRelayer: messageRelayer,
  768. }
  769. output, err := svc.InsertItemHandler(nil, tc.userSession, tc.inputSNAC.Frame,
  770. tc.inputSNAC.Body.(oscar.SNAC_0x13_0x08_FeedbagInsertItem))
  771. assert.NoError(t, err)
  772. assert.Equal(t, output, tc.expectOutput)
  773. })
  774. }
  775. }
  776. func TestFeedbagService_UpdateItemHandler(t *testing.T) {
  777. cases := []struct {
  778. // name is the unit test name
  779. name string
  780. // userSession is the session of the user adding to feedbag
  781. userSession *state.Session
  782. // inputSNAC is the SNAC sent from the client to the server
  783. inputSNAC oscar.SNACMessage
  784. // mockParams is the list of params sent to mocks that satisfy this
  785. // method's dependencies
  786. mockParams mockParams
  787. // expectOutput is the SNAC sent from the server to client
  788. expectOutput oscar.SNACMessage
  789. }{
  790. {
  791. name: "user updates online buddies in feedbag, receives buddy arrival notifications",
  792. userSession: newTestSession("user_screen_name"),
  793. inputSNAC: oscar.SNACMessage{
  794. Frame: oscar.SNACFrame{
  795. RequestID: 1234,
  796. },
  797. Body: oscar.SNAC_0x13_0x09_FeedbagUpdateItem{
  798. Items: []oscar.FeedbagItem{
  799. {
  800. ClassID: oscar.FeedbagClassIDPermit,
  801. Name: "buddy_1_online",
  802. },
  803. {
  804. ClassID: oscar.FeedbagClassIDPermit,
  805. Name: "buddy_2_online",
  806. },
  807. },
  808. },
  809. },
  810. mockParams: mockParams{
  811. feedbagManagerParams: feedbagManagerParams{
  812. feedbagUpsertParams: feedbagUpsertParams{
  813. {
  814. screenName: "user_screen_name",
  815. items: []oscar.FeedbagItem{
  816. {
  817. ClassID: oscar.FeedbagClassIDPermit,
  818. Name: "buddy_1_online",
  819. },
  820. {
  821. ClassID: oscar.FeedbagClassIDPermit,
  822. Name: "buddy_2_online",
  823. },
  824. },
  825. },
  826. },
  827. },
  828. messageRelayerParams: messageRelayerParams{
  829. retrieveByScreenNameParams: retrieveByScreenNameParams{
  830. {
  831. screenName: "buddy_1_online",
  832. sess: newTestSession("buddy_1_online", sessOptCannedSignonTime),
  833. },
  834. {
  835. screenName: "buddy_2_online",
  836. sess: newTestSession("buddy_2_online", sessOptCannedSignonTime),
  837. },
  838. },
  839. sendToScreenNameParams: sendToScreenNameParams{
  840. {
  841. screenName: "user_screen_name",
  842. message: oscar.SNACMessage{
  843. Frame: oscar.SNACFrame{
  844. FoodGroup: oscar.Buddy,
  845. SubGroup: oscar.BuddyArrived,
  846. },
  847. Body: oscar.SNAC_0x03_0x0B_BuddyArrived{
  848. TLVUserInfo: newTestSession("buddy_1_online", sessOptCannedSignonTime).TLVUserInfo(),
  849. },
  850. },
  851. },
  852. {
  853. screenName: "user_screen_name",
  854. message: oscar.SNACMessage{
  855. Frame: oscar.SNACFrame{
  856. FoodGroup: oscar.Buddy,
  857. SubGroup: oscar.BuddyArrived,
  858. },
  859. Body: oscar.SNAC_0x03_0x0B_BuddyArrived{
  860. TLVUserInfo: newTestSession("buddy_2_online", sessOptCannedSignonTime).TLVUserInfo(),
  861. },
  862. },
  863. },
  864. },
  865. },
  866. },
  867. expectOutput: oscar.SNACMessage{
  868. Frame: oscar.SNACFrame{
  869. FoodGroup: oscar.Feedbag,
  870. SubGroup: oscar.FeedbagStatus,
  871. RequestID: 1234,
  872. },
  873. Body: oscar.SNAC_0x13_0x0E_FeedbagStatus{
  874. Results: []uint16{0x0000, 0x0000},
  875. },
  876. },
  877. },
  878. {
  879. name: "user updates offline buddy in feedbag, receives no buddy arrival notification",
  880. userSession: newTestSession("user_screen_name"),
  881. inputSNAC: oscar.SNACMessage{
  882. Frame: oscar.SNACFrame{
  883. RequestID: 1234,
  884. },
  885. Body: oscar.SNAC_0x13_0x09_FeedbagUpdateItem{
  886. Items: []oscar.FeedbagItem{
  887. {
  888. ClassID: oscar.FeedbagClassIDPermit,
  889. Name: "buddy_offline",
  890. },
  891. },
  892. },
  893. },
  894. mockParams: mockParams{
  895. feedbagManagerParams: feedbagManagerParams{
  896. feedbagUpsertParams: feedbagUpsertParams{
  897. {
  898. screenName: "user_screen_name",
  899. items: []oscar.FeedbagItem{
  900. {
  901. ClassID: oscar.FeedbagClassIDPermit,
  902. Name: "buddy_offline",
  903. },
  904. },
  905. },
  906. },
  907. },
  908. messageRelayerParams: messageRelayerParams{
  909. retrieveByScreenNameParams: retrieveByScreenNameParams{
  910. {
  911. screenName: "buddy_offline",
  912. sess: nil,
  913. },
  914. },
  915. },
  916. },
  917. expectOutput: oscar.SNACMessage{
  918. Frame: oscar.SNACFrame{
  919. FoodGroup: oscar.Feedbag,
  920. SubGroup: oscar.FeedbagStatus,
  921. RequestID: 1234,
  922. },
  923. Body: oscar.SNAC_0x13_0x0E_FeedbagStatus{
  924. Results: []uint16{0x0000},
  925. },
  926. },
  927. },
  928. {
  929. name: "user updates an invisible buddy in feedbag, receives no buddy arrival notification",
  930. userSession: newTestSession("user_screen_name"),
  931. inputSNAC: oscar.SNACMessage{
  932. Frame: oscar.SNACFrame{
  933. RequestID: 1234,
  934. },
  935. Body: oscar.SNAC_0x13_0x09_FeedbagUpdateItem{
  936. Items: []oscar.FeedbagItem{
  937. {
  938. ClassID: oscar.FeedbagClassIDPermit,
  939. Name: "invisible_buddy_online",
  940. },
  941. },
  942. },
  943. },
  944. mockParams: mockParams{
  945. feedbagManagerParams: feedbagManagerParams{
  946. feedbagUpsertParams: feedbagUpsertParams{
  947. {
  948. screenName: "user_screen_name",
  949. items: []oscar.FeedbagItem{
  950. {
  951. ClassID: oscar.FeedbagClassIDPermit,
  952. Name: "invisible_buddy_online",
  953. },
  954. },
  955. },
  956. },
  957. },
  958. messageRelayerParams: messageRelayerParams{
  959. retrieveByScreenNameParams: retrieveByScreenNameParams{
  960. {
  961. screenName: "invisible_buddy_online",
  962. sess: newTestSession("invisible_buddy_online", sessOptInvisible),
  963. },
  964. },
  965. },
  966. },
  967. expectOutput: oscar.SNACMessage{
  968. Frame: oscar.SNACFrame{
  969. FoodGroup: oscar.Feedbag,
  970. SubGroup: oscar.FeedbagStatus,
  971. RequestID: 1234,
  972. },
  973. Body: oscar.SNAC_0x13_0x0E_FeedbagStatus{
  974. Results: []uint16{0x0000},
  975. },
  976. },
  977. },
  978. }
  979. for _, tc := range cases {
  980. t.Run(tc.name, func(t *testing.T) {
  981. feedbagManager := newMockFeedbagManager(t)
  982. for _, params := range tc.mockParams.feedbagManagerParams.feedbagUpsertParams {
  983. feedbagManager.EXPECT().
  984. FeedbagUpsert(params.screenName, params.items).
  985. Return(nil)
  986. }
  987. messageRelayer := newMockMessageRelayer(t)
  988. for _, params := range tc.mockParams.messageRelayerParams.retrieveByScreenNameParams {
  989. messageRelayer.EXPECT().
  990. RetrieveByScreenName(params.screenName).
  991. Return(params.sess)
  992. }
  993. for _, params := range tc.mockParams.messageRelayerParams.sendToScreenNameParams {
  994. messageRelayer.EXPECT().
  995. RelayToScreenName(mock.Anything, params.screenName, params.message)
  996. }
  997. svc := FeedbagService{
  998. feedbagManager: feedbagManager,
  999. messageRelayer: messageRelayer,
  1000. }
  1001. output, err := svc.UpdateItemHandler(nil, tc.userSession, tc.inputSNAC.Frame,
  1002. tc.inputSNAC.Body.(oscar.SNAC_0x13_0x09_FeedbagUpdateItem))
  1003. assert.NoError(t, err)
  1004. assert.Equal(t, output, tc.expectOutput)
  1005. })
  1006. }
  1007. }
  1008. func TestFeedbagService_DeleteItemHandler(t *testing.T) {
  1009. cases := []struct {
  1010. // name is the unit test name
  1011. name string
  1012. // userSession is the session of the user adding to feedbag
  1013. userSession *state.Session
  1014. // inputSNAC is the SNAC sent from the client to the server
  1015. inputSNAC oscar.SNACMessage
  1016. // mockParams is the list of params sent to mocks that satisfy this
  1017. // method's dependencies
  1018. mockParams mockParams
  1019. // expectOutput is the SNAC sent from the server to client
  1020. expectOutput oscar.SNACMessage
  1021. }{
  1022. {
  1023. name: "user deletes buddy",
  1024. userSession: newTestSession("user_screen_name"),
  1025. inputSNAC: oscar.SNACMessage{
  1026. Frame: oscar.SNACFrame{
  1027. RequestID: 1234,
  1028. },
  1029. Body: oscar.SNAC_0x13_0x0A_FeedbagDeleteItem{
  1030. Items: []oscar.FeedbagItem{
  1031. {
  1032. ClassID: oscar.FeedbagClassIdBuddy,
  1033. Name: "buddy_1_online",
  1034. },
  1035. },
  1036. },
  1037. },
  1038. mockParams: mockParams{
  1039. feedbagManagerParams: feedbagManagerParams{
  1040. feedbagDeleteParams: feedbagDeleteParams{
  1041. {
  1042. screenName: "user_screen_name",
  1043. items: []oscar.FeedbagItem{
  1044. {
  1045. ClassID: oscar.FeedbagClassIdBuddy,
  1046. Name: "buddy_1_online",
  1047. },
  1048. },
  1049. },
  1050. },
  1051. },
  1052. },
  1053. expectOutput: oscar.SNACMessage{
  1054. Frame: oscar.SNACFrame{
  1055. FoodGroup: oscar.Feedbag,
  1056. SubGroup: oscar.FeedbagStatus,
  1057. RequestID: 1234,
  1058. },
  1059. Body: oscar.SNAC_0x13_0x0E_FeedbagStatus{
  1060. Results: []uint16{0x0000},
  1061. },
  1062. },
  1063. },
  1064. {
  1065. name: "user unblocks buddies, user and buddies receive buddy arrival notifications",
  1066. userSession: newTestSession("user_screen_name", sessOptCannedSignonTime),
  1067. inputSNAC: oscar.SNACMessage{
  1068. Frame: oscar.SNACFrame{
  1069. RequestID: 1234,
  1070. },
  1071. Body: oscar.SNAC_0x13_0x0A_FeedbagDeleteItem{
  1072. Items: []oscar.FeedbagItem{
  1073. {
  1074. ClassID: oscar.FeedbagClassIDDeny,
  1075. Name: "buddy_1_online",
  1076. },
  1077. {
  1078. ClassID: oscar.FeedbagClassIDDeny,
  1079. Name: "buddy_2_online",
  1080. },
  1081. },
  1082. },
  1083. },
  1084. mockParams: mockParams{
  1085. feedbagManagerParams: feedbagManagerParams{
  1086. feedbagDeleteParams: feedbagDeleteParams{
  1087. {
  1088. screenName: "user_screen_name",
  1089. items: []oscar.FeedbagItem{
  1090. {
  1091. ClassID: oscar.FeedbagClassIDDeny,
  1092. Name: "buddy_1_online",
  1093. },
  1094. {
  1095. ClassID: oscar.FeedbagClassIDDeny,
  1096. Name: "buddy_2_online",
  1097. },
  1098. },
  1099. },
  1100. },
  1101. },
  1102. messageRelayerParams: messageRelayerParams{
  1103. retrieveByScreenNameParams: retrieveByScreenNameParams{
  1104. {
  1105. screenName: "buddy_1_online",
  1106. sess: newTestSession("buddy_1_online", sessOptCannedSignonTime),
  1107. },
  1108. {
  1109. screenName: "buddy_2_online",
  1110. sess: newTestSession("buddy_2_online", sessOptCannedSignonTime),
  1111. },
  1112. },
  1113. sendToScreenNameParams: sendToScreenNameParams{
  1114. {
  1115. screenName: "user_screen_name",
  1116. message: oscar.SNACMessage{
  1117. Frame: oscar.SNACFrame{
  1118. FoodGroup: oscar.Buddy,
  1119. SubGroup: oscar.BuddyArrived,
  1120. },
  1121. Body: oscar.SNAC_0x03_0x0B_BuddyArrived{
  1122. TLVUserInfo: newTestSession("buddy_1_online", sessOptCannedSignonTime).TLVUserInfo(),
  1123. },
  1124. },
  1125. },
  1126. {
  1127. screenName: "buddy_1_online",
  1128. message: oscar.SNACMessage{
  1129. Frame: oscar.SNACFrame{
  1130. FoodGroup: oscar.Buddy,
  1131. SubGroup: oscar.BuddyArrived,
  1132. },
  1133. Body: oscar.SNAC_0x03_0x0B_BuddyArrived{
  1134. TLVUserInfo: newTestSession("user_screen_name", sessOptCannedSignonTime).TLVUserInfo(),
  1135. },
  1136. },
  1137. },
  1138. {
  1139. screenName: "user_screen_name",
  1140. message: oscar.SNACMessage{
  1141. Frame: oscar.SNACFrame{
  1142. FoodGroup: oscar.Buddy,
  1143. SubGroup: oscar.BuddyArrived,
  1144. },
  1145. Body: oscar.SNAC_0x03_0x0B_BuddyArrived{
  1146. TLVUserInfo: newTestSession("buddy_2_online", sessOptCannedSignonTime).TLVUserInfo(),
  1147. },
  1148. },
  1149. },
  1150. {
  1151. screenName: "buddy_2_online",
  1152. message: oscar.SNACMessage{
  1153. Frame: oscar.SNACFrame{
  1154. FoodGroup: oscar.Buddy,
  1155. SubGroup: oscar.BuddyArrived,
  1156. },
  1157. Body: oscar.SNAC_0x03_0x0B_BuddyArrived{
  1158. TLVUserInfo: newTestSession("user_screen_name", sessOptCannedSignonTime).TLVUserInfo(),
  1159. },
  1160. },
  1161. },
  1162. },
  1163. },
  1164. },
  1165. expectOutput: oscar.SNACMessage{
  1166. Frame: oscar.SNACFrame{
  1167. FoodGroup: oscar.Feedbag,
  1168. SubGroup: oscar.FeedbagStatus,
  1169. RequestID: 1234,
  1170. },
  1171. Body: oscar.SNAC_0x13_0x0E_FeedbagStatus{
  1172. Results: []uint16{0x0000, 0x0000},
  1173. },
  1174. },
  1175. },
  1176. {
  1177. name: "user unblocks offline buddy, receives no buddy arrival notifications",
  1178. userSession: newTestSession("user_screen_name"),
  1179. inputSNAC: oscar.SNACMessage{
  1180. Frame: oscar.SNACFrame{
  1181. RequestID: 1234,
  1182. },
  1183. Body: oscar.SNAC_0x13_0x0A_FeedbagDeleteItem{
  1184. Items: []oscar.FeedbagItem{
  1185. {
  1186. ClassID: oscar.FeedbagClassIDDeny,
  1187. Name: "buddy_offline",
  1188. },
  1189. },
  1190. },
  1191. },
  1192. mockParams: mockParams{
  1193. feedbagManagerParams: feedbagManagerParams{
  1194. feedbagDeleteParams: feedbagDeleteParams{
  1195. {
  1196. screenName: "user_screen_name",
  1197. items: []oscar.FeedbagItem{
  1198. {
  1199. ClassID: oscar.FeedbagClassIDDeny,
  1200. Name: "buddy_offline",
  1201. },
  1202. },
  1203. },
  1204. },
  1205. },
  1206. messageRelayerParams: messageRelayerParams{
  1207. retrieveByScreenNameParams: retrieveByScreenNameParams{
  1208. {
  1209. screenName: "buddy_offline",
  1210. sess: nil,
  1211. },
  1212. },
  1213. },
  1214. },
  1215. expectOutput: oscar.SNACMessage{
  1216. Frame: oscar.SNACFrame{
  1217. FoodGroup: oscar.Feedbag,
  1218. SubGroup: oscar.FeedbagStatus,
  1219. RequestID: 1234,
  1220. },
  1221. Body: oscar.SNAC_0x13_0x0E_FeedbagStatus{
  1222. Results: []uint16{0x0000},
  1223. },
  1224. },
  1225. },
  1226. {
  1227. name: "user unblocks invisible buddy, user receives no buddy arrival notification, buddy receives buddy arrival notifications",
  1228. userSession: newTestSession("user_screen_name", sessOptCannedSignonTime),
  1229. inputSNAC: oscar.SNACMessage{
  1230. Frame: oscar.SNACFrame{
  1231. RequestID: 1234,
  1232. },
  1233. Body: oscar.SNAC_0x13_0x0A_FeedbagDeleteItem{
  1234. Items: []oscar.FeedbagItem{
  1235. {
  1236. ClassID: oscar.FeedbagClassIDDeny,
  1237. Name: "invisible_buddy_online",
  1238. },
  1239. },
  1240. },
  1241. },
  1242. mockParams: mockParams{
  1243. feedbagManagerParams: feedbagManagerParams{
  1244. feedbagDeleteParams: feedbagDeleteParams{
  1245. {
  1246. screenName: "user_screen_name",
  1247. items: []oscar.FeedbagItem{
  1248. {
  1249. ClassID: oscar.FeedbagClassIDDeny,
  1250. Name: "invisible_buddy_online",
  1251. },
  1252. },
  1253. },
  1254. },
  1255. },
  1256. messageRelayerParams: messageRelayerParams{
  1257. retrieveByScreenNameParams: retrieveByScreenNameParams{
  1258. {
  1259. screenName: "invisible_buddy_online",
  1260. sess: newTestSession("invisible_buddy_online", sessOptInvisible),
  1261. },
  1262. },
  1263. sendToScreenNameParams: sendToScreenNameParams{
  1264. {
  1265. screenName: "invisible_buddy_online",
  1266. message: oscar.SNACMessage{
  1267. Frame: oscar.SNACFrame{
  1268. FoodGroup: oscar.Buddy,
  1269. SubGroup: oscar.BuddyArrived,
  1270. },
  1271. Body: oscar.SNAC_0x03_0x0B_BuddyArrived{
  1272. TLVUserInfo: newTestSession("user_screen_name", sessOptCannedSignonTime).TLVUserInfo(),
  1273. },
  1274. },
  1275. },
  1276. },
  1277. },
  1278. },
  1279. expectOutput: oscar.SNACMessage{
  1280. Frame: oscar.SNACFrame{
  1281. FoodGroup: oscar.Feedbag,
  1282. SubGroup: oscar.FeedbagStatus,
  1283. RequestID: 1234,
  1284. },
  1285. Body: oscar.SNAC_0x13_0x0E_FeedbagStatus{
  1286. Results: []uint16{0x0000},
  1287. },
  1288. },
  1289. },
  1290. }
  1291. for _, tc := range cases {
  1292. t.Run(tc.name, func(t *testing.T) {
  1293. feedbagManager := newMockFeedbagManager(t)
  1294. for _, params := range tc.mockParams.feedbagManagerParams.feedbagDeleteParams {
  1295. feedbagManager.EXPECT().
  1296. FeedbagDelete(params.screenName, params.items).
  1297. Return(nil)
  1298. }
  1299. messageRelayer := newMockMessageRelayer(t)
  1300. for _, params := range tc.mockParams.messageRelayerParams.retrieveByScreenNameParams {
  1301. messageRelayer.EXPECT().
  1302. RetrieveByScreenName(params.screenName).
  1303. Return(params.sess)
  1304. }
  1305. for _, params := range tc.mockParams.messageRelayerParams.sendToScreenNameParams {
  1306. messageRelayer.EXPECT().
  1307. RelayToScreenName(mock.Anything, params.screenName, params.message)
  1308. }
  1309. svc := FeedbagService{
  1310. feedbagManager: feedbagManager,
  1311. messageRelayer: messageRelayer,
  1312. }
  1313. output, err := svc.DeleteItemHandler(nil, tc.userSession, tc.inputSNAC.Frame,
  1314. tc.inputSNAC.Body.(oscar.SNAC_0x13_0x0A_FeedbagDeleteItem))
  1315. assert.NoError(t, err)
  1316. assert.Equal(t, output, tc.expectOutput)
  1317. })
  1318. }
  1319. }