admin_test.go 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972
  1. package foodgroup
  2. import (
  3. "net/mail"
  4. "testing"
  5. "github.com/mk6i/retro-aim-server/config"
  6. "github.com/mk6i/retro-aim-server/state"
  7. "github.com/mk6i/retro-aim-server/wire"
  8. "github.com/stretchr/testify/assert"
  9. "github.com/stretchr/testify/mock"
  10. )
  11. func TestAdminService_ConfirmRequest(t *testing.T) {
  12. cases := []struct {
  13. // name is the unit test name
  14. name string
  15. // cfg is the app configuration
  16. cfg config.Config
  17. // inputSNAC is the SNAC sent from the client to the server
  18. inputSNAC wire.SNACMessage
  19. // mockParams is the list of params sent to mocks that satisfy this
  20. // method's dependencies
  21. mockParams mockParams
  22. // userSession is the session of the user
  23. userSession *state.Session
  24. // expectOutput is the SNAC sent from the server to client
  25. expectOutput wire.SNACMessage
  26. // expectErr is the expected error returned
  27. expectErr error
  28. }{
  29. {
  30. name: "unconfirmed account sends confirmation request",
  31. userSession: newTestSession("chattingchuck"),
  32. inputSNAC: wire.SNACMessage{
  33. Frame: wire.SNACFrame{
  34. FoodGroup: wire.Admin,
  35. SubGroup: wire.AdminAcctConfirmRequest,
  36. RequestID: 1234,
  37. },
  38. Body: wire.SNAC_0x07_0x06_AdminConfirmRequest{},
  39. },
  40. expectOutput: wire.SNACMessage{
  41. Frame: wire.SNACFrame{
  42. FoodGroup: wire.Admin,
  43. SubGroup: wire.AdminAcctConfirmReply,
  44. RequestID: 1234,
  45. },
  46. Body: wire.SNAC_0x07_0x07_AdminConfirmReply{
  47. Status: wire.AdminAcctConfirmStatusEmailSent,
  48. },
  49. },
  50. mockParams: mockParams{
  51. accountManagerParams: accountManagerParams{
  52. accountManagerEmailAddressByNameParams: accountManagerEmailAddressByNameParams{
  53. {
  54. screenName: state.NewIdentScreenName("chattingchuck"),
  55. emailAddress: &mail.Address{
  56. Address: "chuck@aol.com",
  57. },
  58. err: nil,
  59. },
  60. },
  61. accountManagerConfirmStatusByNameParams: accountManagerConfirmStatusByNameParams{
  62. {
  63. screenName: state.NewIdentScreenName("chattingchuck"),
  64. confirmStatus: false,
  65. err: nil,
  66. },
  67. },
  68. accountManagerUpdateConfirmStatusParams: accountManagerUpdateConfirmStatusParams{
  69. {
  70. confirmStatus: true,
  71. screenName: state.NewIdentScreenName("chattingchuck"),
  72. err: nil,
  73. },
  74. },
  75. },
  76. buddyBroadcasterParams: buddyBroadcasterParams{
  77. broadcastBuddyArrivedParams: broadcastBuddyArrivedParams{
  78. {
  79. screenName: state.NewIdentScreenName("Chatting Chuck"),
  80. },
  81. },
  82. },
  83. },
  84. },
  85. {
  86. name: "already confirmed account sends confirmation request",
  87. userSession: newTestSession("chattingchuck"),
  88. inputSNAC: wire.SNACMessage{
  89. Frame: wire.SNACFrame{
  90. FoodGroup: wire.Admin,
  91. SubGroup: wire.AdminAcctConfirmRequest,
  92. RequestID: 1234,
  93. },
  94. Body: wire.SNAC_0x07_0x06_AdminConfirmRequest{},
  95. },
  96. expectOutput: wire.SNACMessage{
  97. Frame: wire.SNACFrame{
  98. FoodGroup: wire.Admin,
  99. SubGroup: wire.AdminAcctConfirmReply,
  100. RequestID: 1234,
  101. },
  102. Body: wire.SNAC_0x07_0x07_AdminConfirmReply{
  103. Status: wire.AdminAcctConfirmStatusAlreadyConfirmed,
  104. },
  105. },
  106. mockParams: mockParams{
  107. accountManagerParams: accountManagerParams{
  108. accountManagerEmailAddressByNameParams: accountManagerEmailAddressByNameParams{
  109. {
  110. screenName: state.NewIdentScreenName("chattingchuck"),
  111. emailAddress: &mail.Address{
  112. Address: "chuck@aol.com",
  113. },
  114. err: nil,
  115. },
  116. },
  117. accountManagerConfirmStatusByNameParams: accountManagerConfirmStatusByNameParams{
  118. {
  119. screenName: state.NewIdentScreenName("chattingchuck"),
  120. confirmStatus: true,
  121. err: nil,
  122. },
  123. },
  124. },
  125. },
  126. },
  127. {
  128. name: "acccount with no email address sends confirmation request",
  129. userSession: newTestSession("chattingchuck"),
  130. inputSNAC: wire.SNACMessage{
  131. Frame: wire.SNACFrame{
  132. FoodGroup: wire.Admin,
  133. SubGroup: wire.AdminAcctConfirmRequest,
  134. RequestID: 1234,
  135. },
  136. Body: wire.SNAC_0x07_0x06_AdminConfirmRequest{},
  137. },
  138. expectOutput: wire.SNACMessage{
  139. Frame: wire.SNACFrame{
  140. FoodGroup: wire.Admin,
  141. SubGroup: wire.AdminAcctConfirmReply,
  142. RequestID: 1234,
  143. },
  144. Body: wire.SNAC_0x07_0x07_AdminConfirmReply{
  145. Status: wire.AdminAcctConfirmStatusServerError,
  146. },
  147. },
  148. mockParams: mockParams{
  149. accountManagerParams: accountManagerParams{
  150. accountManagerEmailAddressByNameParams: accountManagerEmailAddressByNameParams{
  151. {
  152. screenName: state.NewIdentScreenName("chattingchuck"),
  153. emailAddress: nil,
  154. err: state.ErrNoEmailAddress,
  155. },
  156. },
  157. },
  158. },
  159. },
  160. }
  161. for _, tc := range cases {
  162. t.Run(tc.name, func(t *testing.T) {
  163. sessionManager := newMockSessionManager(t)
  164. accountManager := newMockAccountManager(t)
  165. buddyBroadcaster := newMockbuddyBroadcaster(t)
  166. for _, params := range tc.mockParams.accountManagerParams.accountManagerEmailAddressByNameParams {
  167. accountManager.EXPECT().
  168. EmailAddressByName(params.screenName).
  169. Return(params.emailAddress, params.err)
  170. }
  171. for _, params := range tc.mockParams.accountManagerParams.accountManagerConfirmStatusByNameParams {
  172. accountManager.EXPECT().
  173. ConfirmStatusByName(params.screenName).
  174. Return(params.confirmStatus, params.err)
  175. }
  176. for _, params := range tc.mockParams.accountManagerParams.accountManagerUpdateConfirmStatusParams {
  177. accountManager.EXPECT().
  178. UpdateConfirmStatus(params.confirmStatus, params.screenName).
  179. Return(params.err)
  180. }
  181. for _, params := range tc.mockParams.broadcastBuddyArrivedParams {
  182. buddyBroadcaster.EXPECT().
  183. BroadcastBuddyArrived(mock.Anything, tc.userSession).
  184. Return(params.err)
  185. }
  186. svc := AdminService{
  187. sessionManager: sessionManager,
  188. accountManager: accountManager,
  189. buddyUpdateBroadcaster: buddyBroadcaster,
  190. }
  191. outputSNAC, err := svc.ConfirmRequest(nil, tc.userSession, tc.inputSNAC.Frame)
  192. assert.ErrorIs(t, err, tc.expectErr)
  193. if tc.expectErr != nil {
  194. return
  195. }
  196. assert.Equal(t, tc.expectOutput, outputSNAC)
  197. })
  198. }
  199. }
  200. func TestAdminService_InfoQuery(t *testing.T) {
  201. cases := []struct {
  202. // name is the unit test name
  203. name string
  204. // cfg is the app configuration
  205. cfg config.Config
  206. // inputSNAC is the SNAC sent from the client to the server
  207. inputSNAC wire.SNACMessage
  208. // mockParams is the list of params sent to mocks that satisfy this
  209. // method's dependencies
  210. mockParams mockParams
  211. // userSession is the session of the user
  212. userSession *state.Session
  213. // expectOutput is the SNAC sent from the server to client
  214. expectOutput wire.SNACMessage
  215. // expectErr is the expected error returned
  216. expectErr error
  217. }{
  218. {
  219. name: "user requests account registration status",
  220. userSession: newTestSession("chattingchuck"),
  221. inputSNAC: wire.SNACMessage{
  222. Frame: wire.SNACFrame{
  223. FoodGroup: wire.Admin,
  224. SubGroup: wire.AdminInfoQuery,
  225. RequestID: 1337,
  226. },
  227. Body: wire.SNAC_0x07_0x02_AdminInfoQuery{
  228. TLVRestBlock: wire.TLVRestBlock{
  229. TLVList: wire.TLVList{
  230. wire.NewTLV(wire.AdminTLVRegistrationStatus, uint16(0x00))},
  231. },
  232. },
  233. },
  234. expectOutput: wire.SNACMessage{
  235. Frame: wire.SNACFrame{
  236. FoodGroup: wire.Admin,
  237. SubGroup: wire.AdminInfoReply,
  238. RequestID: 1337,
  239. },
  240. Body: wire.SNAC_0x07_0x03_AdminInfoReply{
  241. Permissions: wire.AdminInfoPermissionsReadWrite,
  242. TLVBlock: wire.TLVBlock{
  243. TLVList: wire.TLVList{
  244. wire.NewTLV(wire.AdminTLVRegistrationStatus, wire.AdminInfoRegStatusLimitDisclosure),
  245. },
  246. },
  247. },
  248. },
  249. mockParams: mockParams{
  250. accountManagerParams: accountManagerParams{
  251. accountManagerRegStatusByNameParams: accountManagerRegStatusByNameParams{
  252. {
  253. screenName: state.NewIdentScreenName("chattingchuck"),
  254. regStatus: wire.AdminInfoRegStatusLimitDisclosure,
  255. err: nil,
  256. },
  257. },
  258. },
  259. },
  260. },
  261. {
  262. name: "user requests account email address",
  263. userSession: newTestSession("chattingchuck"),
  264. inputSNAC: wire.SNACMessage{
  265. Frame: wire.SNACFrame{
  266. FoodGroup: wire.Admin,
  267. SubGroup: wire.AdminInfoQuery,
  268. RequestID: 1337,
  269. },
  270. Body: wire.SNAC_0x07_0x02_AdminInfoQuery{
  271. TLVRestBlock: wire.TLVRestBlock{
  272. TLVList: wire.TLVList{
  273. wire.NewTLV(wire.AdminTLVEmailAddress, uint16(0x00))},
  274. },
  275. },
  276. },
  277. expectOutput: wire.SNACMessage{
  278. Frame: wire.SNACFrame{
  279. FoodGroup: wire.Admin,
  280. SubGroup: wire.AdminInfoReply,
  281. RequestID: 1337,
  282. },
  283. Body: wire.SNAC_0x07_0x03_AdminInfoReply{
  284. Permissions: wire.AdminInfoPermissionsReadWrite,
  285. TLVBlock: wire.TLVBlock{
  286. TLVList: wire.TLVList{
  287. wire.NewTLV(wire.AdminTLVEmailAddress, "chattingchuck@aol.com"),
  288. },
  289. },
  290. },
  291. },
  292. mockParams: mockParams{
  293. accountManagerParams: accountManagerParams{
  294. accountManagerEmailAddressByNameParams: accountManagerEmailAddressByNameParams{
  295. {
  296. screenName: state.NewIdentScreenName("chattingchuck"),
  297. emailAddress: &mail.Address{
  298. Address: "chattingchuck@aol.com",
  299. },
  300. err: nil,
  301. },
  302. },
  303. },
  304. },
  305. },
  306. {
  307. name: "user requests account email address but not set",
  308. userSession: newTestSession("chattingchuck"),
  309. inputSNAC: wire.SNACMessage{
  310. Frame: wire.SNACFrame{
  311. FoodGroup: wire.Admin,
  312. SubGroup: wire.AdminInfoQuery,
  313. RequestID: 1337,
  314. },
  315. Body: wire.SNAC_0x07_0x02_AdminInfoQuery{
  316. TLVRestBlock: wire.TLVRestBlock{
  317. TLVList: wire.TLVList{
  318. wire.NewTLV(wire.AdminTLVEmailAddress, uint16(0x00))},
  319. },
  320. },
  321. },
  322. expectOutput: wire.SNACMessage{
  323. Frame: wire.SNACFrame{
  324. FoodGroup: wire.Admin,
  325. SubGroup: wire.AdminInfoReply,
  326. RequestID: 1337,
  327. },
  328. Body: wire.SNAC_0x07_0x03_AdminInfoReply{
  329. Permissions: wire.AdminInfoPermissionsReadWrite,
  330. TLVBlock: wire.TLVBlock{
  331. TLVList: wire.TLVList{
  332. wire.NewTLV(wire.AdminTLVEmailAddress, ""),
  333. },
  334. },
  335. },
  336. },
  337. mockParams: mockParams{
  338. accountManagerParams: accountManagerParams{
  339. accountManagerEmailAddressByNameParams: accountManagerEmailAddressByNameParams{
  340. {
  341. screenName: state.NewIdentScreenName("chattingchuck"),
  342. emailAddress: nil,
  343. err: state.ErrNoEmailAddress,
  344. },
  345. },
  346. },
  347. },
  348. },
  349. {
  350. name: "user requests formatted screenname",
  351. userSession: newTestSession("ChattingChuck"),
  352. inputSNAC: wire.SNACMessage{
  353. Frame: wire.SNACFrame{
  354. FoodGroup: wire.Admin,
  355. SubGroup: wire.AdminInfoQuery,
  356. RequestID: 1337,
  357. },
  358. Body: wire.SNAC_0x07_0x02_AdminInfoQuery{
  359. TLVRestBlock: wire.TLVRestBlock{
  360. TLVList: wire.TLVList{
  361. wire.NewTLV(wire.AdminTLVScreenNameFormatted, uint16(0x00))},
  362. },
  363. },
  364. },
  365. expectOutput: wire.SNACMessage{
  366. Frame: wire.SNACFrame{
  367. FoodGroup: wire.Admin,
  368. SubGroup: wire.AdminInfoReply,
  369. RequestID: 1337,
  370. },
  371. Body: wire.SNAC_0x07_0x03_AdminInfoReply{
  372. Permissions: wire.AdminInfoPermissionsReadWrite,
  373. TLVBlock: wire.TLVBlock{
  374. TLVList: wire.TLVList{
  375. wire.NewTLV(wire.AdminTLVScreenNameFormatted, "ChattingChuck"),
  376. },
  377. },
  378. },
  379. },
  380. },
  381. {
  382. name: "user requests invalid TLV",
  383. userSession: newTestSession("ChattingChuck"),
  384. inputSNAC: wire.SNACMessage{
  385. Frame: wire.SNACFrame{
  386. FoodGroup: wire.Admin,
  387. SubGroup: wire.AdminInfoQuery,
  388. RequestID: 1337,
  389. },
  390. Body: wire.SNAC_0x07_0x02_AdminInfoQuery{
  391. TLVRestBlock: wire.TLVRestBlock{
  392. TLVList: wire.TLVList{
  393. wire.NewTLV(uint16(0x99), uint16(0x00))},
  394. },
  395. },
  396. },
  397. expectOutput: wire.SNACMessage{
  398. Frame: wire.SNACFrame{
  399. FoodGroup: wire.Admin,
  400. SubGroup: wire.AdminErr,
  401. RequestID: 1337,
  402. },
  403. Body: wire.SNACError{
  404. Code: wire.ErrorCodeNotSupportedByHost,
  405. },
  406. },
  407. },
  408. }
  409. for _, tc := range cases {
  410. t.Run(tc.name, func(t *testing.T) {
  411. sessionManager := newMockSessionManager(t)
  412. accountManager := newMockAccountManager(t)
  413. buddyBroadcaster := newMockbuddyBroadcaster(t)
  414. for _, params := range tc.mockParams.accountManagerParams.accountManagerRegStatusByNameParams {
  415. accountManager.EXPECT().
  416. RegStatusByName(params.screenName).
  417. Return(params.regStatus, params.err)
  418. }
  419. for _, params := range tc.mockParams.accountManagerParams.accountManagerEmailAddressByNameParams {
  420. accountManager.EXPECT().
  421. EmailAddressByName(params.screenName).
  422. Return(params.emailAddress, params.err)
  423. }
  424. svc := AdminService{
  425. sessionManager: sessionManager,
  426. accountManager: accountManager,
  427. buddyUpdateBroadcaster: buddyBroadcaster,
  428. }
  429. outputSNAC, err := svc.InfoQuery(nil, tc.userSession, tc.inputSNAC.Frame, tc.inputSNAC.Body.(wire.SNAC_0x07_0x02_AdminInfoQuery))
  430. assert.ErrorIs(t, err, tc.expectErr)
  431. if tc.expectErr != nil {
  432. return
  433. }
  434. assert.Equal(t, tc.expectOutput, outputSNAC)
  435. })
  436. }
  437. }
  438. func TestAdminService_InfoChangeRequest_ScreenName(t *testing.T) {
  439. cases := []struct {
  440. // name is the unit test name
  441. name string
  442. // cfg is the app configuration
  443. cfg config.Config
  444. // inputSNAC is the SNAC sent from the client to the server
  445. inputSNAC wire.SNACMessage
  446. // mockParams is the list of params sent to mocks that satisfy this
  447. // method's dependencies
  448. mockParams mockParams
  449. // userSession is the session of the user
  450. userSession *state.Session
  451. // expectOutput is the SNAC sent from the server to client
  452. expectOutput wire.SNACMessage
  453. // expectErr is the expected error returned
  454. expectErr error
  455. }{
  456. {
  457. name: "user changes screen name format successfully",
  458. userSession: newTestSession("chattingchuck"),
  459. mockParams: mockParams{
  460. accountManagerParams: accountManagerParams{
  461. accountManagerUpdateDisplayScreenNameParams: accountManagerUpdateDisplayScreenNameParams{
  462. {
  463. displayScreenName: state.DisplayScreenName("Chatting Chuck"),
  464. },
  465. },
  466. },
  467. buddyBroadcasterParams: buddyBroadcasterParams{
  468. broadcastBuddyArrivedParams: broadcastBuddyArrivedParams{
  469. {
  470. screenName: state.NewIdentScreenName("Chatting Chuck"),
  471. },
  472. },
  473. },
  474. messageRelayerParams: messageRelayerParams{
  475. relayToScreenNameParams: relayToScreenNameParams{
  476. {
  477. screenName: state.NewIdentScreenName("Chatting Chuck"),
  478. message: wire.SNACMessage{
  479. Frame: wire.SNACFrame{
  480. FoodGroup: wire.OService,
  481. SubGroup: wire.OServiceUserInfoUpdate,
  482. },
  483. Body: wire.SNAC_0x01_0x0F_OServiceUserInfoUpdate{
  484. TLVUserInfo: newTestSession("Chatting Chuck").TLVUserInfo(),
  485. },
  486. },
  487. },
  488. },
  489. },
  490. },
  491. inputSNAC: wire.SNACMessage{
  492. Frame: wire.SNACFrame{
  493. FoodGroup: wire.Admin,
  494. SubGroup: wire.AdminInfoChangeRequest,
  495. RequestID: 1337,
  496. },
  497. Body: wire.SNAC_0x07_0x04_AdminInfoChangeRequest{
  498. TLVRestBlock: wire.TLVRestBlock{
  499. TLVList: wire.TLVList{
  500. wire.NewTLV(wire.AdminTLVScreenNameFormatted, "Chatting Chuck"),
  501. },
  502. },
  503. },
  504. },
  505. expectOutput: wire.SNACMessage{
  506. Frame: wire.SNACFrame{
  507. FoodGroup: wire.Admin,
  508. SubGroup: wire.AdminInfoChangeReply,
  509. RequestID: 1337,
  510. },
  511. Body: wire.SNAC_0x07_0x05_AdminChangeReply{
  512. Permissions: wire.AdminInfoPermissionsReadWrite,
  513. TLVBlock: wire.TLVBlock{
  514. TLVList: wire.TLVList{
  515. wire.NewTLV(wire.AdminTLVScreenNameFormatted, "Chatting Chuck"),
  516. },
  517. },
  518. },
  519. },
  520. },
  521. {
  522. name: "proposed screen name is too long",
  523. userSession: newTestSession("chattingchuck"),
  524. inputSNAC: wire.SNACMessage{
  525. Frame: wire.SNACFrame{
  526. FoodGroup: wire.Admin,
  527. SubGroup: wire.AdminInfoChangeRequest,
  528. RequestID: 1337,
  529. },
  530. Body: wire.SNAC_0x07_0x04_AdminInfoChangeRequest{
  531. TLVRestBlock: wire.TLVRestBlock{
  532. TLVList: wire.TLVList{
  533. wire.NewTLV(wire.AdminTLVScreenNameFormatted, "c h a t t i n g c h u c k")},
  534. },
  535. },
  536. },
  537. expectOutput: wire.SNACMessage{
  538. Frame: wire.SNACFrame{
  539. FoodGroup: wire.Admin,
  540. SubGroup: wire.AdminInfoChangeReply,
  541. RequestID: 1337,
  542. },
  543. Body: wire.SNAC_0x07_0x05_AdminChangeReply{
  544. Permissions: wire.AdminInfoPermissionsReadWrite,
  545. TLVBlock: wire.TLVBlock{
  546. TLVList: wire.TLVList{
  547. wire.NewTLV(wire.AdminTLVErrorCode, wire.AdminInfoErrorInvalidNickNameLength),
  548. wire.NewTLV(wire.AdminTLVUrl, ""),
  549. },
  550. },
  551. },
  552. },
  553. },
  554. {
  555. name: "proposed screen name does not match session screen name",
  556. userSession: newTestSession("chattingchuck"),
  557. inputSNAC: wire.SNACMessage{
  558. Frame: wire.SNACFrame{
  559. FoodGroup: wire.Admin,
  560. SubGroup: wire.AdminInfoChangeRequest,
  561. RequestID: 1337,
  562. },
  563. Body: wire.SNAC_0x07_0x04_AdminInfoChangeRequest{
  564. TLVRestBlock: wire.TLVRestBlock{
  565. TLVList: wire.TLVList{
  566. wire.NewTLV(wire.AdminTLVScreenNameFormatted, "QuietQuinton")},
  567. },
  568. },
  569. },
  570. expectOutput: wire.SNACMessage{
  571. Frame: wire.SNACFrame{
  572. FoodGroup: wire.Admin,
  573. SubGroup: wire.AdminInfoChangeReply,
  574. RequestID: 1337,
  575. },
  576. Body: wire.SNAC_0x07_0x05_AdminChangeReply{
  577. Permissions: wire.AdminInfoPermissionsReadWrite,
  578. TLVBlock: wire.TLVBlock{
  579. TLVList: wire.TLVList{
  580. wire.NewTLV(wire.AdminTLVErrorCode, wire.AdminInfoErrorValidateNickName),
  581. wire.NewTLV(wire.AdminTLVUrl, ""),
  582. },
  583. },
  584. },
  585. },
  586. },
  587. {
  588. name: "proposed screen name ends in a space",
  589. userSession: newTestSession("chattingchuck"),
  590. inputSNAC: wire.SNACMessage{
  591. Frame: wire.SNACFrame{
  592. FoodGroup: wire.Admin,
  593. SubGroup: wire.AdminInfoChangeRequest,
  594. RequestID: 1337,
  595. },
  596. Body: wire.SNAC_0x07_0x04_AdminInfoChangeRequest{
  597. TLVRestBlock: wire.TLVRestBlock{
  598. TLVList: wire.TLVList{
  599. wire.NewTLV(wire.AdminTLVScreenNameFormatted, "ChattingChuck ")},
  600. },
  601. },
  602. },
  603. expectOutput: wire.SNACMessage{
  604. Frame: wire.SNACFrame{
  605. FoodGroup: wire.Admin,
  606. SubGroup: wire.AdminInfoChangeReply,
  607. RequestID: 1337,
  608. },
  609. Body: wire.SNAC_0x07_0x05_AdminChangeReply{
  610. Permissions: wire.AdminInfoPermissionsReadWrite,
  611. TLVBlock: wire.TLVBlock{
  612. TLVList: wire.TLVList{
  613. wire.NewTLV(wire.AdminTLVErrorCode, wire.AdminInfoErrorInvalidNickName),
  614. wire.NewTLV(wire.AdminTLVUrl, ""),
  615. },
  616. },
  617. },
  618. },
  619. },
  620. }
  621. for _, tc := range cases {
  622. t.Run(tc.name, func(t *testing.T) {
  623. sessionManager := newMockSessionManager(t)
  624. accountManager := newMockAccountManager(t)
  625. buddyBroadcaster := newMockbuddyBroadcaster(t)
  626. messageRelayer := newMockMessageRelayer(t)
  627. for _, params := range tc.mockParams.accountManagerParams.accountManagerUpdateDisplayScreenNameParams {
  628. accountManager.EXPECT().
  629. UpdateDisplayScreenName(params.displayScreenName).
  630. Return(params.err)
  631. }
  632. for _, params := range tc.mockParams.broadcastBuddyArrivedParams {
  633. p := params
  634. buddyBroadcaster.EXPECT().
  635. BroadcastBuddyArrived(mock.Anything, mock.MatchedBy(func(s *state.Session) bool {
  636. return s.IdentScreenName() == p.screenName
  637. })).
  638. Return(p.err)
  639. }
  640. for _, params := range tc.mockParams.messageRelayerParams.relayToScreenNameParams {
  641. p := params
  642. messageRelayer.EXPECT().
  643. RelayToScreenName(mock.Anything, p.screenName, p.message)
  644. }
  645. svc := AdminService{
  646. sessionManager: sessionManager,
  647. accountManager: accountManager,
  648. buddyUpdateBroadcaster: buddyBroadcaster,
  649. messageRelayer: messageRelayer,
  650. }
  651. outputSNAC, err := svc.InfoChangeRequest(nil, tc.userSession, tc.inputSNAC.Frame, tc.inputSNAC.Body.(wire.SNAC_0x07_0x04_AdminInfoChangeRequest))
  652. assert.ErrorIs(t, err, tc.expectErr)
  653. if tc.expectErr != nil {
  654. return
  655. }
  656. assert.Equal(t, tc.expectOutput, outputSNAC)
  657. })
  658. }
  659. }
  660. func TestAdminService_InfoChangeRequest_EmailAddress(t *testing.T) {
  661. // One case needs a 320 character long email address
  662. longEmailAddress := "longemailaddress@"
  663. for i := 0; i < 50; i++ {
  664. longEmailAddress += "domain"
  665. }
  666. longEmailAddress += ".com"
  667. cases := []struct {
  668. // name is the unit test name
  669. name string
  670. // cfg is the app configuration
  671. cfg config.Config
  672. // inputSNAC is the SNAC sent from the client to the server
  673. inputSNAC wire.SNACMessage
  674. // mockParams is the list of params sent to mocks that satisfy this
  675. // method's dependencies
  676. mockParams mockParams
  677. // userSession is the session of the user
  678. userSession *state.Session
  679. // expectOutput is the SNAC sent from the server to client
  680. expectOutput wire.SNACMessage
  681. // expectErr is the expected error returned
  682. expectErr error
  683. }{
  684. {
  685. name: "user changes email address successfully",
  686. userSession: newTestSession("chattingchuck"),
  687. mockParams: mockParams{
  688. accountManagerParams: accountManagerParams{
  689. accountManagerUpdateEmailAddressParams: accountManagerUpdateEmailAddressParams{
  690. {
  691. screenName: state.NewIdentScreenName("chattingchuck"),
  692. emailAddress: &mail.Address{
  693. Address: "chattingchuck@aol.com",
  694. },
  695. },
  696. },
  697. },
  698. },
  699. inputSNAC: wire.SNACMessage{
  700. Frame: wire.SNACFrame{
  701. FoodGroup: wire.Admin,
  702. SubGroup: wire.AdminInfoChangeRequest,
  703. RequestID: 1337,
  704. },
  705. Body: wire.SNAC_0x07_0x04_AdminInfoChangeRequest{
  706. TLVRestBlock: wire.TLVRestBlock{
  707. TLVList: wire.TLVList{
  708. wire.NewTLV(wire.AdminTLVEmailAddress, "chattingchuck@aol.com"),
  709. },
  710. },
  711. },
  712. },
  713. expectOutput: wire.SNACMessage{
  714. Frame: wire.SNACFrame{
  715. FoodGroup: wire.Admin,
  716. SubGroup: wire.AdminInfoChangeReply,
  717. RequestID: 1337,
  718. },
  719. Body: wire.SNAC_0x07_0x05_AdminChangeReply{
  720. Permissions: wire.AdminInfoPermissionsReadWrite,
  721. TLVBlock: wire.TLVBlock{
  722. TLVList: wire.TLVList{
  723. wire.NewTLV(wire.AdminTLVEmailAddress, "chattingchuck@aol.com"),
  724. },
  725. },
  726. },
  727. },
  728. },
  729. {
  730. name: "proposed email address invalid rfc 5322 format",
  731. userSession: newTestSession("chattingchuck"),
  732. inputSNAC: wire.SNACMessage{
  733. Frame: wire.SNACFrame{
  734. FoodGroup: wire.Admin,
  735. SubGroup: wire.AdminInfoChangeRequest,
  736. RequestID: 1337,
  737. },
  738. Body: wire.SNAC_0x07_0x04_AdminInfoChangeRequest{
  739. TLVRestBlock: wire.TLVRestBlock{
  740. TLVList: wire.TLVList{
  741. wire.NewTLV(wire.AdminTLVEmailAddress, "chattingchuck@@@@@@@aol.com"),
  742. },
  743. },
  744. },
  745. },
  746. expectOutput: wire.SNACMessage{
  747. Frame: wire.SNACFrame{
  748. FoodGroup: wire.Admin,
  749. SubGroup: wire.AdminInfoChangeReply,
  750. RequestID: 1337,
  751. },
  752. Body: wire.SNAC_0x07_0x05_AdminChangeReply{
  753. Permissions: wire.AdminInfoPermissionsReadWrite,
  754. TLVBlock: wire.TLVBlock{
  755. TLVList: wire.TLVList{
  756. wire.NewTLV(wire.AdminTLVErrorCode, wire.AdminInfoErrorInvalidEmail),
  757. wire.NewTLV(wire.AdminTLVUrl, ""),
  758. },
  759. },
  760. },
  761. },
  762. },
  763. {
  764. name: "proposed email address too long",
  765. userSession: newTestSession("chattingchuck"),
  766. inputSNAC: wire.SNACMessage{
  767. Frame: wire.SNACFrame{
  768. FoodGroup: wire.Admin,
  769. SubGroup: wire.AdminInfoChangeRequest,
  770. RequestID: 1337,
  771. },
  772. Body: wire.SNAC_0x07_0x04_AdminInfoChangeRequest{
  773. TLVRestBlock: wire.TLVRestBlock{
  774. TLVList: wire.TLVList{
  775. wire.NewTLV(wire.AdminTLVEmailAddress, longEmailAddress),
  776. },
  777. },
  778. },
  779. },
  780. expectOutput: wire.SNACMessage{
  781. Frame: wire.SNACFrame{
  782. FoodGroup: wire.Admin,
  783. SubGroup: wire.AdminInfoChangeReply,
  784. RequestID: 1337,
  785. },
  786. Body: wire.SNAC_0x07_0x05_AdminChangeReply{
  787. Permissions: wire.AdminInfoPermissionsReadWrite,
  788. TLVBlock: wire.TLVBlock{
  789. TLVList: wire.TLVList{
  790. wire.NewTLV(wire.AdminTLVErrorCode, wire.AdminInfoErrorInvalidEmailLength),
  791. wire.NewTLV(wire.AdminTLVUrl, ""),
  792. },
  793. },
  794. },
  795. },
  796. },
  797. }
  798. for _, tc := range cases {
  799. t.Run(tc.name, func(t *testing.T) {
  800. sessionManager := newMockSessionManager(t)
  801. accountManager := newMockAccountManager(t)
  802. buddyBroadcaster := newMockbuddyBroadcaster(t)
  803. messageRelayer := newMockMessageRelayer(t)
  804. for _, params := range tc.mockParams.accountManagerParams.accountManagerUpdateEmailAddressParams {
  805. accountManager.EXPECT().
  806. UpdateEmailAddress(params.emailAddress, params.screenName).
  807. Return(params.err)
  808. }
  809. svc := AdminService{
  810. sessionManager: sessionManager,
  811. accountManager: accountManager,
  812. buddyUpdateBroadcaster: buddyBroadcaster,
  813. messageRelayer: messageRelayer,
  814. }
  815. outputSNAC, err := svc.InfoChangeRequest(nil, tc.userSession, tc.inputSNAC.Frame, tc.inputSNAC.Body.(wire.SNAC_0x07_0x04_AdminInfoChangeRequest))
  816. assert.ErrorIs(t, err, tc.expectErr)
  817. if tc.expectErr != nil {
  818. return
  819. }
  820. assert.Equal(t, tc.expectOutput, outputSNAC)
  821. })
  822. }
  823. }
  824. func TestAdminService_InfoChangeRequest_RegStatus(t *testing.T) {
  825. cases := []struct {
  826. // name is the unit test name
  827. name string
  828. // cfg is the app configuration
  829. cfg config.Config
  830. // inputSNAC is the SNAC sent from the client to the server
  831. inputSNAC wire.SNACMessage
  832. // mockParams is the list of params sent to mocks that satisfy this
  833. // method's dependencies
  834. mockParams mockParams
  835. // userSession is the session of the user
  836. userSession *state.Session
  837. // expectOutput is the SNAC sent from the server to client
  838. expectOutput wire.SNACMessage
  839. // expectErr is the expected error returned
  840. expectErr error
  841. }{
  842. {
  843. name: "user changes reg preference successfully",
  844. userSession: newTestSession("chattingchuck"),
  845. mockParams: mockParams{
  846. accountManagerParams: accountManagerParams{
  847. accountManagerUpdateRegStatusParams: accountManagerUpdateRegStatusParams{
  848. {
  849. screenName: state.NewIdentScreenName("chattingchuck"),
  850. regStatus: wire.AdminInfoRegStatusNoDisclosure,
  851. },
  852. },
  853. },
  854. },
  855. inputSNAC: wire.SNACMessage{
  856. Frame: wire.SNACFrame{
  857. FoodGroup: wire.Admin,
  858. SubGroup: wire.AdminInfoChangeRequest,
  859. RequestID: 1337,
  860. },
  861. Body: wire.SNAC_0x07_0x04_AdminInfoChangeRequest{
  862. TLVRestBlock: wire.TLVRestBlock{
  863. TLVList: wire.TLVList{
  864. wire.NewTLV(wire.AdminTLVRegistrationStatus, wire.AdminInfoRegStatusNoDisclosure),
  865. },
  866. },
  867. },
  868. },
  869. expectOutput: wire.SNACMessage{
  870. Frame: wire.SNACFrame{
  871. FoodGroup: wire.Admin,
  872. SubGroup: wire.AdminInfoChangeReply,
  873. RequestID: 1337,
  874. },
  875. Body: wire.SNAC_0x07_0x05_AdminChangeReply{
  876. Permissions: wire.AdminInfoPermissionsReadWrite,
  877. TLVBlock: wire.TLVBlock{
  878. TLVList: wire.TLVList{
  879. wire.NewTLV(wire.AdminTLVRegistrationStatus, wire.AdminInfoRegStatusNoDisclosure),
  880. },
  881. },
  882. },
  883. },
  884. },
  885. {
  886. name: "proposed reg preference invalid",
  887. userSession: newTestSession("chattingchuck"),
  888. inputSNAC: wire.SNACMessage{
  889. Frame: wire.SNACFrame{
  890. FoodGroup: wire.Admin,
  891. SubGroup: wire.AdminInfoChangeRequest,
  892. RequestID: 1337,
  893. },
  894. Body: wire.SNAC_0x07_0x04_AdminInfoChangeRequest{
  895. TLVRestBlock: wire.TLVRestBlock{
  896. TLVList: wire.TLVList{
  897. wire.NewTLV(wire.AdminTLVRegistrationStatus, uint16(0x1337)),
  898. },
  899. },
  900. },
  901. },
  902. expectOutput: wire.SNACMessage{
  903. Frame: wire.SNACFrame{
  904. FoodGroup: wire.Admin,
  905. SubGroup: wire.AdminInfoChangeReply,
  906. RequestID: 1337,
  907. },
  908. Body: wire.SNAC_0x07_0x05_AdminChangeReply{
  909. Permissions: wire.AdminInfoPermissionsReadWrite,
  910. TLVBlock: wire.TLVBlock{
  911. TLVList: wire.TLVList{
  912. wire.NewTLV(wire.AdminTLVErrorCode, wire.AdminInfoErrorInvalidRegistrationPreference),
  913. wire.NewTLV(wire.AdminTLVUrl, ""),
  914. },
  915. },
  916. },
  917. },
  918. },
  919. }
  920. for _, tc := range cases {
  921. t.Run(tc.name, func(t *testing.T) {
  922. sessionManager := newMockSessionManager(t)
  923. accountManager := newMockAccountManager(t)
  924. buddyBroadcaster := newMockbuddyBroadcaster(t)
  925. messageRelayer := newMockMessageRelayer(t)
  926. for _, params := range tc.mockParams.accountManagerParams.accountManagerUpdateRegStatusParams {
  927. accountManager.EXPECT().
  928. UpdateRegStatus(params.regStatus, params.screenName).
  929. Return(params.err)
  930. }
  931. svc := AdminService{
  932. sessionManager: sessionManager,
  933. accountManager: accountManager,
  934. buddyUpdateBroadcaster: buddyBroadcaster,
  935. messageRelayer: messageRelayer,
  936. }
  937. outputSNAC, err := svc.InfoChangeRequest(nil, tc.userSession, tc.inputSNAC.Frame, tc.inputSNAC.Body.(wire.SNAC_0x07_0x04_AdminInfoChangeRequest))
  938. assert.ErrorIs(t, err, tc.expectErr)
  939. if tc.expectErr != nil {
  940. return
  941. }
  942. assert.Equal(t, tc.expectOutput, outputSNAC)
  943. })
  944. }
  945. }