email_helper_test.rb 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538
  1. require 'test_helper'
  2. class EmailHelperTest < ActiveSupport::TestCase
  3. test 'a mx_records' do
  4. domain = 'zammad.com'
  5. mx_domains = EmailHelper.mx_records(domain)
  6. assert_equal('mx2.zammad.com', mx_domains[0])
  7. end
  8. test 'a email parser test' do
  9. user, domain = EmailHelper.parse_email('somebody@example.com')
  10. assert_equal('somebody', user)
  11. assert_equal('example.com', domain)
  12. user, domain = EmailHelper.parse_email('somebody+test@example.com')
  13. assert_equal('somebody+test', user)
  14. assert_equal('example.com', domain)
  15. user, domain = EmailHelper.parse_email('somebody+testexample.com')
  16. assert_not(user)
  17. assert_not(domain)
  18. end
  19. test 'provider test' do
  20. email = 'linus@kernel.org'
  21. password = 'some_pw'
  22. map = EmailHelper.provider(email, password)
  23. assert_equal('imap', map[:google_imap][:inbound][:adapter])
  24. assert_equal('imap.gmail.com', map[:google_imap][:inbound][:options][:host])
  25. assert_equal(993, map[:google_imap][:inbound][:options][:port])
  26. assert_equal(email, map[:google_imap][:inbound][:options][:user])
  27. assert_equal(password, map[:google_imap][:inbound][:options][:password])
  28. assert_equal('smtp', map[:google_imap][:outbound][:adapter])
  29. assert_equal('smtp.gmail.com', map[:google_imap][:outbound][:options][:host])
  30. assert_equal(25, map[:google_imap][:outbound][:options][:port])
  31. assert_equal(true, map[:google_imap][:outbound][:options][:start_tls])
  32. assert_equal(email, map[:google_imap][:outbound][:options][:user])
  33. assert_equal(password, map[:google_imap][:outbound][:options][:password])
  34. end
  35. test 'provider_inbound_mx' do
  36. email = 'linus@zammad.com'
  37. password = 'some_pw'
  38. user, domain = EmailHelper.parse_email(email)
  39. mx_domains = EmailHelper.mx_records(domain)
  40. map = EmailHelper.provider_inbound_mx(user, email, password, mx_domains)
  41. assert_equal('imap', map[0][:adapter])
  42. assert_equal('mx2.zammad.com', map[0][:options][:host])
  43. assert_equal(993, map[0][:options][:port])
  44. assert_equal(user, map[0][:options][:user])
  45. assert_equal(password, map[0][:options][:password])
  46. assert_equal('imap', map[1][:adapter])
  47. assert_equal('mx2.zammad.com', map[1][:options][:host])
  48. assert_equal(993, map[1][:options][:port])
  49. assert_equal(email, map[1][:options][:user])
  50. assert_equal(password, map[1][:options][:password])
  51. end
  52. test 'provider_inbound_guess' do
  53. email = 'linus@zammad.com'
  54. password = 'some_pw'
  55. user, domain = EmailHelper.parse_email(email)
  56. map = EmailHelper.provider_inbound_guess(user, email, password, domain)
  57. assert_equal('imap', map[0][:adapter])
  58. assert_equal('mail.zammad.com', map[0][:options][:host])
  59. assert_equal(993, map[0][:options][:port])
  60. assert_equal(user, map[0][:options][:user])
  61. assert_equal(password, map[0][:options][:password])
  62. assert_equal('imap', map[1][:adapter])
  63. assert_equal('mail.zammad.com', map[1][:options][:host])
  64. assert_equal(993, map[1][:options][:port])
  65. assert_equal(email, map[1][:options][:user])
  66. assert_equal(password, map[1][:options][:password])
  67. end
  68. test 'provider_outbound_mx' do
  69. email = 'linus@zammad.com'
  70. password = 'some_pw'
  71. user, domain = EmailHelper.parse_email(email)
  72. mx_domains = EmailHelper.mx_records(domain)
  73. map = EmailHelper.provider_outbound_mx(user, email, password, mx_domains)
  74. assert_equal('smtp', map[0][:adapter])
  75. assert_equal('mx2.zammad.com', map[0][:options][:host])
  76. assert_equal(25, map[0][:options][:port])
  77. assert_equal(true, map[0][:options][:start_tls])
  78. assert_equal(user, map[0][:options][:user])
  79. assert_equal(password, map[0][:options][:password])
  80. assert_equal('smtp', map[1][:adapter])
  81. assert_equal('mx2.zammad.com', map[1][:options][:host])
  82. assert_equal(25, map[1][:options][:port])
  83. assert_equal(true, map[1][:options][:start_tls])
  84. assert_equal(email, map[1][:options][:user])
  85. assert_equal(password, map[1][:options][:password])
  86. end
  87. test 'provider_outbound_guess' do
  88. email = 'linus@zammad.com'
  89. password = 'some_pw'
  90. user, domain = EmailHelper.parse_email(email)
  91. map = EmailHelper.provider_outbound_guess(user, email, password, domain)
  92. assert_equal('smtp', map[0][:adapter])
  93. assert_equal('mail.zammad.com', map[0][:options][:host])
  94. assert_equal(25, map[0][:options][:port])
  95. assert_equal(true, map[0][:options][:start_tls])
  96. assert_equal(user, map[0][:options][:user])
  97. assert_equal(password, map[0][:options][:password])
  98. assert_equal('smtp', map[1][:adapter])
  99. assert_equal('mail.zammad.com', map[1][:options][:host])
  100. assert_equal(25, map[1][:options][:port])
  101. assert_equal(true, map[1][:options][:start_tls])
  102. assert_equal(email, map[1][:options][:user])
  103. assert_equal(password, map[1][:options][:password])
  104. end
  105. test 'z probe_inbound' do
  106. # invalid adapter
  107. result = EmailHelper::Probe.inbound(
  108. adapter: 'imap2',
  109. options: {
  110. host: 'nonexisting_host',
  111. port: 993,
  112. ssl: true,
  113. user: 'some@example.com',
  114. password: 'password',
  115. }
  116. )
  117. assert_equal('failed', result[:result])
  118. # network issues
  119. result = EmailHelper::Probe.inbound(
  120. adapter: 'imap',
  121. options: {
  122. host: 'nonexisting_host',
  123. port: 993,
  124. ssl: true,
  125. user: 'some@example.com',
  126. password: 'password',
  127. }
  128. )
  129. assert_equal('invalid', result[:result])
  130. assert_equal('Hostname not found!', result[:message_human])
  131. assert_equal('nonexisting_host', result[:settings][:options][:host])
  132. # try to access imap on host with blocked port to force a "Connection refused!" error
  133. result = EmailHelper::Probe.inbound(
  134. adapter: 'imap',
  135. options: {
  136. host: '127.0.0.1',
  137. port: 8, # no service to be expected
  138. ssl: true,
  139. user: 'some@example.com',
  140. password: 'password',
  141. }
  142. )
  143. assert_equal('invalid', result[:result])
  144. assert_equal('Connection refused!', result[:message_human])
  145. assert_equal('127.0.0.1', result[:settings][:options][:host])
  146. result = EmailHelper::Probe.inbound(
  147. adapter: 'imap',
  148. options: {
  149. host: '172.42.42.42',
  150. port: 993,
  151. ssl: true,
  152. user: 'some@example.com',
  153. password: 'password',
  154. }
  155. )
  156. assert_equal('invalid', result[:result])
  157. assert_match(%r{Host not reachable|No route to host}, result[:message_human])
  158. assert_equal('172.42.42.42', result[:settings][:options][:host])
  159. # gmail
  160. result = EmailHelper::Probe.inbound(
  161. adapter: 'imap',
  162. options: {
  163. host: 'imap.gmail.com',
  164. port: 993,
  165. ssl: true,
  166. user: 'some@example.com',
  167. password: 'password',
  168. }
  169. )
  170. assert_equal('invalid', result[:result])
  171. assert_match(%r{Authentication failed, username incorrect|Authentication failed, invalid credentials}, result[:message_human])
  172. assert_equal('imap.gmail.com', result[:settings][:options][:host])
  173. result = EmailHelper::Probe.inbound(
  174. adapter: 'imap',
  175. options: {
  176. host: 'imap.gmail.com',
  177. port: 993,
  178. ssl: true,
  179. user: 'frank.tailor05@googlemail.com',
  180. password: 'password',
  181. }
  182. )
  183. assert_equal('invalid', result[:result])
  184. # if we have to many failed logins, we need to handle another error message
  185. if result[:message_human].present?
  186. assert_match(%r{Authentication failed, username incorrect|Authentication failed, invalid credentials}, result[:message_human])
  187. else
  188. assert_match(%r{Web login required}, result[:message])
  189. end
  190. assert_equal('imap.gmail.com', result[:settings][:options][:host])
  191. # dovecot
  192. result = EmailHelper::Probe.inbound(
  193. adapter: 'imap',
  194. options: {
  195. host: 'mx2.zammad.com',
  196. port: 993,
  197. ssl: true,
  198. user: 'some@example.com',
  199. password: 'password',
  200. }
  201. )
  202. assert_equal('invalid', result[:result])
  203. assert_equal('Authentication failed!', result[:message_human])
  204. assert_equal('mx2.zammad.com', result[:settings][:options][:host])
  205. # realtest - test I
  206. if !ENV['EMAILHELPER_MAILBOX_1']
  207. raise "Need EMAILHELPER_MAILBOX_1 as ENV variable like export EMAILHELPER_MAILBOX_1='unittestemailhelper01@zammad.com:somepass'"
  208. end
  209. mailbox_user = ENV['EMAILHELPER_MAILBOX_1'].split(':')[0]
  210. mailbox_password = ENV['EMAILHELPER_MAILBOX_1'].split(':')[1]
  211. result = EmailHelper::Probe.inbound(
  212. adapter: 'imap',
  213. options: {
  214. host: 'mx2.zammad.com',
  215. port: 993,
  216. ssl: true,
  217. user: mailbox_user,
  218. password: mailbox_password,
  219. }
  220. )
  221. assert_equal('ok', result[:result])
  222. end
  223. test 'z probe_outbound' do
  224. # invalid adapter
  225. result = EmailHelper::Probe.outbound(
  226. {
  227. adapter: 'smtp2',
  228. options: {
  229. host: 'nonexisting_host',
  230. port: 25,
  231. start_tls: true,
  232. user: 'some@example.com',
  233. password: 'password',
  234. },
  235. },
  236. 'some@example.com',
  237. )
  238. assert_equal('failed', result[:result])
  239. # network issues
  240. result = EmailHelper::Probe.outbound(
  241. {
  242. adapter: 'smtp',
  243. options: {
  244. host: 'nonexisting_host',
  245. port: 25,
  246. start_tls: true,
  247. user: 'some@example.com',
  248. password: 'password',
  249. }
  250. },
  251. 'some@example.com',
  252. )
  253. assert_equal('invalid', result[:result])
  254. assert_equal('Hostname not found!', result[:message_human])
  255. assert_equal('nonexisting_host', result[:settings][:options][:host])
  256. # try to access SMTP on host with blocked port to force a "Connection refused!" error
  257. result = EmailHelper::Probe.outbound(
  258. {
  259. adapter: 'smtp',
  260. options: {
  261. host: '127.0.0.1',
  262. port: 8, # no service to be expected
  263. start_tls: true,
  264. user: 'some@example.com',
  265. password: 'password',
  266. }
  267. },
  268. 'some@example.com',
  269. )
  270. assert_equal('invalid', result[:result])
  271. assert_equal('Connection refused!', result[:message_human])
  272. assert_equal('127.0.0.1', result[:settings][:options][:host])
  273. result = EmailHelper::Probe.outbound(
  274. {
  275. adapter: 'smtp',
  276. options: {
  277. host: '172.42.42.42',
  278. port: 25,
  279. start_tls: true,
  280. user: 'some@example.com',
  281. password: 'password',
  282. }
  283. },
  284. 'some@example.com',
  285. )
  286. assert_equal('invalid', result[:result])
  287. assert_match(%r{Host not reachable|No route to host}, result[:message_human])
  288. assert_equal('172.42.42.42', result[:settings][:options][:host])
  289. # gmail
  290. result = EmailHelper::Probe.outbound(
  291. {
  292. adapter: 'smtp',
  293. options: {
  294. host: 'smtp.gmail.com',
  295. port: 25,
  296. start_tls: true,
  297. user: 'some@example.com',
  298. password: 'password',
  299. }
  300. },
  301. 'some@example.com',
  302. )
  303. assert_equal('invalid', result[:result])
  304. assert_equal('Authentication failed!', result[:message_human])
  305. assert_equal('smtp.gmail.com', result[:settings][:options][:host])
  306. result = EmailHelper::Probe.outbound(
  307. {
  308. adapter: 'smtp',
  309. options: {
  310. host: 'smtp.gmail.com',
  311. port: 25,
  312. start_tls: true,
  313. user: 'frank.tailor05@googlemail.com',
  314. password: 'password',
  315. }
  316. },
  317. 'some@example.com',
  318. )
  319. assert_equal('invalid', result[:result])
  320. # if we have to many failed logins, we need to handle another error message
  321. if result[:message_human].present?
  322. assert_equal('Authentication failed!', result[:message_human])
  323. else
  324. assert_match(%r{Please log in with your web browser and then try again}, result[:message])
  325. end
  326. assert_equal('smtp.gmail.com', result[:settings][:options][:host])
  327. # dovecot
  328. result = EmailHelper::Probe.outbound(
  329. {
  330. adapter: 'smtp',
  331. options: {
  332. host: 'mx2.zammad.com',
  333. port: 587,
  334. user: 'some@example.com',
  335. password: 'password',
  336. }
  337. },
  338. 'some@example.com',
  339. )
  340. assert_equal('invalid', result[:result])
  341. assert_equal('Authentication failed!', result[:message_human])
  342. assert_equal('mx2.zammad.com', result[:settings][:options][:host])
  343. # realtest - test I
  344. if !ENV['EMAILHELPER_MAILBOX_1']
  345. raise "Need EMAILHELPER_MAILBOX_1 as ENV variable like export EMAILHELPER_MAILBOX_1='unittestemailhelper01@zammad.com:somepass'"
  346. end
  347. mailbox_user = ENV['EMAILHELPER_MAILBOX_1'].split(':')[0]
  348. mailbox_password = ENV['EMAILHELPER_MAILBOX_1'].split(':')[1]
  349. result = EmailHelper::Probe.outbound(
  350. {
  351. adapter: 'smtp',
  352. options: {
  353. host: 'mx2.zammad.com',
  354. port: 587,
  355. user: mailbox_user,
  356. password: mailbox_password,
  357. }
  358. },
  359. mailbox_user,
  360. )
  361. assert_equal('ok', result[:result])
  362. end
  363. test 'zz probe' do
  364. result = EmailHelper::Probe.full(
  365. email: 'invalid_format',
  366. password: 'somepass',
  367. )
  368. assert_equal('invalid', result[:result])
  369. assert_not(result[:setting])
  370. # realtest - test I, with imap
  371. if !ENV['EMAILHELPER_MAILBOX_1']
  372. raise "Need EMAILHELPER_MAILBOX_1 as ENV variable like export EMAILHELPER_MAILBOX_1='unittestemailhelper01@zammad.com:somepass'"
  373. end
  374. mailbox_user = ENV['EMAILHELPER_MAILBOX_1'].split(':')[0]
  375. mailbox_password = ENV['EMAILHELPER_MAILBOX_1'].split(':')[1]
  376. result = EmailHelper::Probe.full(
  377. email: mailbox_user,
  378. password: mailbox_password,
  379. )
  380. assert_equal('ok', result[:result])
  381. assert_equal('mx2.zammad.com', result[:setting][:inbound][:options][:host])
  382. assert_equal('mx2.zammad.com', result[:setting][:outbound][:options][:host])
  383. # realtest - test II, gmail with only pop3
  384. if !ENV['EMAILHELPER_MAILBOX_2']
  385. raise "Need EMAILHELPER_MAILBOX_2 as ENV variable like export EMAILHELPER_MAILBOX_2='hansb36621@gmail.com:somepass'"
  386. end
  387. mailbox_user = ENV['EMAILHELPER_MAILBOX_2'].split(':')[0]
  388. mailbox_password = ENV['EMAILHELPER_MAILBOX_2'].split(':')[1]
  389. result = EmailHelper::Probe.full(
  390. email: mailbox_user,
  391. password: mailbox_password,
  392. )
  393. assert_nil(result[:reason])
  394. assert_equal('ok', result[:result])
  395. assert_equal('pop.gmail.com', result[:setting][:inbound][:options][:host])
  396. assert_equal('smtp.gmail.com', result[:setting][:outbound][:options][:host])
  397. end
  398. test 'zz verify' do
  399. # realtest - test I, with imap
  400. if !ENV['EMAILHELPER_MAILBOX_1']
  401. raise "Need EMAILHELPER_MAILBOX_1 as ENV variable like export EMAILHELPER_MAILBOX_1='unittestemailhelper01@zammad.com:somepass'"
  402. end
  403. mailbox_user = ENV['EMAILHELPER_MAILBOX_1'].split(':')[0]
  404. mailbox_password = ENV['EMAILHELPER_MAILBOX_1'].split(':')[1]
  405. result = EmailHelper::Verify.email(
  406. inbound: {
  407. adapter: 'imap',
  408. options: {
  409. host: 'mx2.zammad.com',
  410. port: 993,
  411. ssl: true,
  412. user: mailbox_user,
  413. password: mailbox_password,
  414. },
  415. },
  416. outbound: {
  417. adapter: 'smtp',
  418. options: {
  419. host: 'mx2.zammad.com',
  420. port: 587,
  421. user: mailbox_user,
  422. password: mailbox_password,
  423. },
  424. },
  425. sender: mailbox_user,
  426. )
  427. assert_equal('ok', result[:result])
  428. # realtest - test II, gmail with pop3
  429. if !ENV['EMAILHELPER_MAILBOX_2']
  430. raise "Need EMAILHELPER_MAILBOX_2 as ENV variable like export EMAILHELPER_MAILBOX_2='hansb36621@gmail.com:somepass'"
  431. end
  432. mailbox_user = ENV['EMAILHELPER_MAILBOX_2'].split(':')[0]
  433. mailbox_password = ENV['EMAILHELPER_MAILBOX_2'].split(':')[1]
  434. EmailHelper.parse_email(mailbox_user)
  435. result = EmailHelper::Verify.email(
  436. inbound: {
  437. adapter: 'pop3',
  438. options: {
  439. host: 'pop.gmail.com',
  440. port: 995,
  441. ssl: true,
  442. user: mailbox_user,
  443. password: mailbox_password,
  444. },
  445. },
  446. outbound: {
  447. adapter: 'smtp',
  448. options: {
  449. host: 'smtp.gmail.com',
  450. port: 25,
  451. start_tls: true,
  452. user: mailbox_user,
  453. password: mailbox_password,
  454. },
  455. },
  456. sender: mailbox_user,
  457. )
  458. assert_equal('ok', result[:result])
  459. end
  460. end