4
0

http_test.go 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649
  1. package toc
  2. import (
  3. "encoding/base64"
  4. "io"
  5. "log/slog"
  6. "net/http"
  7. "net/http/httptest"
  8. "testing"
  9. "time"
  10. "github.com/stretchr/testify/assert"
  11. "github.com/stretchr/testify/mock"
  12. "golang.org/x/time/rate"
  13. "github.com/mk6i/retro-aim-server/state"
  14. "github.com/mk6i/retro-aim-server/wire"
  15. )
  16. func TestOSCARProxy_NewServeMux(t *testing.T) {
  17. cookieBaker, err := state.NewHMACCookieBaker()
  18. assert.NoError(t, err)
  19. p := OSCARProxy{
  20. CookieBaker: cookieBaker,
  21. Logger: slog.Default(),
  22. }
  23. cookie, err := p.newHTTPAuthToken(state.NewIdentScreenName("me"))
  24. assert.NoError(t, err)
  25. cases := []struct {
  26. // name is the unit test name
  27. name string
  28. // path is the HTTP request path
  29. path string
  30. // expectedStatus is the expected HTTP response code
  31. expectedStatus int
  32. // expectedBody is the expected body payload
  33. expectedBody string
  34. // mockParams is the list of params sent to mocks that satisfy this
  35. // method's dependencies
  36. mockParams mockParams
  37. }{
  38. {
  39. name: "Successfully retrieve HTML profile",
  40. path: "/info?from=me&user=them&cookie=" + cookie,
  41. expectedStatus: http.StatusOK,
  42. expectedBody: `<font lang="0"><a href="aim:GoChat?RoomName=General&amp;Exchange=4">Let's chat</font></a><br><br><font color="#ff0000" lang="0">colorfg</font><font color="#000000"> </font><font back="#00ff00">colorbg</font><font> </font><font size="4">big</font><font size="3"> <b></font><font>bold</b></font><font> <i></font><font>italic</i></font><font> <u></font><font>underline</u></font><font> 8-)</font><hr><s>strike</s><sub>sub</sub><sup>sup</sup>`,
  43. mockParams: mockParams{
  44. locateParams: locateParams{
  45. userInfoQueryParams: userInfoQueryParams{
  46. {
  47. me: state.NewIdentScreenName("me"),
  48. inBody: wire.SNAC_0x02_0x05_LocateUserInfoQuery{
  49. Type: uint16(wire.LocateTypeSig),
  50. ScreenName: "them",
  51. },
  52. msg: wire.SNACMessage{
  53. Frame: wire.SNACFrame{
  54. FoodGroup: wire.Locate,
  55. SubGroup: wire.LocateUserInfoReply,
  56. },
  57. Body: wire.SNAC_0x02_0x06_LocateUserInfoReply{
  58. TLVUserInfo: newTestSession("them").TLVUserInfo(),
  59. LocateInfo: wire.TLVRestBlock{
  60. TLVList: wire.TLVList{
  61. wire.NewTLVBE(wire.LocateTLVTagsInfoSigData, `"<HTML><BODY BGCOLOR="#ffffff"><FONT LANG="0"><A HREF="aim:GoChat?RoomName=General&Exchange=4">Let's chat</FONT></A><BR><BR><FONT COLOR="#ff0000" LANG="0">colorfg</FONT><FONT COLOR="#000000"> </FONT><FONT BACK="#00ff00">colorbg</FONT><FONT> </FONT><FONT SIZE=4>big</FONT><FONT SIZE=3> <B></FONT><FONT>bold</B></FONT><FONT> <I></FONT><FONT>italic</I></FONT><FONT> <U></FONT><FONT>underline</U></FONT><FONT> 8-)</FONT><HR><S>strike</S><SUB>sub</SUB><SUP>sup</SUP></BODY></HTML>"`),
  62. },
  63. },
  64. },
  65. },
  66. },
  67. },
  68. },
  69. },
  70. },
  71. {
  72. name: "Successfully retrieve plaintext profile",
  73. path: "/info?from=me&user=them&cookie=" + cookie,
  74. expectedStatus: http.StatusOK,
  75. expectedBody: "My profile!",
  76. mockParams: mockParams{
  77. locateParams: locateParams{
  78. userInfoQueryParams: userInfoQueryParams{
  79. {
  80. me: state.NewIdentScreenName("me"),
  81. inBody: wire.SNAC_0x02_0x05_LocateUserInfoQuery{
  82. Type: uint16(wire.LocateTypeSig),
  83. ScreenName: "them",
  84. },
  85. msg: wire.SNACMessage{
  86. Frame: wire.SNACFrame{
  87. FoodGroup: wire.Locate,
  88. SubGroup: wire.LocateUserInfoReply,
  89. },
  90. Body: wire.SNAC_0x02_0x06_LocateUserInfoReply{
  91. TLVUserInfo: newTestSession("them").TLVUserInfo(),
  92. LocateInfo: wire.TLVRestBlock{
  93. TLVList: wire.TLVList{
  94. wire.NewTLVBE(wire.LocateTLVTagsInfoSigData, "My profile!"),
  95. },
  96. },
  97. },
  98. },
  99. },
  100. },
  101. },
  102. },
  103. },
  104. {
  105. name: "Retrieve profile with missing `from` query param",
  106. path: "/info?user=them&cookie=" + cookie,
  107. expectedStatus: http.StatusBadRequest,
  108. expectedBody: "required `from` param is missing",
  109. },
  110. {
  111. name: "Retrieve profile with missing `from` query param",
  112. path: "/info?from=me&cookie=" + cookie,
  113. expectedStatus: http.StatusBadRequest,
  114. expectedBody: "required `user` param is missing",
  115. },
  116. {
  117. name: "Retrieve profile with missing `cookie` query param",
  118. path: "/info?from=me&user=them",
  119. expectedStatus: http.StatusBadRequest,
  120. expectedBody: "required `cookie` param is missing",
  121. },
  122. {
  123. name: "Retrieve profile with invalid auth cookie",
  124. path: func() string {
  125. return "/info?from=me&user=them&cookie=" + base64.URLEncoding.EncodeToString([]byte("blahblah"))
  126. }(),
  127. expectedStatus: http.StatusForbidden,
  128. expectedBody: "invalid auth cookie",
  129. },
  130. {
  131. name: "Retrieve profile, receive error from locate svc",
  132. path: "/info?from=me&user=them&cookie=" + cookie,
  133. expectedStatus: http.StatusInternalServerError,
  134. expectedBody: "internal server error",
  135. mockParams: mockParams{
  136. locateParams: locateParams{
  137. userInfoQueryParams: userInfoQueryParams{
  138. {
  139. me: state.NewIdentScreenName("me"),
  140. inBody: wire.SNAC_0x02_0x05_LocateUserInfoQuery{
  141. Type: uint16(wire.LocateTypeSig),
  142. ScreenName: "them",
  143. },
  144. msg: wire.SNACMessage{
  145. Frame: wire.SNACFrame{
  146. FoodGroup: wire.Locate,
  147. SubGroup: wire.LocateUserInfoReply,
  148. },
  149. Body: wire.SNAC_0x02_0x06_LocateUserInfoReply{
  150. TLVUserInfo: newTestSession("them").TLVUserInfo(),
  151. LocateInfo: wire.TLVRestBlock{
  152. TLVList: wire.TLVList{
  153. wire.NewTLVBE(wire.LocateTLVTagsInfoSigData, "<HTML><BODY>My profile!</BODY></HTML>"),
  154. },
  155. },
  156. },
  157. },
  158. err: io.EOF,
  159. },
  160. },
  161. },
  162. },
  163. },
  164. {
  165. name: "Retrieve profile, receive unknown response from locate svc",
  166. path: "/info?from=me&user=them&cookie=" + cookie,
  167. expectedStatus: http.StatusInternalServerError,
  168. expectedBody: "internal server error",
  169. mockParams: mockParams{
  170. locateParams: locateParams{
  171. userInfoQueryParams: userInfoQueryParams{
  172. {
  173. me: state.NewIdentScreenName("me"),
  174. inBody: wire.SNAC_0x02_0x05_LocateUserInfoQuery{
  175. Type: uint16(wire.LocateTypeSig),
  176. ScreenName: "them",
  177. },
  178. msg: wire.SNACMessage{
  179. Frame: wire.SNACFrame{
  180. FoodGroup: wire.Locate,
  181. SubGroup: wire.LocateUserInfoReply,
  182. },
  183. Body: wire.SNAC_0x04_0x09_ICBMEvilReply{},
  184. },
  185. },
  186. },
  187. },
  188. },
  189. },
  190. {
  191. name: "Retrieve profile, user offline",
  192. path: "/info?from=me&user=them&cookie=" + cookie,
  193. expectedStatus: http.StatusNotFound,
  194. expectedBody: "user is unavailable",
  195. mockParams: mockParams{
  196. locateParams: locateParams{
  197. userInfoQueryParams: userInfoQueryParams{
  198. {
  199. me: state.NewIdentScreenName("me"),
  200. inBody: wire.SNAC_0x02_0x05_LocateUserInfoQuery{
  201. Type: uint16(wire.LocateTypeSig),
  202. ScreenName: "them",
  203. },
  204. msg: wire.SNACMessage{
  205. Frame: wire.SNACFrame{
  206. FoodGroup: wire.Locate,
  207. SubGroup: wire.LocateUserInfoReply,
  208. },
  209. Body: wire.SNACError{
  210. Code: wire.ErrorCodeNotLoggedOn,
  211. },
  212. },
  213. },
  214. },
  215. },
  216. },
  217. },
  218. {
  219. name: "Retrieve profile, receive error code from locate svc",
  220. path: "/info?from=me&user=them&cookie=" + cookie,
  221. expectedStatus: http.StatusInternalServerError,
  222. expectedBody: "internal server error",
  223. mockParams: mockParams{
  224. locateParams: locateParams{
  225. userInfoQueryParams: userInfoQueryParams{
  226. {
  227. me: state.NewIdentScreenName("me"),
  228. inBody: wire.SNAC_0x02_0x05_LocateUserInfoQuery{
  229. Type: uint16(wire.LocateTypeSig),
  230. ScreenName: "them",
  231. },
  232. msg: wire.SNACMessage{
  233. Frame: wire.SNACFrame{
  234. FoodGroup: wire.Locate,
  235. SubGroup: wire.LocateUserInfoReply,
  236. },
  237. Body: wire.SNACError{
  238. Code: wire.ErrorCodeInvalidSnac,
  239. },
  240. },
  241. },
  242. },
  243. },
  244. },
  245. },
  246. {
  247. name: "Successfully retrieve directory info",
  248. path: "/dir_info?user=them&cookie=" + cookie,
  249. expectedStatus: http.StatusOK,
  250. expectedBody: "their_first_name",
  251. mockParams: mockParams{
  252. locateParams: locateParams{
  253. dirInfoParams: dirInfoParams{
  254. {
  255. body: wire.SNAC_0x02_0x0B_LocateGetDirInfo{
  256. ScreenName: "them",
  257. },
  258. msg: wire.SNACMessage{
  259. Body: wire.SNAC_0x02_0x0C_LocateGetDirReply{
  260. Status: wire.LocateGetDirReplyOK,
  261. TLVBlock: wire.TLVBlock{
  262. TLVList: wire.TLVList{
  263. wire.NewTLVBE(wire.ODirTLVFirstName, "their_first_name"),
  264. },
  265. },
  266. },
  267. },
  268. },
  269. },
  270. },
  271. },
  272. },
  273. {
  274. name: "Retrieve directory info, no results found",
  275. path: "/dir_info?user=them&cookie=" + cookie,
  276. expectedStatus: http.StatusNotFound,
  277. expectedBody: "no user directory info found",
  278. mockParams: mockParams{
  279. locateParams: locateParams{
  280. dirInfoParams: dirInfoParams{
  281. {
  282. body: wire.SNAC_0x02_0x0B_LocateGetDirInfo{
  283. ScreenName: "them",
  284. },
  285. msg: wire.SNACMessage{
  286. Body: wire.SNAC_0x02_0x0C_LocateGetDirReply{
  287. Status: wire.LocateGetDirReplyOK,
  288. TLVBlock: wire.TLVBlock{
  289. TLVList: wire.TLVList{},
  290. },
  291. },
  292. },
  293. },
  294. },
  295. },
  296. },
  297. },
  298. {
  299. name: "Retrieve directory info, unexpected response from locate svc",
  300. path: "/dir_info?user=them&cookie=" + cookie,
  301. expectedStatus: http.StatusInternalServerError,
  302. expectedBody: "internal server error",
  303. mockParams: mockParams{
  304. locateParams: locateParams{
  305. dirInfoParams: dirInfoParams{
  306. {
  307. body: wire.SNAC_0x02_0x0B_LocateGetDirInfo{
  308. ScreenName: "them",
  309. },
  310. msg: wire.SNACMessage{
  311. Body: wire.SNACError{},
  312. },
  313. },
  314. },
  315. },
  316. },
  317. },
  318. {
  319. name: "Search directory with missing `user` query param",
  320. path: "/dir_info?cookie=" + cookie,
  321. expectedStatus: http.StatusBadRequest,
  322. expectedBody: "required `user` param is missing",
  323. },
  324. {
  325. name: "Retrieve directory info, receive err from locate svc",
  326. path: "/dir_info?user=them&cookie=" + cookie,
  327. expectedStatus: http.StatusInternalServerError,
  328. expectedBody: "internal server error",
  329. mockParams: mockParams{
  330. locateParams: locateParams{
  331. dirInfoParams: dirInfoParams{
  332. {
  333. body: wire.SNAC_0x02_0x0B_LocateGetDirInfo{
  334. ScreenName: "them",
  335. },
  336. msg: wire.SNACMessage{
  337. Body: wire.SNAC_0x02_0x0C_LocateGetDirReply{
  338. Status: wire.LocateGetDirReplyOK,
  339. TLVBlock: wire.TLVBlock{
  340. TLVList: wire.TLVList{
  341. wire.NewTLVBE(wire.ODirTLVFirstName, "their_first_name"),
  342. },
  343. },
  344. },
  345. },
  346. err: io.EOF,
  347. },
  348. },
  349. },
  350. },
  351. },
  352. {
  353. name: "Successfully search directory by name and address",
  354. path: "/dir_search?first_name=their_first_name" +
  355. "&middle_name=their_middle_name" +
  356. "&last_name=their_last_name" +
  357. "&maiden_name=their_maiden_name" +
  358. "&city=their_city" +
  359. "&state=their_state" +
  360. "&country=their_country" +
  361. "&cookie=" + cookie,
  362. expectedStatus: http.StatusOK,
  363. expectedBody: "their_first_name",
  364. mockParams: mockParams{
  365. dirSearchParams: dirSearchParams{
  366. infoQueryParams: infoQueryParams{
  367. {
  368. inBody: wire.SNAC_0x0F_0x02_InfoQuery{
  369. TLVRestBlock: wire.TLVRestBlock{
  370. TLVList: wire.TLVList{
  371. wire.NewTLVBE(wire.ODirTLVFirstName, "their_first_name"),
  372. wire.NewTLVBE(wire.ODirTLVMiddleName, "their_middle_name"),
  373. wire.NewTLVBE(wire.ODirTLVLastName, "their_last_name"),
  374. wire.NewTLVBE(wire.ODirTLVMaidenName, "their_maiden_name"),
  375. wire.NewTLVBE(wire.ODirTLVCity, "their_city"),
  376. wire.NewTLVBE(wire.ODirTLVState, "their_state"),
  377. wire.NewTLVBE(wire.ODirTLVCountry, "their_country"),
  378. },
  379. },
  380. },
  381. msg: wire.SNACMessage{
  382. Body: wire.SNAC_0x0F_0x03_InfoReply{
  383. Status: wire.ODirSearchResponseOK,
  384. Results: struct {
  385. List []wire.TLVBlock `oscar:"count_prefix=uint16"`
  386. }{
  387. List: []wire.TLVBlock{
  388. {
  389. TLVList: wire.TLVList{
  390. wire.NewTLVBE(wire.ODirTLVFirstName, "their_first_name"),
  391. },
  392. },
  393. },
  394. },
  395. },
  396. },
  397. },
  398. },
  399. },
  400. },
  401. },
  402. {
  403. name: "Successfully search directory by email",
  404. path: "/dir_search?email=their_email@aol.com&cookie=" + cookie,
  405. expectedStatus: http.StatusOK,
  406. expectedBody: "their_first_name",
  407. mockParams: mockParams{
  408. dirSearchParams: dirSearchParams{
  409. infoQueryParams: infoQueryParams{
  410. {
  411. inBody: wire.SNAC_0x0F_0x02_InfoQuery{
  412. TLVRestBlock: wire.TLVRestBlock{
  413. TLVList: wire.TLVList{
  414. wire.NewTLVBE(wire.ODirTLVEmailAddress, "their_email@aol.com"),
  415. },
  416. },
  417. },
  418. msg: wire.SNACMessage{
  419. Body: wire.SNAC_0x0F_0x03_InfoReply{
  420. Status: wire.ODirSearchResponseOK,
  421. Results: struct {
  422. List []wire.TLVBlock `oscar:"count_prefix=uint16"`
  423. }{
  424. List: []wire.TLVBlock{
  425. {
  426. TLVList: wire.TLVList{
  427. wire.NewTLVBE(wire.ODirTLVFirstName, "their_first_name"),
  428. },
  429. },
  430. },
  431. },
  432. },
  433. },
  434. },
  435. },
  436. },
  437. },
  438. },
  439. {
  440. name: "Successfully search directory by keyword",
  441. path: "/dir_search?keyword=their_keyword&cookie=" + cookie,
  442. expectedStatus: http.StatusOK,
  443. expectedBody: "their_first_name",
  444. mockParams: mockParams{
  445. dirSearchParams: dirSearchParams{
  446. infoQueryParams: infoQueryParams{
  447. {
  448. inBody: wire.SNAC_0x0F_0x02_InfoQuery{
  449. TLVRestBlock: wire.TLVRestBlock{
  450. TLVList: wire.TLVList{
  451. wire.NewTLVBE(wire.ODirTLVInterest, "their_keyword"),
  452. },
  453. },
  454. },
  455. msg: wire.SNACMessage{
  456. Body: wire.SNAC_0x0F_0x03_InfoReply{
  457. Status: wire.ODirSearchResponseOK,
  458. Results: struct {
  459. List []wire.TLVBlock `oscar:"count_prefix=uint16"`
  460. }{
  461. List: []wire.TLVBlock{
  462. {
  463. TLVList: wire.TLVList{
  464. wire.NewTLVBE(wire.ODirTLVFirstName, "their_first_name"),
  465. },
  466. },
  467. },
  468. },
  469. },
  470. },
  471. },
  472. },
  473. },
  474. },
  475. },
  476. {
  477. name: "Search directory by email, receive err from dir search svc",
  478. path: "/dir_search?email=their_email@aol.com&cookie=" + cookie,
  479. expectedStatus: http.StatusInternalServerError,
  480. expectedBody: "internal server error",
  481. mockParams: mockParams{
  482. dirSearchParams: dirSearchParams{
  483. infoQueryParams: infoQueryParams{
  484. {
  485. inBody: wire.SNAC_0x0F_0x02_InfoQuery{
  486. TLVRestBlock: wire.TLVRestBlock{
  487. TLVList: wire.TLVList{
  488. wire.NewTLVBE(wire.ODirTLVEmailAddress, "their_email@aol.com"),
  489. },
  490. },
  491. },
  492. msg: wire.SNACMessage{
  493. Body: wire.SNAC_0x0F_0x03_InfoReply{
  494. Status: wire.ODirSearchResponseOK,
  495. Results: struct {
  496. List []wire.TLVBlock `oscar:"count_prefix=uint16"`
  497. }{
  498. List: []wire.TLVBlock{
  499. {
  500. TLVList: wire.TLVList{
  501. wire.NewTLVBE(wire.ODirTLVFirstName, "their_first_name"),
  502. },
  503. },
  504. },
  505. },
  506. },
  507. },
  508. err: io.EOF,
  509. },
  510. },
  511. },
  512. },
  513. },
  514. {
  515. name: "Search directory by email, receive unknown response from dir search svc",
  516. path: "/dir_search?email=their_email@aol.com&cookie=" + cookie,
  517. expectedStatus: http.StatusInternalServerError,
  518. expectedBody: "internal server error",
  519. mockParams: mockParams{
  520. dirSearchParams: dirSearchParams{
  521. infoQueryParams: infoQueryParams{
  522. {
  523. inBody: wire.SNAC_0x0F_0x02_InfoQuery{
  524. TLVRestBlock: wire.TLVRestBlock{
  525. TLVList: wire.TLVList{
  526. wire.NewTLVBE(wire.ODirTLVEmailAddress, "their_email@aol.com"),
  527. },
  528. },
  529. },
  530. msg: wire.SNACMessage{
  531. Body: wire.SNACError{},
  532. },
  533. },
  534. },
  535. },
  536. },
  537. },
  538. {
  539. name: "Search directory without any correct search parameters",
  540. path: "/dir_search?cookie=" + cookie,
  541. expectedStatus: http.StatusBadRequest,
  542. expectedBody: "missing search parameters",
  543. mockParams: mockParams{
  544. dirSearchParams: dirSearchParams{
  545. infoQueryParams: infoQueryParams{
  546. {
  547. inBody: wire.SNAC_0x0F_0x02_InfoQuery{},
  548. msg: wire.SNACMessage{
  549. Body: wire.SNAC_0x0F_0x03_InfoReply{
  550. Status: wire.ODirSearchResponseNameMissing,
  551. },
  552. },
  553. },
  554. },
  555. },
  556. },
  557. },
  558. {
  559. name: "Search directory, receive error code from search dir svc",
  560. path: "/dir_search?cookie=" + cookie,
  561. expectedStatus: http.StatusInternalServerError,
  562. expectedBody: "internal server error",
  563. mockParams: mockParams{
  564. dirSearchParams: dirSearchParams{
  565. infoQueryParams: infoQueryParams{
  566. {
  567. inBody: wire.SNAC_0x0F_0x02_InfoQuery{},
  568. msg: wire.SNACMessage{
  569. Body: wire.SNAC_0x0F_0x03_InfoReply{
  570. Status: wire.ODirSearchResponseUnavailable1,
  571. },
  572. },
  573. },
  574. },
  575. },
  576. },
  577. },
  578. {
  579. name: "Search directory, receive unknown response from search dir svc",
  580. path: "/dir_search?cookie=" + cookie,
  581. expectedStatus: http.StatusInternalServerError,
  582. expectedBody: "internal server error",
  583. mockParams: mockParams{
  584. dirSearchParams: dirSearchParams{
  585. infoQueryParams: infoQueryParams{
  586. {
  587. inBody: wire.SNAC_0x0F_0x02_InfoQuery{},
  588. msg: wire.SNACMessage{
  589. Body: wire.SNAC_0x0F_0x03_InfoReply{
  590. Status: wire.ODirSearchResponseUnavailable1,
  591. },
  592. },
  593. },
  594. },
  595. },
  596. },
  597. },
  598. }
  599. for _, tc := range cases {
  600. t.Run(tc.name, func(t *testing.T) {
  601. locateSvc := newMockLocateService(t)
  602. for _, params := range tc.mockParams.userInfoQueryParams {
  603. locateSvc.EXPECT().
  604. UserInfoQuery(mock.Anything, matchSession(params.me), wire.SNACFrame{}, params.inBody).
  605. Return(params.msg, params.err)
  606. }
  607. for _, params := range tc.mockParams.dirInfoParams {
  608. locateSvc.EXPECT().
  609. DirInfo(mock.Anything, wire.SNACFrame{}, params.body).
  610. Return(params.msg, params.err)
  611. }
  612. dirSearchSvc := newMockDirSearchService(t)
  613. for _, params := range tc.mockParams.infoQueryParams {
  614. dirSearchSvc.EXPECT().
  615. InfoQuery(mock.Anything, wire.SNACFrame{}, params.inBody).
  616. Return(params.msg, params.err)
  617. }
  618. svc := OSCARProxy{
  619. CookieBaker: cookieBaker,
  620. DirSearchService: dirSearchSvc,
  621. LocateService: locateSvc,
  622. Logger: slog.Default(),
  623. HTTPIPRateLimiter: NewIPRateLimiter(rate.Every(1*time.Minute), 10, 1*time.Minute),
  624. SNACRateLimits: wire.DefaultSNACRateLimits(),
  625. }
  626. req, err := http.NewRequest(http.MethodGet, tc.path, nil)
  627. req.RemoteAddr = "127.0.0.1:1234"
  628. if err != nil {
  629. t.Fatalf("Failed to create request: %v", err)
  630. }
  631. rr := httptest.NewRecorder()
  632. svc.NewServeMux().ServeHTTP(rr, req)
  633. assert.Equal(t, tc.expectedStatus, rr.Code)
  634. assert.Contains(t, rr.Body.String(), tc.expectedBody)
  635. })
  636. }
  637. }