simplenews.test 97 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488
  1. <?php
  2. /**
  3. * @file
  4. * Simplenews test functions.
  5. *
  6. * @ingroup simplenews
  7. */
  8. class SimplenewsTestCase extends DrupalWebTestCase {
  9. public function setUp($modules = array()) {
  10. $modules = array_merge(array('taxonomy', 'simplenews'), $modules);
  11. parent::setUp($modules);
  12. //$this->simplenews_admin_user = $this->drupalCreateUser(array('administer newsletters', 'administer simplenews settings', 'administer simplenews subscriptions'));
  13. //$this->sender_user = $this->drupalCreateUser(array('create simplenews content', 'edit own simplenews content', 'send newsletter'));
  14. variable_set('site_mail', 'user@example.com');
  15. }
  16. /**
  17. * Set anonymous user permission to subscribe.
  18. *
  19. * @param boolean $enabled
  20. * Allow anonymous subscribing.
  21. */
  22. function setAnonymousUserSubscription($enabled) {
  23. if ($enabled) {
  24. db_insert('role_permission')
  25. ->fields(array('rid', 'permission'), array(DRUPAL_ANONYMOUS_RID, 'subscribe to newsletters'))
  26. ->execute();
  27. }
  28. }
  29. /**
  30. * Set authenticated user permission to subscribe.
  31. *
  32. * @param boolean $enabled
  33. * Allow authenticated subscribing.
  34. */
  35. function setAuthenticatedUserSubscription($enabled) {
  36. if ($enabled) {
  37. db_insert('role_permission')
  38. ->fields(array('rid', 'permission'), array(DRUPAL_AUTHENTICATED_RID, 'subscribe to newsletters'))
  39. ->execute();
  40. }
  41. }
  42. /**
  43. * Generates a random email address.
  44. *
  45. * @todo: Make this function redundant by modification of Simplenews.
  46. * Email addresses are case sensitive, simplenews system should handle with
  47. * this correctly.
  48. */
  49. function randomEmail($number = 4, $prefix = 'simpletest_', $domain = 'example.com') {
  50. return strtolower($this->randomName($number, $prefix) . '@' . $domain);
  51. }
  52. /**
  53. * Select randomly one of the available newsletters.
  54. *
  55. * @return newsletter tid.
  56. */
  57. function getRandomNewsletter() {
  58. if ($taxonomies = taxonomy_get_tree(variable_get('simplenews_vid', ''))) {
  59. $tids = array();
  60. foreach ($taxonomies as $newsletter) {
  61. $tids[] = $newsletter->tid;
  62. }
  63. $key = array_rand($tids);
  64. return $tids[$key];
  65. }
  66. return 0;
  67. }
  68. /**
  69. * Enable newsletter subscription block.
  70. *
  71. * @param integer $tid
  72. * newsletter term id
  73. * @param array $settings
  74. * ['message'] = Block message
  75. * ['form'] = '1': Subscription form; '0': Link to form
  76. * ['link to previous'] = {1, 0} Display link to previous issues
  77. * ['previous issues'] = {1, 0} Display previous issues
  78. * ['issue count'] = {1, 2, 3, ...}Number of issues to display
  79. * ['rss feed'] = {1, 0} Display RSS-feed icon
  80. */
  81. function setupSubscriptionBlock($tid, $settings = array()) {
  82. $bid = db_select('block')
  83. ->fields('block', array('bid'))
  84. ->condition('module', 'simplenews')
  85. ->condition('delta', $tid)
  86. ->execute();
  87. // Check to see if the box was created by checking that it's in the database..
  88. $this->assertNotNull($bid, t('Block found in database'));
  89. // Enable the block in the left side bar.
  90. //@todo: replace this by BlockTestCase::moveBlockToRegion in D7
  91. $block['module'] = 'simplenews';
  92. $block['delta'] = $tid;
  93. $edit['blocks[' . $block['module'] . '_' . $block['delta'] . '][region]'] = 'sidebar_first';
  94. $this->drupalPost('admin/structure/block', $edit, t('Save blocks'));
  95. // Set block parameters
  96. $edit = array();
  97. if (isset($settings['message'])) {
  98. $edit['simplenews_block_m_' . $tid] = $settings['message'];
  99. }
  100. if (isset($settings['form'])) {
  101. $edit['simplenews_block_f_' . $tid] = $settings['form'];
  102. }
  103. if (isset($settings['link to previous'])) {
  104. $edit['simplenews_block_l_' . $tid] = $settings['link to previous'];
  105. }
  106. if (isset($settings['previous issues'])) {
  107. $edit['simplenews_block_i_status_' . $tid] = $settings['previous issues'];
  108. }
  109. if (isset($settings['issue count'])) {
  110. $edit['simplenews_block_i_' . $tid] = $settings['issue count'];
  111. // @todo check the count
  112. }
  113. if (isset($settings['rss feed'])) {
  114. $edit['simplenews_block_r_' . $tid] = $settings['rss feed'];
  115. }
  116. // Simplify confirmation form submission by hiding the subscribe block on
  117. // that page. Same for the newsletter/subscriptions page.
  118. $edit['pages'] = "newsletter/confirm/*\nnewsletter/subscriptions";
  119. $this->drupalPost('admin/structure/block/manage/simplenews/' . $tid . '/configure', $edit, t('Save block'));
  120. $this->assertText('The block configuration has been saved.', 'The newsletter block configuration has been saved.');
  121. }
  122. function setUpSubscribers($count = 100, $tid = 1) {
  123. // Subscribe users.
  124. $this->subscribers = array();
  125. for ($i = 0; $i < $count; $i++) {
  126. $mail = $this->randomEmail();
  127. $this->subscribers[$mail] = $mail;
  128. }
  129. $this->drupalGet('admin/people/simplenews');
  130. $this->clickLink(t('Mass subscribe'));
  131. $edit = array(
  132. 'emails' => implode(',', $this->subscribers),
  133. // @todo: Don't hardcode the default tid.
  134. 'newsletters[' . $tid . ']' => TRUE,
  135. );
  136. $this->drupalPost(NULL, $edit, t('Subscribe'));
  137. }
  138. }
  139. class SimplenewsSubscribeTestCase extends SimplenewsTestCase {
  140. /**
  141. * Implement getInfo().
  142. */
  143. function getInfo() {
  144. return array(
  145. 'name' => t('Subscribe and unsubscribe users'),
  146. 'description' => t('(un)subscription of anonymous and authenticated users. Subscription via block, subscription page and account page'),
  147. 'group' => t('Simplenews'),
  148. );
  149. }
  150. /**
  151. * Subscribe to multiple newsletters at the same time.
  152. */
  153. function testSubscribeMultiple() {
  154. $admin_user = $this->drupalCreateUser(array('administer blocks', 'administer content types', 'administer nodes', 'access administration pages', 'administer permissions', 'administer newsletters'));
  155. $this->drupalLogin($admin_user);
  156. $this->setAnonymousUserSubscription(TRUE);
  157. $this->drupalGet('admin/config/services/simplenews');
  158. for ($i = 0; $i < 5; $i++) {
  159. $this->clickLink(t('Add newsletter category'));
  160. $edit = array(
  161. 'name' => $this->randomName(),
  162. 'description' => $this->randomString(20),
  163. 'opt_inout' => 'double',
  164. );
  165. $this->drupalPost(NULL, $edit, t('Save'));
  166. }
  167. drupal_static_reset('simplenews_categories_load_multiple');
  168. $categories = simplenews_categories_load_multiple();
  169. $this->drupalLogout();
  170. $enable = array_rand($categories, 3);
  171. $mail = $this->randomEmail(8, 'testmail');
  172. $edit = array(
  173. 'mail' => $mail,
  174. );
  175. foreach ($enable as $tid) {
  176. $edit['newsletters[' . $tid . ']'] = TRUE;
  177. }
  178. $this->drupalPost('newsletter/subscriptions', $edit, t('Subscribe'));
  179. $this->assertText(t('You will receive a confirmation e-mail shortly containing further instructions on how to complete your subscription.'), t('Subscription confirmation e-mail sent.'));
  180. $mails = $this->drupalGetMails();
  181. $body = $mails[0]['body'];
  182. // Verify listed changes.
  183. foreach ($categories as $tid => $category) {
  184. $pos = strpos($body, t('Subscribe to @name', array('@name' => $category->name)));
  185. if (in_array($tid, $enable)) {
  186. $this->assertTrue($pos);
  187. }
  188. else {
  189. $this->assertFalse($pos);
  190. }
  191. }
  192. $pattern = '@newsletter/confirm/combined/[0-9,a-f]+t0@';
  193. $found = preg_match($pattern, $body, $match);
  194. $confirm_url = $match[0];
  195. $this->assertTrue($found, t('Confirmation URL found: @url', array('@url' => $confirm_url)));
  196. $this->drupalGet($confirm_url);
  197. $this->assertRaw(t('Are you sure you want to confirm the following subscription changes for %user?', array('%user' => $mail)), t('Subscription confirmation found.'));
  198. // Verify listed changes.
  199. foreach ($categories as $tid => $category) {
  200. if (in_array($tid, $enable)) {
  201. $this->assertText(t('Subscribe to @name', array('@name' => $category->name)));
  202. }
  203. else {
  204. $this->assertNoText(t('Subscribe to @name', array('@name' => $category->name)));
  205. }
  206. }
  207. $this->drupalPost($confirm_url, NULL, t('Confirm'));
  208. $this->assertRaw(t('Subscription changes confirmed for %user.', array('%user' => $mail)), t('Anonymous subscriber added to newsletter'));
  209. // Verify subscription changes.
  210. foreach ($categories as $tid => $category) {
  211. $is_subscribed = simplenews_user_is_subscribed($mail, $tid);
  212. if (in_array($tid, $enable)) {
  213. $this->assertTrue($is_subscribed);
  214. }
  215. else {
  216. $this->assertFalse($is_subscribed);
  217. }
  218. }
  219. // Go to the manage page and submit without changes.
  220. $subscriber = simplenews_subscriber_load_by_mail($mail);
  221. $hash = simplenews_generate_hash($subscriber->mail, $subscriber->snid, $tid);
  222. $this->drupalPost('newsletter/subscriptions/' . $hash, array(), t('Update'));
  223. $mails = $this->drupalGetMails();
  224. $body = $mails[1]['body'];
  225. $this->assertTrue(strpos($body, 'No confirmation necessary'));
  226. $pattern = '@newsletter/confirm/combined/[0-9,a-f]+t0@';
  227. $found = preg_match($pattern, $body, $match);
  228. $this->assertFalse($found, t('No confirmation link in unchanged confirm mail.'));
  229. // Unsubscribe from two of the three enabled newsletters.
  230. $disable = array_rand(array_flip($enable), 2);
  231. $edit = array(
  232. 'mail' => $mail,
  233. );
  234. foreach ($disable as $tid) {
  235. $edit['newsletters[' . $tid . ']'] = TRUE;
  236. }
  237. $this->drupalPost('newsletter/subscriptions', $edit, t('Unsubscribe'));
  238. $this->assertText(t('You will receive a confirmation e-mail shortly containing further instructions on how to cancel your subscription.'), t('Subscription confirmation e-mail sent.'));
  239. $mails = $this->drupalGetMails();
  240. $body = $mails[2]['body'];
  241. // Verify listed changes.
  242. foreach ($categories as $tid => $category) {
  243. $pos = strpos($body, t('Unsubscribe from @name', array('@name' => $category->name)));
  244. if (in_array($tid, $disable)) {
  245. $this->assertTrue($pos);
  246. }
  247. else {
  248. $this->assertFalse($pos);
  249. }
  250. }
  251. $pattern = '@newsletter/confirm/combined/[0-9,a-f]+t0@';
  252. $found = preg_match($pattern, $body, $match);
  253. $confirm_url = $match[0];
  254. $this->assertTrue($found, t('Confirmation URL found: @url', array('@url' => $confirm_url)));
  255. $this->drupalGet($confirm_url);
  256. $this->assertRaw(t('Are you sure you want to confirm the following subscription changes for %user?', array('%user' => $mail)), t('Subscription confirmation found.'));
  257. // Verify listed changes.
  258. foreach ($categories as $tid => $category) {
  259. if (in_array($tid, $disable)) {
  260. $this->assertText(t('Unsubscribe from @name', array('@name' => $category->name)));
  261. }
  262. else {
  263. $this->assertNoText(t('Unsubscribe from @name', array('@name' => $category->name)));
  264. }
  265. }
  266. $this->drupalPost($confirm_url, NULL, t('Confirm'));
  267. $this->assertRaw(t('Subscription changes confirmed for %user.', array('%user' => $mail)), t('Anonymous subscriber added to newsletter'));
  268. // Verify subscription changes.
  269. drupal_static_reset('simplenews_user_is_subscribed');
  270. $still_enabled = array_diff($enable, $disable);
  271. foreach ($categories as $tid => $category) {
  272. $is_subscribed = simplenews_user_is_subscribed($mail, $tid);
  273. if (in_array($tid, $still_enabled)) {
  274. $this->assertTrue($is_subscribed);
  275. }
  276. else {
  277. $this->assertFalse($is_subscribed);
  278. }
  279. }
  280. // Make sure that a single change results in a non-multi confirmation mail.
  281. $tid = reset($disable);
  282. $edit = array(
  283. 'mail' => $mail,
  284. 'newsletters[' . $tid . ']' => TRUE,
  285. );
  286. $this->drupalPost('newsletter/subscriptions', $edit, t('Subscribe'));
  287. $mails = $this->drupalGetMails();
  288. $body = $mails[3]['body'];
  289. $pattern = '@newsletter/confirm/add/[0-9,a-f]+t[0-9]+@';
  290. $found= preg_match($pattern, $body, $match);
  291. $confirm_url = $match[0];
  292. $this->assertTrue($found, t('Single add confirmation URL found: @url', array('@url' => $confirm_url)));
  293. // Change behavior to always use combined mails.
  294. variable_set('simplenews_use_combined', 'always');
  295. $edit = array(
  296. 'mail' => $mail,
  297. 'newsletters[' . $tid . ']' => TRUE,
  298. );
  299. $this->drupalPost('newsletter/subscriptions', $edit, t('Subscribe'));
  300. $mails = $this->drupalGetMails();
  301. $body = $mails[4]['body'];
  302. $pattern = '@newsletter/confirm/combined/[0-9,a-f]+t0@';
  303. $found= preg_match($pattern, $body, $match);
  304. $confirm_url = $match[0];
  305. $this->assertTrue($found, t('Multi confirmation URL found: @url', array('@url' => $confirm_url)));
  306. // Change behavior to never, should send two separate mails.
  307. variable_set('simplenews_use_combined', 'never');
  308. $edit = array(
  309. 'mail' => $mail,
  310. );
  311. foreach ($disable as $tid) {
  312. $edit['newsletters[' . $tid . ']'] = TRUE;
  313. }
  314. $this->drupalPost('newsletter/subscriptions', $edit, t('Subscribe'));
  315. $this->assertText(t('You will receive a confirmation e-mail shortly containing further instructions on how to complete your subscription.'), t('Subscription confirmation e-mail sent.'));
  316. $mails = $this->drupalGetMails();
  317. foreach (array(5, 6) as $id) {
  318. $body = $mails[$id]['body'];
  319. $pattern = '@newsletter/confirm/add/[0-9,a-f]+t[0-9]+@';
  320. $found= preg_match($pattern, $body, $match);
  321. $confirm_url = $match[0];
  322. $this->assertTrue($found, t('Single add confirmation URL found: @url', array('@url' => $confirm_url)));
  323. }
  324. }
  325. /**
  326. * testSubscribeAnonymous
  327. *
  328. * Steps performed:
  329. * 0. Preparation
  330. * 1. Subscribe anonymous via block
  331. * 2. Subscribe anonymous via subscription page
  332. * 3. Subscribe anonymous via multi block
  333. */
  334. function testSubscribeAnonymous() {
  335. // 0. Preparation
  336. // Login admin
  337. // Set permission for anonymous to subscribe
  338. // Enable newsletter block
  339. // Logout admin
  340. $admin_user = $this->drupalCreateUser(array('administer blocks', 'administer content types', 'administer nodes', 'access administration pages', 'administer permissions'));
  341. $this->drupalLogin($admin_user);
  342. $this->setAnonymousUserSubscription(TRUE);
  343. // Setup subscription block with subscription form.
  344. $block_settings = array(
  345. 'message' => $this->randomName(4),
  346. 'form' => '1',
  347. 'link to previous' => FALSE,
  348. 'previous issues' => FALSE,
  349. 'rss feed' => TRUE,
  350. );
  351. $tid = $this->getRandomNewsletter();
  352. $this->setupSubscriptionBlock($tid, $block_settings);
  353. $this->drupalLogout();
  354. //file_put_contents('output.html', $this->drupalGetContent());
  355. // 1. Subscribe anonymous via block
  356. // Subscribe + submit
  357. // Assert confirmation message
  358. // Assert outgoing email
  359. //
  360. // Confirm using mail link
  361. // Confirm using mail link
  362. // Assert confirmation message
  363. $mail = $this->randomEmail(8, 'testmail');
  364. $edit = array(
  365. 'mail' => $mail,
  366. );
  367. $this->drupalPost(NULL, $edit, t('Subscribe'));
  368. $this->assertText(t('You will receive a confirmation e-mail shortly containing further instructions on how to complete your subscription.'), t('Subscription confirmation e-mail sent.'));
  369. $subscriber = simplenews_subscriber_load_by_mail($mail);
  370. $subscription = db_query('SELECT * FROM {simplenews_subscription} WHERE snid = :snid AND tid = :tid', array(':snid' => $subscriber->snid, ':tid' => $tid))->fetchObject();
  371. $this->assertEqual(SIMPLENEWS_SUBSCRIPTION_STATUS_UNCONFIRMED, $subscription->status, t('Subscription is unconfirmed'));
  372. $mails = $this->drupalGetMails();
  373. $body = $mails[0]['body'];
  374. $pattern = '@newsletter/confirm/add/[0-9,a-f]+t[0-9]+@';
  375. preg_match($pattern, $body, $match);
  376. $found= preg_match($pattern, $body, $match);
  377. $confirm_url = $match[0];
  378. $this->assertTrue($found, t('Confirmation URL found: @url', array('@url' => $confirm_url)));
  379. $this->drupalGet($confirm_url);
  380. $newsletter = taxonomy_term_load($tid);
  381. $this->assertRaw(t('Are you sure you want to add %user to the %newsletter mailing list?', array('%user' => $mail, '%newsletter' => $newsletter->name)), t('Subscription confirmation found.'));
  382. $this->drupalPost(NULL, array(), t('Subscribe'));
  383. $this->assertRaw(t('%user was added to the %newsletter mailing list.', array('%user' => $mail, '%newsletter' => $newsletter->name)), t('Anonymous subscriber added to newsletter'));
  384. // Test that it is possible to register with a mail address that is already
  385. // a subscriber.
  386. variable_set('user_register', 1);
  387. variable_set('user_email_verification', FALSE);
  388. $edit = array(
  389. 'name' => $this->randomName(),
  390. 'mail' => $mail,
  391. 'pass[pass1]' => $pass = $this->randomName(),
  392. 'pass[pass2]' => $pass,
  393. );
  394. $this->drupalPost('user/register', $edit, t('Create new account'));
  395. // Verify confirmation messages.
  396. $this->assertText(t('Registration successful. You are now logged in.'));
  397. // Verify that the subscriber has been updated and references to the correct
  398. // user.
  399. $subscriber = simplenews_subscriber_load_by_mail($mail);
  400. $account = user_load_by_mail($mail);
  401. $this->assertEqual($subscriber->uid, $account->uid);
  402. $this->assertEqual($account->name, $edit['name']);
  403. $this->drupalLogout();
  404. // 2. Subscribe anonymous via subscription page
  405. // Subscribe + submit
  406. // Assert confirmation message
  407. // Assert outgoing email
  408. //
  409. // Confirm using mail link
  410. // Confirm using mail link
  411. // Assert confirmation message
  412. $mail = $this->randomEmail(8, 'testmail');
  413. $edit = array(
  414. "newsletters[$tid]" => '1',
  415. 'mail' => $mail,
  416. );
  417. $this->drupalPost('newsletter/subscriptions', $edit, t('Subscribe'));
  418. $this->assertText(t('You will receive a confirmation e-mail shortly containing further instructions on how to complete your subscription.'), t('Subscription confirmation e-mail sent.'));
  419. $mails = $this->drupalGetMails();
  420. $body = $mails[2]['body'];
  421. $pattern = '@newsletter/confirm/add/[0-9,a-f]+t[0-9]+@';
  422. preg_match($pattern, $body, $match);
  423. $found= preg_match($pattern, $body, $match);
  424. $confirm_url = $match[0];
  425. $this->assertTrue($found, t('Confirmation URL found: @url', array('@url' => $confirm_url)));
  426. $this->drupalGet($confirm_url);
  427. $newsletter = taxonomy_term_load($tid);
  428. $this->assertRaw(t('Are you sure you want to add %user to the %newsletter mailing list?', array('%user' => $mail, '%newsletter' => $newsletter->name)), t('Subscription confirmation found.'));
  429. $this->drupalPost($confirm_url, NULL, t('Subscribe'));
  430. $this->assertRaw(t('%user was added to the %newsletter mailing list.', array('%user' => $mail, '%newsletter' => $newsletter->name)), t('Anonymous subscriber added to newsletter'));
  431. // 3. Subscribe anonymous via multi block
  432. $this->drupalLogin($admin_user);
  433. // Enable the multi-sign up block.
  434. $this->setupSubscriptionBlock(0);
  435. // Disable the category block.
  436. $edit = array(
  437. 'blocks[simplenews_' . $tid . '][region]' => -1,
  438. );
  439. $this->drupalPost(NULL, $edit, t('Save blocks'));
  440. $this->drupalLogout();
  441. // Try to submit multi-signup form without selecting a category.
  442. $mail = $this->randomEmail(8, 'testmail');
  443. $edit = array(
  444. 'mail' => $mail,
  445. );
  446. $this->drupalPost(NULL, $edit, t('Subscribe'));
  447. $this->assertText(t('You must select at least one newsletter.'));
  448. // Now fill out the form and try again. The e-mail should still be listed.
  449. $edit = array(
  450. 'newsletters[' . $tid . ']' => TRUE,
  451. );
  452. $this->drupalPost(NULL, $edit, t('Subscribe'));
  453. $this->assertText(t('You will receive a confirmation e-mail shortly containing further instructions on how to complete your subscription.'));
  454. $mails = $this->drupalGetMails();
  455. $body = $mails[3]['body'];
  456. $pattern = '@newsletter/confirm/add/[0-9,a-f]+t[0-9]+@';
  457. preg_match($pattern, $body, $match);
  458. $found= preg_match($pattern, $body, $match);
  459. $confirm_url = $match[0];
  460. $this->assertTrue($found, t('Confirmation URL found: @url', array('@url' => $confirm_url)));
  461. $this->drupalGet($confirm_url);
  462. $newsletter = taxonomy_term_load($tid);
  463. $this->assertRaw(t('Are you sure you want to add %user to the %newsletter mailing list?', array('%user' => $mail, '%newsletter' => $newsletter->name)), t('Subscription confirmation found.'));
  464. $this->drupalPost($confirm_url, NULL, t('Subscribe'));
  465. $this->assertRaw(t('%user was added to the %newsletter mailing list.', array('%user' => $mail, '%newsletter' => $newsletter->name)), t('Anonymous subscriber added to newsletter'));
  466. // Try to subscribe again, this should not re-set the status to unconfirmed.
  467. $edit = array(
  468. 'mail' => $mail,
  469. 'newsletters[' . $tid . ']' => TRUE,
  470. );
  471. $this->drupalPost(NULL, $edit, t('Subscribe'));
  472. $this->assertText(t('You will receive a confirmation e-mail shortly containing further instructions on how to complete your subscription.'));
  473. $subscriber = simplenews_subscriber_load_by_mail($mail);
  474. $this->assertEqual(SIMPLENEWS_SUBSCRIPTION_STATUS_SUBSCRIBED, $subscriber->newsletter_subscription[$tid]->status);
  475. // Now the same with the newsletter/subscriptions page.
  476. $mail = $this->randomEmail(8, 'testmail');
  477. $edit = array(
  478. 'mail' => $mail,
  479. );
  480. $this->drupalPost('newsletter/subscriptions', $edit, t('Subscribe'));
  481. $this->assertText(t('You must select at least one newsletter.'));
  482. // Now fill out the form and try again.
  483. $edit = array(
  484. 'newsletters[' . $tid . ']' => TRUE,
  485. );
  486. $this->drupalPost(NULL, $edit, t('Subscribe'));
  487. $this->assertText(t('You will receive a confirmation e-mail shortly containing further instructions on how to complete your subscription.'));
  488. $mails = $this->drupalGetMails();
  489. $body = $mails[5]['body'];
  490. $pattern = '@newsletter/confirm/add/[0-9,a-f]+t[0-9]+@';
  491. $found = preg_match($pattern, $body, $match);
  492. $confirm_url = $match[0];
  493. $this->assertTrue($found, t('Confirmation URL found: @url', array('@url' => $confirm_url)));
  494. $this->drupalGet($confirm_url);
  495. $newsletter = taxonomy_term_load($tid);
  496. $this->assertRaw(t('Are you sure you want to add %user to the %newsletter mailing list?', array('%user' => $mail, '%newsletter' => $newsletter->name)), t('Subscription confirmation found.'));
  497. $this->drupalPost($confirm_url, NULL, t('Subscribe'));
  498. $this->assertRaw(t('%user was added to the %newsletter mailing list.', array('%user' => $mail, '%newsletter' => $newsletter->name)), t('Anonymous subscriber added to newsletter'));
  499. // Test unsubscribe on newsletter/subscriptions page.
  500. $edit = array(
  501. 'mail' => $mail,
  502. );
  503. $this->drupalPost('newsletter/subscriptions', $edit, t('Unsubscribe'));
  504. $this->assertText(t('You must select at least one newsletter.'));
  505. // Now fill out the form and try again.
  506. $edit = array(
  507. 'newsletters[' . $tid . ']' => TRUE,
  508. );
  509. $this->drupalPost(NULL, $edit, t('Unsubscribe'));
  510. $this->assertText(t('You will receive a confirmation e-mail shortly containing further instructions on how to cancel your subscription.'));
  511. $mails = $this->drupalGetMails();
  512. $body = $mails[6]['body'];
  513. $this->assertTrue(strpos($body, t('We have received a request to remove the @mail', array('@mail' => $mail))) === 0);
  514. $pattern = '@newsletter/confirm/remove/[0-9,a-f]+t[0-9]+@';
  515. $found = preg_match($pattern, $body, $match);
  516. $confirm_url = $match[0];
  517. $this->assertTrue($found, t('Confirmation URL found: @url', array('@url' => $confirm_url)));
  518. $this->drupalGet($confirm_url);
  519. $newsletter = taxonomy_term_load($tid);
  520. $this->assertRaw(t('Are you sure you want to remove %user from the %newsletter mailing list?', array('%user' => $mail, '%newsletter' => $newsletter->name)), t('Subscription confirmation found.'));
  521. $this->drupalPost($confirm_url, NULL, t('Unsubscribe'));
  522. $this->assertRaw(t('%user was unsubscribed from the %newsletter mailing list.', array('%user' => $mail, '%newsletter' => $newsletter->name)), t('Anonymous subscriber remved from newsletter'));
  523. // Visit the newsletter/subscriptions page with the hash.
  524. $subscriber = simplenews_subscriber_load_by_mail($mail);
  525. $hash = simplenews_generate_hash($subscriber->mail, $subscriber->snid, $tid);
  526. $this->drupalGet('newsletter/subscriptions/' . $hash);
  527. $this->assertText(t('Subscriptions for @mail', array('@mail' => $mail)));
  528. $edit = array(
  529. 'newsletters[' . $tid . ']' => TRUE,
  530. );
  531. $this->drupalPost(NULL, $edit, t('Update'));
  532. // Make sure the user is not yet subscribed.
  533. $subscriber = simplenews_subscriber_load_by_mail($mail);
  534. $this->assertTrue(empty($subscriber->tids));
  535. $this->assertEqual(SIMPLENEWS_SUBSCRIPTION_STATUS_UNCONFIRMED, $subscriber->newsletter_subscription[$tid]->status);
  536. $mails = $this->drupalGetMails();
  537. $body = $mails[7]['body'];
  538. $pattern = '@newsletter/confirm/add/[0-9,a-f]+t[0-9]+@';
  539. $found = preg_match($pattern, $body, $match);
  540. $confirm_url = $match[0];
  541. $this->assertTrue($found, t('Confirmation URL found: @url', array('@url' => $confirm_url)));
  542. $this->drupalGet($confirm_url);
  543. $newsletter = taxonomy_term_load($tid);
  544. $this->assertRaw(t('Are you sure you want to add %user to the %newsletter mailing list?', array('%user' => $mail, '%newsletter' => $newsletter->name)), t('Subscription confirmation found.'));
  545. $this->drupalPost($confirm_url, NULL, t('Subscribe'));
  546. $this->assertRaw(t('%user was added to the %newsletter mailing list.', array('%user' => $mail, '%newsletter' => $newsletter->name)), t('Anonymous subscriber added to newsletter'));
  547. // Make sure the subscription is confirmed now.
  548. $subscriber = simplenews_subscriber_load_by_mail($mail);
  549. $this->assertTrue(isset($subscriber->tids[$tid]));
  550. $this->assertEqual(SIMPLENEWS_SUBSCRIPTION_STATUS_SUBSCRIBED, $subscriber->newsletter_subscription[$tid]->status);
  551. // Attemt to fetch the page using an invalid hash format.
  552. $this->drupalGet('newsletter/subscriptions/' . strrev($hash));
  553. $this->assertResponse(404);
  554. // Attemt to fetch the page using a wrong hash but correct format.
  555. $this->drupalGet('newsletter/subscriptions/' . simplenews_generate_hash($subscriber->mail . 'a', $subscriber->snid, $tid));
  556. $this->assertResponse(404);
  557. }
  558. /**
  559. * Test anonymous subscription with single opt in.
  560. *
  561. * Steps performed:
  562. * 0. Preparation
  563. * 1. Subscribe anonymous via block
  564. */
  565. function testSubscribeAnonymousSingle() {
  566. // 0. Preparation
  567. // Login admin
  568. // Create single opt in newsletter.
  569. // Set permission for anonymous to subscribe
  570. // Enable newsletter block
  571. // Logout admin
  572. $admin_user = $this->drupalCreateUser(array('administer blocks', 'administer content types', 'administer nodes', 'access administration pages', 'administer permissions', 'administer newsletters'));
  573. $this->drupalLogin($admin_user);
  574. $this->setAnonymousUserSubscription(TRUE);
  575. // Setup subscription block with subscription form.
  576. $block_settings = array(
  577. 'message' => $this->randomName(4),
  578. 'form' => '1',
  579. 'link to previous' => FALSE,
  580. 'previous issues' => FALSE,
  581. 'rss feed' => TRUE,
  582. );
  583. $this->drupalGet('admin/config/services/simplenews');
  584. $this->clickLink(t('Add newsletter category'));
  585. $edit = array(
  586. 'name' => $this->randomName(),
  587. 'description' => $this->randomString(20),
  588. 'opt_inout' => 'single',
  589. );
  590. $this->drupalPost(NULL, $edit, t('Save'));
  591. // @todo: Don't hardcode this.
  592. $tid = 2;
  593. $this->setupSubscriptionBlock($tid, $block_settings);
  594. $this->drupalLogout();
  595. // 1. Subscribe anonymous via block
  596. // Subscribe + submit
  597. // Assert confirmation message
  598. // Verify subscription state.
  599. $mail = $this->randomEmail(8, 'testmail');
  600. $edit = array(
  601. 'mail' => $mail,
  602. );
  603. $this->drupalPost(NULL, $edit, t('Subscribe'));
  604. $this->assertText(t('You have been subscribed.'), t('Anonymous subscriber added to newsletter'));
  605. $subscriber = simplenews_subscriber_load_by_mail($mail);
  606. $this->assertEqual(SIMPLENEWS_SUBSCRIPTION_STATUS_SUBSCRIBED, $subscriber->newsletter_subscription[$tid]->status);
  607. // Unsubscribe again.
  608. $edit = array(
  609. 'mail' => $mail,
  610. 'newsletters[' . $tid . ']' => TRUE,
  611. );
  612. $this->drupalPost('newsletter/subscriptions', $edit, t('Unsubscribe'));
  613. $subscriber = simplenews_subscriber_load_by_mail($mail);
  614. $this->assertEqual(SIMPLENEWS_SUBSCRIPTION_STATUS_UNSUBSCRIBED, $subscriber->newsletter_subscription[$tid]->status);
  615. }
  616. /**
  617. * testSubscribeAuthenticated
  618. *
  619. * Steps performed:
  620. * 0. Preparation
  621. * 1. Subscribe authenticated via block
  622. * 2. Unsubscribe authenticated via subscription page
  623. * 3. Subscribe authenticated via subscription page
  624. * 4. Unsubscribe authenticated via account page
  625. * 5. Subscribe authenticated via account page
  626. * 6. Subscribe authenticated via multi block
  627. */
  628. function testSubscribeAuthenticated() {
  629. // 0. Preparation
  630. // Login admin
  631. // Set permission for anonymous to subscribe
  632. // Enable newsletter block
  633. // Logout admin
  634. // Login Subscriber
  635. $admin_user = $this->drupalCreateUser(array('administer blocks', 'administer content types', 'administer nodes', 'access administration pages', 'administer permissions'));
  636. $this->drupalLogin($admin_user);
  637. $this->setAnonymousUserSubscription(TRUE);
  638. // Setup subscription block with subscription form.
  639. $block_settings = array(
  640. 'message' => $this->randomName(4),
  641. 'form' => '1',
  642. 'link to previous' => FALSE,
  643. 'previous issues' => FALSE,
  644. 'rss feed' => TRUE,
  645. );
  646. $tid = $this->getRandomNewsletter();
  647. $this->setupSubscriptionBlock($tid, $block_settings);
  648. $this->drupalLogout();
  649. $subscriber_user = $this->drupalCreateUser(array('subscribe to newsletters'));
  650. $this->drupalLogin($subscriber_user);
  651. // 1. Subscribe authenticated via block
  652. // Subscribe + submit
  653. // Assert confirmation message
  654. $this->drupalPost('', NULL, t('Subscribe'));
  655. $this->assertText(t('You have been subscribed.'), t('Authenticated user subscribed using the subscription block.'));
  656. // 2. Unsubscribe authenticated via subscription page
  657. // Unsubscribe + submit
  658. // Assert confirmation message
  659. $edit = array(
  660. "newsletters[$tid]" => 0,
  661. );
  662. $this->drupalPost('newsletter/subscriptions', $edit, t('Update'));
  663. $this->assertRaw(t('The newsletter subscriptions for %mail have been updated.', array('%mail' => $subscriber_user->mail)), t('Authenticated user unsubscribed on the subscriptions page.'));
  664. // 3. Subscribe authenticated via subscription page
  665. // Subscribe + submit
  666. // Assert confirmation message
  667. $edit = array(
  668. "newsletters[$tid]" => '1',
  669. );
  670. $this->drupalPost('newsletter/subscriptions', $edit, t('Update'));
  671. $this->assertRaw(t('The newsletter subscriptions for %mail have been updated.', array('%mail' => $subscriber_user->mail)), t('Authenticated user subscribed on the subscriptions page.'));
  672. // 4. Unsubscribe authenticated via account page
  673. // Unsubscribe + submit
  674. // Assert confirmation message
  675. $edit = array(
  676. "newsletters[$tid]" => FALSE,
  677. );
  678. $url = 'user/' . $subscriber_user->uid . '/edit/simplenews';
  679. $this->drupalPost($url, $edit, t('Save'));
  680. $this->assertRaw(t('The changes have been saved.', array('%mail' => $subscriber_user->mail)), t('Authenticated user unsubscribed on the account page.'));
  681. $subscriber = simplenews_subscriber_load_by_mail($subscriber_user->mail);
  682. $subscription = db_query('SELECT * FROM {simplenews_subscription} WHERE snid = :snid AND tid = :tid', array(':snid' => $subscriber->snid, ':tid' => $tid))->fetchObject();
  683. $this->assertEqual(SIMPLENEWS_SUBSCRIPTION_STATUS_UNSUBSCRIBED, $subscription->status, t('Subscription is unsubscribed'));
  684. // 5. Subscribe authenticated via account page
  685. // Subscribe + submit
  686. // Assert confirmation message
  687. $edit = array(
  688. "newsletters[$tid]" => '1',
  689. );
  690. $url = 'user/' . $subscriber_user->uid . '/edit/simplenews';
  691. $this->drupalPost($url, $edit, t('Save'));
  692. $this->assertRaw(t('The changes have been saved.', array('%mail' => $subscriber_user->mail)), t('Authenticated user unsubscribed on the account page.'));
  693. // Subscribe authenticated via multi block
  694. $this->drupalLogin($admin_user);
  695. // Enable the multi-sign up block.
  696. $this->setupSubscriptionBlock(0);
  697. // Disable the category block.
  698. $edit = array(
  699. 'blocks[simplenews_' . $tid . '][region]' => -1,
  700. );
  701. $this->drupalPost(NULL, $edit, t('Save blocks'));
  702. $this->drupalLogout();
  703. // Try to submit multi-signup form without selecting a category.
  704. $subscriber_user2 = $this->drupalCreateUser(array('subscribe to newsletters'));
  705. $this->drupalLogin($subscriber_user2);
  706. // Check that the user has only access to his own subscriptions page.
  707. $this->drupalGet('user/' . $subscriber_user->uid . '/edit/simplenews');
  708. $this->assertResponse(403);
  709. $this->drupalGet('user/' . $subscriber_user2->uid . '/edit/simplenews');
  710. $this->assertResponse(200);
  711. $this->assertNoField('mail');
  712. $this->drupalPost(NULL, array(), t('Update'));
  713. $this->assertText(t('The newsletter subscriptions for @mail have been updated.', array('@mail' => $subscriber_user2->mail)));
  714. // Nothing should have happened.
  715. $this->assertNoFieldChecked('edit-newsletters-' . $tid);
  716. // Now fill out the form and try again.
  717. $edit = array(
  718. 'newsletters[' . $tid . ']' => TRUE,
  719. );
  720. $this->drupalPost(NULL, $edit, t('Update'));
  721. $this->assertText(t('The newsletter subscriptions for @mail have been updated.', array('@mail' => $subscriber_user2->mail)));
  722. $this->assertFieldChecked('edit-newsletters-' . $tid);
  723. // Unsubscribe.
  724. $edit = array(
  725. 'newsletters[' . $tid . ']' => FALSE,
  726. );
  727. $this->drupalPost(NULL, $edit, t('Update'));
  728. $this->assertText(t('The newsletter subscriptions for @mail have been updated.', array('@mail' => $subscriber_user2->mail)));
  729. $this->assertNoFieldChecked('edit-newsletters-' . $tid);
  730. // And now the same for the newsletter/subscriptions page.
  731. $subscriber_user3 = $this->drupalCreateUser(array('subscribe to newsletters'));
  732. $this->drupalLogin($subscriber_user3);
  733. $this->assertNoField('mail');
  734. $this->drupalPost('newsletter/subscriptions', array(), t('Update'));
  735. $this->assertText(t('The newsletter subscriptions for @mail have been updated.', array('@mail' => $subscriber_user3->mail)));
  736. // Nothing should have happened.
  737. $this->assertNoFieldChecked('edit-newsletters-' . $tid);
  738. // Now fill out the form and try again.
  739. $edit = array(
  740. 'newsletters[' . $tid . ']' => TRUE,
  741. );
  742. $this->drupalPost('newsletter/subscriptions', $edit, t('Update'));
  743. $this->assertText(t('The newsletter subscriptions for @mail have been updated.', array('@mail' => $subscriber_user3->mail)));
  744. $this->assertFieldChecked('edit-newsletters-' . $tid);
  745. // Unsubscribe.
  746. $edit = array(
  747. 'newsletters[' . $tid . ']' => FALSE,
  748. );
  749. $this->drupalPost('newsletter/subscriptions', $edit, t('Update'));
  750. $this->assertText(t('The newsletter subscriptions for @mail have been updated.', array('@mail' => $subscriber_user3->mail)));
  751. $this->assertNoFieldChecked('edit-newsletters-' . $tid);
  752. }
  753. }
  754. /**
  755. * @todo:
  756. * Newsletter node create, send draft, send final
  757. */
  758. class SimpleNewsAdministrationTestCase extends SimplenewsTestCase {
  759. /**
  760. * Implement getInfo().
  761. */
  762. function getInfo() {
  763. return array(
  764. 'name' => t('Simplenews administration'),
  765. 'description' => t('Managing of newsletter categories and content types.'),
  766. 'group' => t('Simplenews'),
  767. );
  768. }
  769. /**
  770. * Test various combinations of newsletter category settings.
  771. */
  772. function testCategorySettings() {
  773. // Allow registration of new accounts without approval.
  774. variable_set('user_register', 1);
  775. variable_set('user_email_verification', FALSE);
  776. // Allow authenticated users to subscribe.
  777. $this->setAuthenticatedUserSubscription(TRUE);
  778. $admin_user = $this->drupalCreateUser(array('administer blocks', 'administer content types', 'administer nodes', 'access administration pages', 'administer permissions', 'administer newsletters', 'administer simplenews subscriptions'));
  779. $this->drupalLogin($admin_user);
  780. $this->drupalGet('admin/config/services/simplenews');
  781. // Create a category for all possible setting combinations.
  782. $new_account = array('none', 'off', 'on', 'silent');
  783. $opt_inout = array('hidden', 'single', 'double');
  784. $block = array('block' => TRUE, 'noblock' => FALSE);
  785. foreach ($new_account as $new_account_setting) {
  786. foreach ($opt_inout as $opt_inout_setting) {
  787. foreach ($block as $name => $value) {
  788. $this->clickLink(t('Add newsletter category'));
  789. $edit = array(
  790. 'name' => implode('-', array($new_account_setting, $opt_inout_setting, $name)),
  791. 'description' => $this->randomString(20),
  792. 'new_account' => $new_account_setting,
  793. 'opt_inout' => $opt_inout_setting,
  794. 'block' => $value,
  795. 'priority' => rand(0, 5),
  796. 'receipt' => rand(0, 1) ? TRUE : FALSE,
  797. 'from_name' => $this->randomName(),
  798. 'from_address' => $this->randomEmail(),
  799. );
  800. $this->drupalPost(NULL, $edit, t('Save'));
  801. }
  802. }
  803. }
  804. drupal_static_reset('simplenews_categories_load_multiple');
  805. $categories = simplenews_categories_load_multiple();
  806. // Check block settings.
  807. $this->drupalGet('admin/structure/block');
  808. //blocks[simplenews_42][region]
  809. foreach ($categories as $category) {
  810. if (strpos($category->name, '-') === FALSE) {
  811. continue;
  812. }
  813. list($new_account_setting, $opt_inout_setting, $block) = explode('-', $category->name);
  814. if ($block == 'block' && $opt_inout_setting != 'hidden') {
  815. $this->assertField('blocks[simplenews_' . $category->tid . '][region]', t('Block is displayed for category'));
  816. }
  817. else {
  818. $this->assertNoField('blocks[simplenews_' . $category->tid . '][region]', t('Block is not displayed for category'));
  819. }
  820. }
  821. // Check registration form.
  822. $this->drupalLogout();
  823. $this->drupalGet('user/register');
  824. foreach ($categories as $category) {
  825. if (strpos($category->name, '-') === FALSE) {
  826. continue;
  827. }
  828. // Explicitly subscribe to the off-double-block newsletter.
  829. if ($category->name == 'off-double-block') {
  830. $off_double_block_tid = $category->tid;
  831. }
  832. list($new_account_setting, $opt_inout_setting, $block) = explode('-', $category->name);
  833. if ($category->new_account == 'on' && $category->opt_inout != 'hidden') {
  834. $this->assertFieldChecked('edit-newsletters-' . $category->tid);
  835. }
  836. else if ($category->new_account == 'off' && $category->opt_inout != 'hidden') {
  837. $this->assertNoFieldChecked('edit-newsletters-' . $category->tid);
  838. }
  839. else {
  840. $this->assertNoField('newsletters[' . $category->tid . ']', t('Hidden or silent newsletter category is not shown.'));
  841. }
  842. }
  843. // Register a new user through the form.
  844. $edit = array(
  845. 'name' => $this->randomName(),
  846. 'mail' => $this->randomEmail(),
  847. 'pass[pass1]' => $pass = $this->randomName(),
  848. 'pass[pass2]' => $pass,
  849. 'newsletters[' . $off_double_block_tid . ']' => $off_double_block_tid,
  850. );
  851. $this->drupalPost(NULL, $edit, t('Create new account'));
  852. // Verify confirmation messages.
  853. $this->assertText(t('Registration successful. You are now logged in.'));
  854. foreach ($categories as $category) {
  855. // Check confirmation message for all on and non-hidden newsletters and
  856. // the one that was explicitly selected.
  857. if (($category->new_account == 'on' && $category->opt_inout != 'hidden') || $category->name == 'off-double-block') {
  858. $this->assertText(t('You have been subscribed to @name.', array('@name' => $category->name)));
  859. }
  860. else {
  861. // All other newsletters must not show a message, e.g. those which were
  862. // subscribed silently.
  863. $this->assertNoText(t('You have been subscribed to @name.', array('@name' => $category->name)));
  864. }
  865. }
  866. // Log out again.
  867. $this->drupalLogout();
  868. // Get the user id and do a login through the drupalLogin() function.
  869. $uid = db_query('SELECT uid FROM {users} WHERE name = :name', array(':name' => $edit['name']))->fetchField();
  870. $user = user_load($uid);
  871. // Set the password so that the login works.
  872. $user->pass_raw = $edit['pass[pass1]'];
  873. // Verify newsletter subscription pages.
  874. $this->drupalLogin($user);
  875. foreach (array('newsletter/subscriptions', 'user/' . $user->uid . '/edit/simplenews') as $path) {
  876. $this->drupalGet($path);
  877. foreach ($categories as $category) {
  878. if (strpos($category->name, '-') === FALSE) {
  879. continue;
  880. }
  881. list($new_account_setting, $opt_inout_setting, $block) = explode('-', $category->name);
  882. if ($category->opt_inout == 'hidden') {
  883. $this->assertNoField('newsletters[' . $category->tid . ']', t('Hidden newsletter category is not shown.'));
  884. }
  885. else if ($category->new_account == 'on' || $category->name == 'off-double-block' || $category->new_account == 'silent') {
  886. // All on, silent and the explicitly selected category should be checked.
  887. $this->assertFieldChecked('edit-newsletters-' . $category->tid);
  888. }
  889. else {
  890. $this->assertNoFieldChecked('edit-newsletters-' . $category->tid);
  891. }
  892. }
  893. }
  894. // Unsubscribe from a newsletter category.
  895. $edit = array(
  896. 'newsletters[' . $off_double_block_tid . ']' => FALSE,
  897. );
  898. $this->drupalPost(NULL, $edit, t('Save'));
  899. $this->assertNoFieldChecked('edit-newsletters-' . $off_double_block_tid);
  900. // Get a category which has the block enabled.
  901. foreach ($categories as $category) {
  902. // The default category is missing the from mail address. Use another one.
  903. if ($category->block == TRUE && $category->tid != 1) {
  904. $edit_category = $category;
  905. break;
  906. }
  907. }
  908. $this->drupalLogin($admin_user);
  909. $this->drupalGet('admin/config/services/simplenews/categories/' . $edit_category->tid . '/edit');
  910. $this->assertFieldByName('name', $edit_category->name, t('Category name is displayed when editing'));
  911. $this->assertFieldByName('description', $edit_category->description, t('Category description is displayed when editing'));
  912. $edit = array('block' => FALSE);
  913. $this->drupalPost(NULL, $edit, t('Save'));
  914. $updated_category = simplenews_category_load($edit_category->tid);
  915. $this->assertEqual(0, $updated_category->block, t('Block for category disabled'));
  916. $this->drupalGet('admin/structure/block');
  917. $this->assertNoText($edit_category->name, t('Category block was removed'));
  918. }
  919. /**
  920. * Test newsletter subscription management.
  921. *
  922. * Steps performed:
  923. *
  924. */
  925. function testSubscriptionManagement() {
  926. $admin_user = $this->drupalCreateUser(array('administer newsletters', 'administer simplenews settings', 'administer simplenews subscriptions', 'administer taxonomy'));
  927. $this->drupalLogin($admin_user);
  928. // Create a second category.
  929. $edit = array(
  930. 'name' => $name = $this->randomName(),
  931. );
  932. $this->drupalPost('admin/config/services/simplenews/add', $edit, t('Save'));
  933. // Add a number of users to each category separately and then add another
  934. // bunch to both.
  935. $subscribers = array();
  936. drupal_static_reset('simplenews_categories_load_multiple');
  937. $categories = simplenews_categories_load_multiple();
  938. $groups = array();
  939. foreach (array_keys($categories) as $tid) {
  940. $groups[$tid] = array($tid);
  941. }
  942. $groups['all'] = array_keys($groups);
  943. $subscribers_flat = array();
  944. foreach ($groups as $key => $group) {
  945. for ($i = 0; $i < 5; $i++) {
  946. $mail = $this->randomEmail();
  947. $subscribers[$key][$mail] = $mail;
  948. $subscribers_flat[$mail] = $mail;
  949. }
  950. }
  951. // Create a user and assign him one of the mail addresses of the all group.
  952. $user = $this->drupalCreateUser(array('subscribe to newsletters'));
  953. // Make sure that user_save() does not update the user object, as it will
  954. // override the pass_raw property which we'll need to log this user in
  955. // later on.
  956. $user_mail = current($subscribers['all']);
  957. user_save(clone $user, array('mail' => $user_mail));
  958. $delimiters = array(',', ' ', "\n");
  959. $this->drupalGet('admin/people/simplenews');
  960. $i = 0;
  961. foreach ($groups as $key => $group) {
  962. $this->clickLink(t('Mass subscribe'));
  963. $edit = array(
  964. // Implode with a different, supported delimiter for each group.
  965. 'emails' => implode($delimiters[$i++], $subscribers[$key]),
  966. );
  967. foreach ($group as $tid) {
  968. $edit['newsletters[' . $tid . ']'] = TRUE;
  969. }
  970. $this->drupalPost(NULL, $edit, t('Subscribe'));
  971. }
  972. // The user to which the mail was assigned should be listed too.
  973. $this->assertText($user->name);
  974. // Verify that all addresses are displayed in the table.
  975. $mail_addresses = $this->xpath('//tr/td[2]');
  976. $this->assertEqual(15, count($mail_addresses));
  977. foreach ($mail_addresses as $mail_address) {
  978. $mail_address = (string)$mail_address;
  979. $this->assertTrue(isset($subscribers_flat[$mail_address]));
  980. unset($subscribers_flat[$mail_address]);
  981. }
  982. // All entries of the array should be removed by now.
  983. $this->assertTrue(empty($subscribers_flat));
  984. // Limit list to subscribers of the first category only.
  985. reset($groups);
  986. $first = key($groups);
  987. // Build a flat list of the subscribers of this list.
  988. $subscribers_flat = array_merge($subscribers[$first], $subscribers['all']);
  989. $edit = array(
  990. 'list' => 'tid-' . $first,
  991. );
  992. $this->drupalPost(NULL, $edit, t('Filter'));
  993. // Verify that all addresses are displayed in the table.
  994. $mail_addresses = $this->xpath('//tr/td[2]');
  995. $this->assertEqual(10, count($mail_addresses));
  996. foreach ($mail_addresses as $mail_address) {
  997. $mail_address = (string)$mail_address;
  998. $this->assertTrue(isset($subscribers_flat[$mail_address]));
  999. unset($subscribers_flat[$mail_address]);
  1000. }
  1001. // All entries of the array should be removed by now.
  1002. $this->assertTrue(empty($subscribers_flat));
  1003. // Filter a single mail address, the one assigned to a user.
  1004. $edit = array(
  1005. 'email' => substr(current($subscribers['all']), 0, 4)
  1006. );
  1007. $this->drupalPost(NULL, $edit, t('Filter'));
  1008. $rows = $this->xpath('//tbody/tr');
  1009. $this->assertEqual(1, count($rows));
  1010. $this->assertEqual(current($subscribers['all']), (string)$rows[0]->td[1]);
  1011. $this->assertEqual($user->name, (string)$rows[0]->td[2]->a);
  1012. // Reset the filter.
  1013. $this->drupalPost(NULL, array(), t('Reset'));
  1014. // Test mass-unsubscribe, unsubscribe one from the first group and one from
  1015. // the all group, but only from the first newsletter category.
  1016. $first_mail = array_rand($subscribers[$first]);
  1017. $all_mail = array_rand($subscribers['all']);
  1018. unset($subscribers[$first][$first_mail]);
  1019. $edit = array(
  1020. 'emails' => $first_mail . ', ' . $all_mail,
  1021. 'newsletters[' . $first . ']' => TRUE,
  1022. );
  1023. $this->clickLink(t('Mass unsubscribe'));
  1024. $this->drupalPost(NULL, $edit, t('Unsubscribe'));
  1025. // The all mail is still displayed because it's still subscribed to the
  1026. // second category. Reload the page to get rid of the confirmation
  1027. // message.
  1028. $this->drupalGet('admin/people/simplenews');
  1029. $this->assertNoText($first_mail);
  1030. $this->assertText($all_mail);
  1031. // Limit to first category, the all mail shouldn't be shown anymore.
  1032. $edit = array(
  1033. 'list' => 'tid-' . $first,
  1034. );
  1035. $this->drupalPost(NULL, $edit, t('Filter'));
  1036. $this->assertNoText($first_mail);
  1037. $this->assertNoText($all_mail);
  1038. // Check exporting.
  1039. $this->clickLink(t('Export'));
  1040. $this->drupalPost(NULL, array('newsletters[' . $first . ']' => TRUE), t('Export'));
  1041. $export_field = $this->xpath($this->constructFieldXpath('name', 'emails'));
  1042. $exported_mails = (string)$export_field[0];
  1043. foreach ($subscribers[$first] as $mail) {
  1044. $this->assertTrue(strpos($exported_mails, $mail) !== FALSE, t('Mail address exported correctly.'));
  1045. }
  1046. foreach ($subscribers['all'] as $mail) {
  1047. if ($mail != $all_mail) {
  1048. $this->assertTrue(strpos($exported_mails, $mail) !== FALSE, t('Mail address exported correctly.'));
  1049. }
  1050. else {
  1051. $this->assertFALSE(strpos($exported_mails, $mail) !== FALSE, t('Unsubscribed mail address not exported.'));
  1052. }
  1053. }
  1054. // Only export unsubscribed mail addresses.
  1055. $edit = array(
  1056. 'subscribed[subscribed]' => FALSE,
  1057. 'subscribed[unsubscribed]' => TRUE,
  1058. 'newsletters[' . $first . ']' => TRUE,
  1059. );
  1060. $this->drupalPost(NULL, $edit, t('Export'));
  1061. $export_field = $this->xpath($this->constructFieldXpath('name', 'emails'));
  1062. $exported_mails = (string)$export_field[0];
  1063. $exported_mails = explode(', ', $exported_mails);
  1064. $this->assertEqual(2, count($exported_mails));
  1065. $this->assertTrue(in_array($all_mail, $exported_mails));
  1066. $this->assertTrue(in_array($first_mail, $exported_mails));
  1067. // Make sure the user is subscribed to the first tid.
  1068. simplenews_subscribe_user($user_mail, $first, FALSE);
  1069. $before_count = simplenews_count_subscriptions($first);
  1070. // Block the user.
  1071. user_save(clone $user, array('status' => 0));
  1072. $this->drupalGet('admin/people/simplenews');
  1073. // Verify updated subscriptions count.
  1074. drupal_static_reset('simplenews_count_subscriptions');
  1075. $after_count = simplenews_count_subscriptions($first);
  1076. $this->assertEqual($before_count - 1, $after_count, t('Blocked users are not counted in subscription count.'));
  1077. // Delete newsletter category.
  1078. $this->drupalPost('taxonomy/term/' . $first . '/edit', array(), t('Delete'));
  1079. $this->assertText(t('This taxonomy term is part of simplenews newsletter category @name. Deleting this term will delete the newsletter category and all subscriptions to category @name. This action cannot be undone.', array('@name' => $categories[$first]->name)), t('Confirmation message displayed.'));
  1080. $this->drupalPost(NULL, array(), t('Delete'));
  1081. $this->assertText(t('All subscriptions to newsletter @newsletter have been deleted.', array('@newsletter' => $categories[$first]->name)));
  1082. // Verify that all related data has been deleted.
  1083. $this->assertFalse(simplenews_category_load($first));
  1084. $this->assertFalse(db_query('SELECT tid FROM {simplenews_category} WHERE tid = :tid', array(':tid' => $first))->fetchField());
  1085. $this->assertFalse(db_query('SELECT * FROM {block} WHERE module = :module AND delta = :tid', array(':module' => 'simplenews', ':tid' => $first))->fetchField());
  1086. // Verify that all subscriptions of that category have been removed.
  1087. $this->drupalGet('admin/people/simplenews');
  1088. foreach ($subscribers[$first] as $mail) {
  1089. $this->assertNoText($mail);
  1090. }
  1091. // Reset list and click on the first subscriber.
  1092. $this->drupalPost(NULL, array(), t('Reset'));
  1093. $this->clickLink(t('edit'));
  1094. // Get the subscriber id from the path.
  1095. $this->assertTrue(preg_match('|admin/people/simplenews/users/edit/(\d+)$|', $this->getUrl(), $matches), 'Subscriber found');
  1096. $subscriber = simplenews_subscriber_load($matches[1]);
  1097. $this->assertText(t('Subscriptions for @mail', array('@mail' => $subscriber->mail)));
  1098. $this->assertFieldChecked('edit-activated--2');
  1099. // Disable account.
  1100. $edit = array(
  1101. 'activated' => FALSE,
  1102. );
  1103. $this->drupalPost(NULL, $edit, t('Update'));
  1104. drupal_static_reset('simplenews_subscriber_load_multiple');
  1105. drupal_static_reset('simplenews_user_is_subscribed');
  1106. $this->assertFalse(simplenews_user_is_subscribed($subscriber->mail, $this->getRandomNewsletter(), t('Subscriber is not active')));
  1107. // Re-enable account.
  1108. $this->drupalGet('admin/people/simplenews/users/edit/' . $subscriber->snid);
  1109. $this->assertText(t('Subscriptions for @mail', array('@mail' => $subscriber->mail)));
  1110. $this->assertNoFieldChecked('edit-activated--2');
  1111. $edit = array(
  1112. 'activated' => TRUE,
  1113. );
  1114. $this->drupalPost(NULL, $edit, t('Update'));
  1115. drupal_static_reset('simplenews_subscriber_load_multiple');
  1116. drupal_static_reset('simplenews_user_is_subscribed');
  1117. $this->assertTrue(simplenews_user_is_subscribed($subscriber->mail, $this->getRandomNewsletter(), t('Subscriber is active again.')));
  1118. // Remove the category.
  1119. $this->drupalGet('admin/people/simplenews/users/edit/' . $subscriber->snid);
  1120. $this->assertText(t('Subscriptions for @mail', array('@mail' => $subscriber->mail)));
  1121. $edit = array(
  1122. 'newsletters[' . reset($subscriber->tids) . ']' => FALSE,
  1123. );
  1124. $this->drupalPost(NULL, $edit, t('Update'));
  1125. drupal_static_reset('simplenews_subscriber_load_multiple');
  1126. drupal_static_reset('simplenews_user_is_subscribed');
  1127. $this->assertFalse(simplenews_user_is_subscribed($subscriber->mail, reset($subscriber->tids), t('Subscriber not subscribed anymore.')));
  1128. // @todo Test Admin subscriber edit preferred language $subscription->language
  1129. }
  1130. /**
  1131. * Test content type configuration.
  1132. */
  1133. function testContentTypes() {
  1134. $admin_user = $this->drupalCreateUser(array('administer blocks', 'administer content types', 'administer nodes', 'access administration pages', 'administer permissions', 'administer newsletters', 'administer simplenews subscriptions', 'bypass node access', 'send newsletter'));
  1135. $this->drupalLogin($admin_user);
  1136. $this->drupalGet('admin/structure/types');
  1137. $this->clickLink(t('Add content type'));
  1138. $edit = array(
  1139. 'name' => $name = $this->randomName(),
  1140. 'type' => $type = strtolower($name),
  1141. 'simplenews_content_type' => TRUE,
  1142. );
  1143. $this->drupalPost(NULL, $edit, t('Save content type'));
  1144. // Verify that the newsletter settings are shown.
  1145. $this->drupalGet('node/add/' . $type);
  1146. $this->assertText(t('Newsletter category'));
  1147. // Create an issue.
  1148. $edit = array(
  1149. 'title' => $this->randomName(),
  1150. );
  1151. $this->drupalPost(NULL, $edit, ('Save'));
  1152. // Send newsletter.
  1153. $this->clickLink(t('Newsletter'));
  1154. $this->assertText(t('Send newsletter'));
  1155. $this->drupalPost(NULL, array(), t('Submit'));
  1156. $mails = $this->drupalGetMails();
  1157. $this->assertEqual('simplenews_test', $mails[0]['id']);
  1158. // @todo: Test with a custom test mail address.
  1159. $this->assertEqual('user@example.com', $mails[0]['to']);
  1160. $this->assertEqual(t('[Drupal newsletter] @title', array('@title' => $edit['title'])), $mails[0]['subject']);
  1161. // Update the content type, remove the simpletest checkbox.
  1162. $edit = array(
  1163. 'simplenews_content_type' => FALSE,
  1164. );
  1165. $this->drupalPost('admin/structure/types/manage/' . $type, $edit, t('Save content type'));
  1166. // Verify that the newsletter settings are still shown.
  1167. // Note: Previously the field got autoremoved. We leave it remaining due to potential data loss.
  1168. $this->drupalGet('node/add/' . $type);
  1169. $this->assertNoText(t('Replacement patterns'));
  1170. $this->assertText(t('Newsletter category'));
  1171. // @todo: Test node update/delete.
  1172. // Delete content type.
  1173. // @todo: Add assertions.
  1174. $this->drupalPost('admin/structure/types/manage/' . $type . '/delete', array(), t('Delete'));
  1175. }
  1176. }
  1177. /**
  1178. * Tests for I18N integration.
  1179. */
  1180. class SimpleNewsI18nTestCase extends SimplenewsTestCase {
  1181. /**
  1182. * Implementation of getInfo().
  1183. */
  1184. function getInfo() {
  1185. return array(
  1186. 'name' => t('Simplenews I18n'),
  1187. 'description' => t('Translation of newsletter categories'),
  1188. 'group' => t('Simplenews'),
  1189. 'dependencies' => array('i18n_taxonomy', 'variable'),
  1190. );
  1191. }
  1192. function setUp() {
  1193. parent::setUp(array('locale', 'i18n', 'variable', 'i18n_string', 'i18n_taxonomy', 'translation', 'i18n_translation'));
  1194. $this->admin_user = $this->drupalCreateUser(array('bypass node access', 'administer nodes', 'administer languages', 'administer content types', 'administer blocks', 'access administration pages', 'administer filters', 'administer taxonomy', 'translate interface', 'subscribe to newsletters', 'administer site configuration', 'translate content', 'administer simplenews subscriptions', 'send newsletter'));
  1195. $this->drupalLogin($this->admin_user);
  1196. $this->setUpLanguages();
  1197. }
  1198. /**
  1199. * Install a the specified language if it has not been already. Otherwise make sure that
  1200. * the language is enabled.
  1201. *
  1202. * Copied from Drupali18nTestCase::addLanguage().
  1203. *
  1204. * @param $language_code
  1205. * The language code the check.
  1206. */
  1207. function addLanguage($language_code) {
  1208. // Check to make sure that language has not already been installed.
  1209. $this->drupalGet('admin/config/regional/language');
  1210. if (strpos($this->drupalGetContent(), 'enabled[' . $language_code . ']') === FALSE) {
  1211. // Doesn't have language installed so add it.
  1212. $edit = array();
  1213. $edit['langcode'] = $language_code;
  1214. $this->drupalPost('admin/config/regional/language/add', $edit, t('Add language'));
  1215. // Make sure we are not using a stale list.
  1216. drupal_static_reset('language_list');
  1217. $languages = language_list('language');
  1218. $this->assertTrue(array_key_exists($language_code, $languages), t('Language was installed successfully.'));
  1219. if (array_key_exists($language_code, $languages)) {
  1220. $this->assertRaw(t('The language %language has been created and can now be used. More information is available on the <a href="@locale-help">help screen</a>.', array('%language' => $languages[$language_code]->name, '@locale-help' => url('admin/help/locale'))), t('Language has been created.'));
  1221. }
  1222. }
  1223. elseif ($this->xpath('//input[@type="checkbox" and @name=:name and @checked="checked"]', array(':name' => 'enabled[' . $language_code . ']'))) {
  1224. // It's installed and enabled. No need to do anything.
  1225. $this->assertTrue(true, 'Language [' . $language_code . '] already installed and enabled.');
  1226. }
  1227. else {
  1228. // It's installed but not enabled. Enable it.
  1229. $this->assertTrue(true, 'Language [' . $language_code . '] already installed.');
  1230. $this->drupalPost(NULL, array('enabled[' . $language_code . ']' => TRUE), t('Save configuration'));
  1231. $this->assertRaw(t('Configuration saved.'), t('Language successfully enabled.'));
  1232. }
  1233. }
  1234. function testCategoryTranslation() {
  1235. $this->drupalLogin($this->admin_user);
  1236. // Make Input Format "Filtered Text" translatable
  1237. $edit = array(
  1238. 'i18n_string_allowed_formats[filtered_html]' => 'filtered_html',
  1239. 'i18n_string_allowed_formats[plain_text]' => 'plain_text',
  1240. );
  1241. $this->drupalPost('admin/config/regional/i18n/strings', $edit, t('Save configuration'));
  1242. $vocabulary = taxonomy_vocabulary_load(variable_get('simplenews_vid', 0));
  1243. $vocabulary->i18n_mode = I18N_MODE_LOCALIZE;
  1244. taxonomy_vocabulary_save($vocabulary);
  1245. drupal_static_reset('i18n_taxonomy_vocabulary_mode');
  1246. // Refresh strings.
  1247. // @todo: simplenews_category_save() should probably take care of this.
  1248. // Currently done separately in simplenews_admin_category_form_submit()
  1249. // for the admin UI.
  1250. $tid = $this->getRandomNewsletter();
  1251. $term = taxonomy_term_load($tid);
  1252. taxonomy_term_save($term);
  1253. $tid = array_shift(simplenews_categories_load_multiple())->tid;
  1254. // Translate term to spanish.
  1255. list($textgroup, $context) = i18n_string_context(array('taxonomy', 'term', $tid, 'name'));
  1256. i18n_string_textgroup($textgroup)->update_translation($context, 'es', $es_name = $this->randomName());
  1257. list($textgroup, $context) = i18n_string_context(array('taxonomy', 'term', $tid, 'description'));
  1258. i18n_string_textgroup($textgroup)->update_translation($context, 'es', $es_description = $this->randomName());
  1259. // Visit newsletter selection page in english.
  1260. $this->drupalGet('user/' . $this->admin_user->uid . '/edit/simplenews');
  1261. $this->assertText(t('Drupal newsletter'));
  1262. // And now in spanish.
  1263. $this->drupalGet('es/user/' . $this->admin_user->uid . '/edit/simplenews');
  1264. $this->assertText($es_name, t('Category name is translated.'));
  1265. }
  1266. function testContentTranslation() {
  1267. // Sign up two users, one in english, another in spanish.
  1268. $english_mail = $this->randomEmail();
  1269. $spanish_mail = $this->randomEmail();
  1270. $tid = $this->getRandomNewsletter();
  1271. simplenews_subscribe_user($english_mail, $tid, FALSE, 'english', 'en');
  1272. simplenews_subscribe_user($spanish_mail, $tid, FALSE, 'spanish', 'es');
  1273. // Translate category.
  1274. $vocabulary = taxonomy_vocabulary_load(variable_get('simplenews_vid', 0));
  1275. $vocabulary->i18n_mode = I18N_MODE_LOCALIZE;
  1276. taxonomy_vocabulary_save($vocabulary);
  1277. drupal_static_reset('i18n_taxonomy_vocabulary_mode');
  1278. // Refresh strings.
  1279. // @todo: simplenews_category_save() should probably take care of this.
  1280. // Currently done separately in simplenews_admin_category_form_submit()
  1281. // for the admin UI.
  1282. $tid = $this->getRandomNewsletter();
  1283. $term = taxonomy_term_load($tid);
  1284. taxonomy_term_save($term);
  1285. // Translate term to spanish.
  1286. list($textgroup, $context) = i18n_string_context(array('taxonomy', 'term', $tid, 'name'));
  1287. i18n_string_textgroup($textgroup)->update_translation($context, 'es', $es_name = $this->randomName());
  1288. // Enable translation for newsletters.
  1289. $edit = array(
  1290. 'language_content_type' => TRANSLATION_ENABLED,
  1291. );
  1292. $this->drupalPost('admin/structure/types/manage/simplenews', $edit, t('Save content type'));
  1293. // Create a Newsletter including a translation.
  1294. $english = array(
  1295. 'title' => $this->randomName(),
  1296. 'language' => 'en',
  1297. 'body[und][0][value]' => 'Link to node: [node:url]',
  1298. );
  1299. $this->drupalPost('node/add/simplenews', $english, ('Save'));
  1300. $this->assertTrue(preg_match('|node/(\d+)$|', $this->getUrl(), $matches), 'Node created');
  1301. $english_node = node_load($matches[1]);
  1302. $this->clickLink(t('Translate'));
  1303. $this->clickLink(t('add translation'));
  1304. $spanish = array(
  1305. 'title' => $this->randomName(),
  1306. );
  1307. $this->drupalPost(NULL, $spanish, ('Save'));
  1308. $this->assertTrue(preg_match('|node/(\d+)$|', $this->getUrl(), $matches), 'Node created');
  1309. $spanish_node = node_load($matches[1]);
  1310. entity_get_controller('node')->resetCache();
  1311. $english_node = node_load($english_node->nid);
  1312. // Verify redirecation to source.
  1313. $this->clickLink(t('Newsletter'));
  1314. $this->assertText(t('This newsletter issue is part of a translation set. Sending this set is controlled from the translation source newsletter.'));
  1315. $this->clickLink(t('translation source newsletter'));
  1316. $this->assertText($english_node->title);
  1317. // Send newsletter.
  1318. $this->clickLink(t('Newsletter'));
  1319. $edit = array(
  1320. 'simplenews[send]' => SIMPLENEWS_COMMAND_SEND_NOW,
  1321. );
  1322. $this->drupalPost(NULL, $edit, t('Submit'));
  1323. simplenews_cron();
  1324. $this->assertEqual(2, count($this->drupalGetMails()));
  1325. $category = simplenews_category_load($this->getRandomNewsletter());
  1326. $languages = language_list();
  1327. foreach ($this->drupalGetMails() as $mail) {
  1328. if ($mail['to'] == $english_mail) {
  1329. $this->assertEqual('en', $mail['language']);
  1330. $this->assertEqual('[' . $category->name . '] ' . $english_node->title, $mail['subject']);
  1331. $node_url = url('node/' . $english_node->nid, array('language' => $languages['en'], 'absolute' => TRUE));
  1332. }
  1333. elseif ($mail['to'] == $spanish_mail) {
  1334. $this->assertEqual('es', $mail['language']);
  1335. $this->assertEqual('[' . $es_name . '] ' . $spanish_node->title, $mail['subject']);
  1336. $node_url = url('node/' . $spanish_node->nid, array('language' => $languages['es'], 'absolute' => TRUE));
  1337. }
  1338. else {
  1339. $this->fail(t('Mail not sent to expected recipient'));
  1340. }
  1341. // Verify that the link is in the correct language.
  1342. $this->assertTrue(strpos($mail['body'], $node_url) !== FALSE);
  1343. }
  1344. // Make sure the language of a node can be changed.
  1345. $english = array(
  1346. 'title' => $this->randomName(),
  1347. 'language' => 'en',
  1348. 'body[und][0][value]' => 'Link to node: [node:url]',
  1349. );
  1350. $this->drupalPost('node/add/simplenews', $english, ('Save'));
  1351. $this->clickLink(t('Edit'));
  1352. $edit = array(
  1353. 'language' => 'es',
  1354. );
  1355. $this->drupalPost(NULL, $edit, t('Save'));
  1356. }
  1357. /**
  1358. * Set up configuration for multiple languages.
  1359. *
  1360. * Copied from Drupali18nTestCase::setUpLanguages().
  1361. */
  1362. function setUpLanguages($admin_permissions = array()) {
  1363. // Add languages.
  1364. $this->default_language = 'en';
  1365. $this->secondary_language = 'es';
  1366. $this->addLanguage($this->default_language);
  1367. $this->addLanguage($this->secondary_language);
  1368. // Enable URL language detection and selection to make the language switcher
  1369. // block appear.
  1370. $edit = array('language[enabled][locale-url]' => TRUE);
  1371. $this->drupalPost('admin/config/regional/language/configure', $edit, t('Save settings'));
  1372. $this->assertRaw(t('Language negotiation configuration saved.'), t('URL language detection enabled.'));
  1373. $this->drupalGet('admin/config/regional/language/configure');
  1374. drupal_static_reset('locale_url_outbound_alter');
  1375. drupal_static_reset('language_list');
  1376. }
  1377. }
  1378. /**
  1379. * Upgrade test from 6.x-1.x
  1380. */
  1381. class SimpleNewsUpgradePath61TestCase extends UpgradePathTestCase {
  1382. public static function getInfo() {
  1383. return array(
  1384. 'name' => 'Simplenews 6.x-1.x upgrade path',
  1385. 'description' => 'Simplenews 6.x-1.x upgrade path tests.',
  1386. 'group' => 'Simplenews',
  1387. );
  1388. }
  1389. public function setUp() {
  1390. // Path to the database dump files.
  1391. $this->databaseDumpFiles = array(
  1392. drupal_get_path('module', 'simplenews') . '/tests/d6_simplenews_61.php',
  1393. );
  1394. parent::setUp();
  1395. }
  1396. /**
  1397. * Test a successful upgrade.
  1398. */
  1399. public function testSimplenewsUpgrade() {
  1400. // Delete everything except taxnomy and simplenews from system to
  1401. // prevent their update functions to be run.
  1402. $this->uninstallModulesExcept(array('taxonomy', 'simplenews'));
  1403. // Disable simplenews, the update hooks will be executed anyway.
  1404. db_update('system')
  1405. ->fields(array(
  1406. 'status' => 0,
  1407. ))
  1408. ->condition('name', 'simplenews')
  1409. ->execute();
  1410. $this->assertTrue($this->performUpgrade(), t('Upgraded successfully.'));
  1411. // Enable simplenews.
  1412. $edit = array(
  1413. 'modules[Mail][simplenews][enable]' => 1,
  1414. );
  1415. $this->drupalPost('admin/modules', $edit, t('Save configuration'));
  1416. $this->drupalGet('admin/config/services/simplenews');
  1417. $this->assertText('Drupal 6 newsletter');
  1418. $this->assertText('Test');
  1419. $this->drupalGet('admin/people/simplenews');
  1420. $this->assertText('another@example.org');
  1421. }
  1422. }
  1423. /**
  1424. * Upgrade test from 6.x-2.x
  1425. */
  1426. class SimpleNewsUpgradePath62TestCase extends UpgradePathTestCase {
  1427. public static function getInfo() {
  1428. return array(
  1429. 'name' => 'Simplenews 6.x-2.x upgrade path',
  1430. 'description' => 'Simplenews 6.x-2.x upgrade path tests.',
  1431. 'group' => 'Simplenews',
  1432. );
  1433. }
  1434. public function setUp() {
  1435. // Path to the database dump files.
  1436. $this->databaseDumpFiles = array(
  1437. drupal_get_path('module', 'simplenews') . '/tests/d6_simplenews_62.php',
  1438. );
  1439. parent::setUp();
  1440. }
  1441. /**
  1442. * Test a successful upgrade.
  1443. */
  1444. public function testSimplenewsUpgrade() {
  1445. // Delete everything except taxnomy and simplenews from system to
  1446. // prevent their update functions to be run.
  1447. $this->uninstallModulesExcept(array('taxonomy', 'simplenews'));
  1448. // Disable simplenews, the update hooks will be executed anyway.
  1449. db_update('system')
  1450. ->fields(array(
  1451. 'status' => 0,
  1452. ))
  1453. ->condition('name', 'simplenews')
  1454. ->execute();
  1455. $this->assertTrue($this->performUpgrade(), t('Upgraded successfully.'));
  1456. // Enable simplenews.
  1457. $edit = array(
  1458. 'modules[Mail][simplenews][enable]' => 1,
  1459. );
  1460. $this->drupalPost('admin/modules', $edit, t('Save configuration'));
  1461. $this->drupalGet('admin/config/services/simplenews');
  1462. $this->assertText('Drupal 6 newsletter');
  1463. $this->assertText('Test');
  1464. $this->drupalGet('admin/people/simplenews');
  1465. $this->assertText('another@example.org');
  1466. }
  1467. }
  1468. /**
  1469. * Test cases for creating and sending newsletters.
  1470. */
  1471. class SimplenewsSendTestCase extends SimplenewsTestCase {
  1472. /**
  1473. * Implementation of getInfo().
  1474. */
  1475. function getInfo() {
  1476. return array(
  1477. 'name' => t('Sending newsletters'),
  1478. 'description' => t('Creating and sending of newsletters, different send processes (with/without cron, send on publish)'),
  1479. 'group' => t('Simplenews'),
  1480. );
  1481. }
  1482. function setUp() {
  1483. parent::setUp();
  1484. $this->user = $this->drupalCreateUser(array('administer newsletters', 'send newsletter', 'administer nodes', 'administer simplenews subscriptions', 'create simplenews content', 'edit any simplenews content', 'view own unpublished content', 'delete any simplenews content'));
  1485. $this->drupalLogin($this->user);
  1486. // Subscribe a few users.
  1487. $this->setUpSubscribers(5);
  1488. }
  1489. /**
  1490. * Send a newsletter using cron.
  1491. */
  1492. function testSendNowNoCron() {
  1493. // Disable cron.
  1494. variable_set('simplenews_use_cron', FALSE);
  1495. // Verify that the newsletter settings are shown.
  1496. $this->drupalGet('node/add/simplenews');
  1497. $this->assertText(t('Newsletter category'));
  1498. $edit = array(
  1499. 'title' => $this->randomName(),
  1500. );
  1501. $this->drupalPost(NULL, $edit, ('Save'));
  1502. $this->assertTrue(preg_match('|node/(\d+)$|', $this->getUrl(), $matches), 'Node created');
  1503. $node = node_load($matches[1]);
  1504. $this->clickLink(t('Newsletter'));
  1505. $this->assertText(t('Send one test newsletter to the test address'));
  1506. $this->assertText(t('Send newsletter'));
  1507. $this->assertNoText(t('Send newsletter when published'), t('Send on publish is not shown for published nodes.'));
  1508. // Verify state.
  1509. $newsletter = simplenews_newsletter_load($node->nid);
  1510. $this->assertEqual(SIMPLENEWS_STATUS_SEND_NOT, $newsletter->status, t('Newsletter not sent yet.'));
  1511. // Send now.
  1512. $this->drupalPost(NULL, array('simplenews[send]' => SIMPLENEWS_COMMAND_SEND_NOW), t('Submit'));
  1513. // Verify state.
  1514. $newsletter = simplenews_newsletter_load($node->nid);
  1515. $this->assertEqual(SIMPLENEWS_STATUS_SEND_READY, $newsletter->status, t('Newsletter sending finished'));
  1516. // Verify mails.
  1517. $mails = $this->drupalGetMails();
  1518. $this->assertEqual(5, count($mails), t('All mails were sent.'));
  1519. foreach ($mails as $mail) {
  1520. $this->assertEqual($mail['subject'], '[Drupal newsletter] ' . $edit['title'], t('Mail has correct subject'));
  1521. $this->assertTrue(isset($this->subscribers[$mail['to']]), t('Found valid recipient'));
  1522. unset($this->subscribers[$mail['to']]);
  1523. }
  1524. $this->assertEqual(0, count($this->subscribers), t('all subscribers have been received a mail'));
  1525. }
  1526. /**
  1527. * Send a newsletter using cron.
  1528. */
  1529. function testSendMultipleNoCron() {
  1530. // Disable cron.
  1531. variable_set('simplenews_use_cron', FALSE);
  1532. // Verify that the newsletter settings are shown.
  1533. $nodes = array();
  1534. for ($i = 0; $i < 3; $i++) {
  1535. $this->drupalGet('node/add/simplenews');
  1536. $this->assertText(t('Newsletter category'));
  1537. $edit = array(
  1538. 'title' => $this->randomName(),
  1539. // The last newsletter shouldn't be published.
  1540. 'status' => $i != 2,
  1541. );
  1542. $this->drupalPost(NULL, $edit, ('Save'));
  1543. $this->assertTrue(preg_match('|node/(\d+)$|', $this->getUrl(), $matches), 'Node created');
  1544. $nodes[] = node_load($matches[1]);
  1545. // Verify state.
  1546. $newsletter = simplenews_newsletter_load($matches[1]);
  1547. $this->assertEqual(SIMPLENEWS_STATUS_SEND_NOT, $newsletter->status, t('Newsletter not sent yet.'));
  1548. }
  1549. // Send the first and last newsletter on the newsletter overview.
  1550. list ($first, $second, $unpublished) = $nodes;
  1551. $edit = array(
  1552. 'issues[' . $first->nid . ']' => $first->nid,
  1553. 'issues[' . $unpublished->nid . ']' => $unpublished->nid ,
  1554. 'operation' => 'activate',
  1555. );
  1556. $this->drupalPost('admin/content/simplenews', $edit, t('Update'));
  1557. $this->assertText(t('Sent the following newsletters: @title.', array('@title' => $first->title)));
  1558. $this->assertText(t('Newsletter @title is unpublished and will be sent on publish.', array('@title' => $unpublished->title)));
  1559. // Verify states.
  1560. $newsletter = simplenews_newsletter_load($first->nid);
  1561. $this->assertEqual(SIMPLENEWS_STATUS_SEND_READY, $newsletter->status, t('First Newsletter sending finished'));
  1562. $newsletter = simplenews_newsletter_load($second->nid);
  1563. $this->assertEqual(SIMPLENEWS_STATUS_SEND_NOT, $newsletter->status, t('Second Newsletter not sent'));
  1564. $newsletter = simplenews_newsletter_load($unpublished->nid);
  1565. $this->assertEqual(SIMPLENEWS_STATUS_SEND_PUBLISH, $newsletter->status, t('Newsletter set to send on publish'));
  1566. // Verify mails.
  1567. $mails = $this->drupalGetMails();
  1568. $this->assertEqual(5, count($mails), t('All mails were sent.'));
  1569. foreach ($mails as $mail) {
  1570. $this->assertEqual($mail['subject'], '[Drupal newsletter] ' . $first->title, t('Mail has correct subject'));
  1571. $this->assertTrue(isset($this->subscribers[$mail['to']]), t('Found valid recipient'));
  1572. unset($this->subscribers[$mail['to']]);
  1573. }
  1574. $this->assertEqual(0, count($this->subscribers), t('all subscribers have been received a mail'));
  1575. }
  1576. /**
  1577. * Send a newsletter using cron and a low throttle.
  1578. */
  1579. function testSendNowCronThrottle() {
  1580. variable_set('simplenews_throttle', 3);
  1581. // Verify that the newsletter settings are shown.
  1582. $this->drupalGet('node/add/simplenews');
  1583. $this->assertText(t('Newsletter category'));
  1584. $edit = array(
  1585. 'title' => $this->randomName(),
  1586. );
  1587. $this->drupalPost(NULL, $edit, ('Save'));
  1588. $this->assertTrue(preg_match('|node/(\d+)$|', $this->getUrl(), $matches), 'Node created');
  1589. $node = node_load($matches[1]);
  1590. $this->clickLink(t('Newsletter'));
  1591. $this->assertText(t('Send one test newsletter to the test address'));
  1592. $this->assertText(t('Send newsletter'));
  1593. $this->assertNoText(t('Send newsletter when published'), t('Send on publish is not shown for published nodes.'));
  1594. // Verify state.
  1595. $newsletter = simplenews_newsletter_load($node->nid);
  1596. $this->assertEqual(SIMPLENEWS_STATUS_SEND_NOT, $newsletter->status, t('Newsletter not sent yet.'));
  1597. // Send now.
  1598. $this->drupalPost(NULL, array('simplenews[send]' => SIMPLENEWS_COMMAND_SEND_NOW), t('Submit'));
  1599. // Verify state.
  1600. $newsletter = simplenews_newsletter_load($node->nid);
  1601. $this->assertEqual(SIMPLENEWS_STATUS_SEND_PENDING, $newsletter->status, t('Newsletter sending pending.'));
  1602. // Verify that no mails have been sent yet.
  1603. $mails = $this->drupalGetMails();
  1604. $this->assertEqual(0, count($mails), t('No mails were sent yet.'));
  1605. $spooled = db_query('SELECT COUNT(*) FROM {simplenews_mail_spool} WHERE nid = :nid', array(':nid' => $node->nid))->fetchField();
  1606. $this->assertEqual(5, $spooled, t('5 mails have been added to the mail spool'));
  1607. // Run cron for the first time.
  1608. simplenews_cron();
  1609. // Verify state.
  1610. $newsletter = simplenews_newsletter_load($node->nid);
  1611. $this->assertEqual(SIMPLENEWS_STATUS_SEND_PENDING, $newsletter->status, t('Newsletter sending pending.'));
  1612. $spooled = db_query('SELECT COUNT(*) FROM {simplenews_mail_spool} WHERE nid = :nid', array(':nid' => $node->nid))->fetchField();
  1613. $this->assertEqual(2, $spooled, t('2 mails remaining in spool.'));
  1614. // Run cron for the second time.
  1615. simplenews_cron();
  1616. // Verify state.
  1617. $newsletter = simplenews_newsletter_load($node->nid);
  1618. $this->assertEqual(SIMPLENEWS_STATUS_SEND_READY, $newsletter->status, t('Newsletter sending finished.'));
  1619. $spooled = db_query('SELECT COUNT(*) FROM {simplenews_mail_spool} WHERE nid = :nid', array(':nid' => $node->nid))->fetchField();
  1620. $this->assertEqual(0, $spooled, t('No mails remaining in spool.'));
  1621. // Verify mails.
  1622. $mails = $this->drupalGetMails();
  1623. $this->assertEqual(5, count($mails), t('All mails were sent.'));
  1624. foreach ($mails as $mail) {
  1625. $this->assertEqual($mail['subject'], '[Drupal newsletter] ' . $edit['title'], t('Mail has correct subject'));
  1626. $this->assertTrue(isset($this->subscribers[$mail['to']]), t('Found valid recipient'));
  1627. unset($this->subscribers[$mail['to']]);
  1628. }
  1629. $this->assertEqual(0, count($this->subscribers), t('all subscribers have been received a mail'));
  1630. }
  1631. /**
  1632. * Send a newsletter without using cron.
  1633. */
  1634. function testSendNowCron() {
  1635. // Verify that the newsletter settings are shown.
  1636. $this->drupalGet('node/add/simplenews');
  1637. $this->assertText(t('Newsletter category'));
  1638. $edit = array(
  1639. 'title' => $this->randomName(),
  1640. );
  1641. // Try preview first.
  1642. $this->drupalPost(NULL, $edit, t('Preview'));
  1643. // Then save.
  1644. $this->drupalPost(NULL, array(), t('Save'));
  1645. $this->assertTrue(preg_match('|node/(\d+)$|', $this->getUrl(), $matches), 'Node created');
  1646. $node = node_load($matches[1]);
  1647. $this->clickLink(t('Newsletter'));
  1648. $this->assertText(t('Send one test newsletter to the test address'));
  1649. $this->assertText(t('Send newsletter'));
  1650. $this->assertNoText(t('Send newsletter when published'), t('Send on publish is not shown for published nodes.'));
  1651. // Verify state.
  1652. $newsletter = simplenews_newsletter_load($node->nid);
  1653. $this->assertEqual(SIMPLENEWS_STATUS_SEND_NOT, $newsletter->status, t('Newsletter not sent yet.'));
  1654. // Send now.
  1655. $this->drupalPost(NULL, array('simplenews[send]' => SIMPLENEWS_COMMAND_SEND_NOW), t('Submit'));
  1656. // Verify state.
  1657. $newsletter = simplenews_newsletter_load($node->nid);
  1658. $this->assertEqual(SIMPLENEWS_STATUS_SEND_PENDING, $newsletter->status, t('Newsletter sending pending.'));
  1659. // Verify that no mails have been sent yet.
  1660. $mails = $this->drupalGetMails();
  1661. $this->assertEqual(0, count($mails), t('No mails were sent yet.'));
  1662. $spooled = db_query('SELECT COUNT(*) FROM {simplenews_mail_spool} WHERE nid = :nid', array(':nid' => $node->nid))->fetchField();
  1663. $this->assertEqual(5, $spooled, t('5 mails have been added to the mail spool'));
  1664. // Check warning message on node edit form.
  1665. $this->clickLink(t('Edit'));
  1666. $this->assertText(t('This newsletter issue is currently being sent. Any changes will be reflected in the e-mails which have not been sent yet.'));
  1667. // Run cron.
  1668. simplenews_cron();
  1669. // Verify state.
  1670. $newsletter = simplenews_newsletter_load($node->nid);
  1671. $this->assertEqual(SIMPLENEWS_STATUS_SEND_READY, $newsletter->status, t('Newsletter sending finished.'));
  1672. $spooled = db_query('SELECT COUNT(*) FROM {simplenews_mail_spool} WHERE nid = :nid', array(':nid' => $node->nid))->fetchField();
  1673. $this->assertEqual(0, $spooled, t('No mails remaining in spool.'));
  1674. // Verify mails.
  1675. $mails = $this->drupalGetMails();
  1676. $this->assertEqual(5, count($mails), t('All mails were sent.'));
  1677. foreach ($mails as $mail) {
  1678. $this->assertEqual($mail['subject'], '[Drupal newsletter] ' . $edit['title'], t('Mail has correct subject'));
  1679. $this->assertTrue(isset($this->subscribers[$mail['to']]), t('Found valid recipient'));
  1680. unset($this->subscribers[$mail['to']]);
  1681. }
  1682. $this->assertEqual(0, count($this->subscribers), t('all subscribers have been received a mail'));
  1683. }
  1684. /**
  1685. * Send a newsletter on publish without using cron.
  1686. */
  1687. function testSendPublishNoCron() {
  1688. // Disable cron.
  1689. variable_set('simplenews_use_cron', FALSE);
  1690. // Verify that the newsletter settings are shown.
  1691. $this->drupalGet('node/add/simplenews');
  1692. $this->assertText(t('Newsletter category'));
  1693. $edit = array(
  1694. 'title' => $this->randomName(),
  1695. 'status' => FALSE,
  1696. );
  1697. $this->drupalPost(NULL, $edit, ('Save'));
  1698. $this->assertTrue(preg_match('|node/(\d+)$|', $this->getUrl(), $matches), 'Node created');
  1699. $node = node_load($matches[1]);
  1700. $this->clickLink(t('Newsletter'));
  1701. $this->assertText(t('Send one test newsletter to the test address'));
  1702. $this->assertText(t('Send newsletter when published'), t('Send on publish is shown'));
  1703. // Verify state.
  1704. $newsletter = simplenews_newsletter_load($node->nid);
  1705. $this->assertEqual(SIMPLENEWS_STATUS_SEND_NOT, $newsletter->status, t('Newsletter not sent yet.'));
  1706. // Send now.
  1707. $this->drupalPost(NULL, array('simplenews[send]' => SIMPLENEWS_COMMAND_SEND_PUBLISH), t('Submit'));
  1708. // Verify state.
  1709. $newsletter = simplenews_newsletter_load($node->nid);
  1710. $this->assertEqual(SIMPLENEWS_STATUS_SEND_PUBLISH, $newsletter->status, t('Newsletter set up for sending on publish.'));
  1711. $this->clickLink(t('Edit'));
  1712. $update = array(
  1713. 'status' => TRUE,
  1714. );
  1715. $this->drupalPost(NULL, $update, t('Save'));
  1716. // Send on publish does not send immediately.
  1717. simplenews_mail_attempt_immediate_send(array(), FALSE);
  1718. // Verify state.
  1719. $newsletter = simplenews_newsletter_load($node->nid);
  1720. $this->assertEqual(SIMPLENEWS_STATUS_SEND_READY, $newsletter->status, t('Newsletter sending finished'));
  1721. // @todo test sent subscriber count.
  1722. // Verify mails.
  1723. $mails = $this->drupalGetMails();
  1724. $this->assertEqual(5, count($mails), t('All mails were sent.'));
  1725. foreach ($mails as $mail) {
  1726. $this->assertEqual($mail['subject'], '[Drupal newsletter] ' . $edit['title'], t('Mail has correct subject'));
  1727. $this->assertTrue(isset($this->subscribers[$mail['to']]), t('Found valid recipient'));
  1728. unset($this->subscribers[$mail['to']]);
  1729. }
  1730. $this->assertEqual(0, count($this->subscribers), t('all subscribers have been received a mail'));
  1731. }
  1732. function testUpdateNewsletter() {
  1733. // Create a second category.
  1734. $this->drupalGet('admin/config/services/simplenews');
  1735. $this->clickLink(t('Add newsletter category'));
  1736. $edit = array(
  1737. 'name' => $this->randomName(),
  1738. 'description' => $this->randomString(20),
  1739. );
  1740. $this->drupalPost(NULL, $edit, t('Save'));
  1741. $this->drupalGet('node/add/simplenews');
  1742. $this->assertText(t('Newsletter category'));
  1743. $edit = array(
  1744. 'title' => $this->randomName(),
  1745. // @todo avoid hardcoding the term id.
  1746. 'field_simplenews_term[und]' => 1,
  1747. );
  1748. $this->drupalPost(NULL, $edit, ('Save'));
  1749. $this->assertTrue(preg_match('|node/(\d+)$|', $this->getUrl(), $matches), 'Node created.');
  1750. $node = node_load($matches[1]);
  1751. // Verify newsletter.
  1752. $newsletter = simplenews_newsletter_load($node->nid);
  1753. $this->assertEqual(SIMPLENEWS_STATUS_SEND_NOT, $newsletter->status, t('Newsletter sending not started.'));
  1754. $this->assertEqual(1, $newsletter->tid, t('Newsletter has tid 1'));
  1755. $this->clickLink(t('Edit'));
  1756. $update = array(
  1757. 'field_simplenews_term[und]' => 2,
  1758. );
  1759. $this->drupalPost(NULL, $update, t('Save'));
  1760. // Verify newsletter.
  1761. $newsletter = simplenews_newsletter_load($node->nid);
  1762. $this->assertEqual(SIMPLENEWS_STATUS_SEND_NOT, $newsletter->status, t('Newsletter sending not started.'));
  1763. $this->assertEqual(2, $newsletter->tid, t('Newsletter has tid 2.'));
  1764. }
  1765. /**
  1766. * Create a newsletter, send mails and then delete.
  1767. */
  1768. function testDelete() {
  1769. // Verify that the newsletter settings are shown.
  1770. $this->drupalGet('node/add/simplenews');
  1771. $this->assertText(t('Newsletter category'));
  1772. // Prevent deleting the mail spool entries automatically.
  1773. variable_set('simplenews_spool_expire', 1);
  1774. $edit = array(
  1775. 'title' => $this->randomName(),
  1776. );
  1777. $this->drupalPost(NULL, $edit, ('Save'));
  1778. $this->assertTrue(preg_match('|node/(\d+)$|', $this->getUrl(), $matches), 'Node created');
  1779. $node = node_load($matches[1]);
  1780. $this->clickLink(t('Newsletter'));
  1781. $this->assertText(t('Send one test newsletter to the test address'));
  1782. $this->assertText(t('Send newsletter'));
  1783. $this->assertNoText(t('Send newsletter when published'), t('Send on publish is not shown for published nodes.'));
  1784. // Verify state.
  1785. $newsletter = simplenews_newsletter_load($node->nid);
  1786. $this->assertEqual(SIMPLENEWS_STATUS_SEND_NOT, $newsletter->status, t('Newsletter not sent yet.'));
  1787. // Send now.
  1788. $this->drupalPost(NULL, array('simplenews[send]' => SIMPLENEWS_COMMAND_SEND_NOW), t('Submit'));
  1789. // Verify state.
  1790. $newsletter = simplenews_newsletter_load($node->nid);
  1791. $this->assertEqual(SIMPLENEWS_STATUS_SEND_PENDING, $newsletter->status, t('Newsletter sending pending.'));
  1792. $spooled = db_query('SELECT COUNT(*) FROM {simplenews_mail_spool} WHERE nid = :nid', array(':nid' => $node->nid))->fetchField();
  1793. $this->assertEqual(5, $spooled, t('5 mails remaining in spool.'));
  1794. // Verify that deleting isn't possible right now.
  1795. $this->clickLink(t('Edit'));
  1796. $this->assertText(t("You can't delete this newsletter because it has not been sent to all its subscribers."));
  1797. $this->assertNoText(t('Delete'));
  1798. // Send mails.
  1799. simplenews_cron();
  1800. // Verify state.
  1801. $newsletter = simplenews_newsletter_load($node->nid);
  1802. $this->assertEqual(SIMPLENEWS_STATUS_SEND_READY, $newsletter->status, t('Newsletter sending finished'));
  1803. $spooled = db_query('SELECT COUNT(*) FROM {simplenews_mail_spool} WHERE nid = :nid', array(':nid' => $node->nid))->fetchField();
  1804. $this->assertEqual(5, $spooled, t('Mails are kept in simplenews_mail_spool after being sent.'));
  1805. // Verify mails.
  1806. $mails = $this->drupalGetMails();
  1807. $this->assertEqual(5, count($mails), t('All mails were sent.'));
  1808. foreach ($mails as $mail) {
  1809. $this->assertEqual($mail['subject'], '[Drupal newsletter] ' . $edit['title'], t('Mail has correct subject'));
  1810. $this->assertTrue(isset($this->subscribers[$mail['to']]), t('Found valid recipient'));
  1811. unset($this->subscribers[$mail['to']]);
  1812. }
  1813. $this->assertEqual(0, count($this->subscribers), t('all subscribers have been received a mail'));
  1814. // Update timestamp to simulate pending lock expiration.
  1815. db_update('simplenews_mail_spool')
  1816. ->fields(array(
  1817. 'timestamp' => simplenews_get_expiration_time() - 1,
  1818. ))
  1819. ->execute();
  1820. // Verify that kept mail spool rows are not re-sent.
  1821. simplenews_cron();
  1822. simplenews_get_spool();
  1823. $mails = $this->drupalGetMails();
  1824. $this->assertEqual(5, count($mails), t('No additional mails have been sent.'));
  1825. // Now delete.
  1826. $this->clickLink(t('Edit'));
  1827. $this->drupalPost(NULL, array(), t('Delete'));
  1828. $this->drupalPost(NULL, array(), t('Delete'));
  1829. // Verify.
  1830. $newsletter = simplenews_newsletter_load($node->nid);
  1831. $this->assertFalse($newsletter);
  1832. $spooled = db_query('SELECT COUNT(*) FROM {simplenews_mail_spool} WHERE nid = :nid', array(':nid' => $node->nid))->fetchField();
  1833. $this->assertEqual(0, $spooled, t('No mails remaining in spool.'));
  1834. }
  1835. }
  1836. /**
  1837. * Test cases for creating and sending newsletters.
  1838. */
  1839. class SimplenewsSourceTestCase extends SimplenewsTestCase {
  1840. /**
  1841. * Implementation of getInfo().
  1842. */
  1843. function getInfo() {
  1844. return array(
  1845. 'name' => t('Source tests'),
  1846. 'description' => t('Tests for the new source interfaces and concepts.'),
  1847. 'group' => t('Simplenews'),
  1848. );
  1849. }
  1850. function setUp() {
  1851. parent::setUp();
  1852. $this->user = $this->drupalCreateUser(array('administer newsletters', 'send newsletter', 'administer nodes', 'administer simplenews subscriptions', 'create simplenews content', 'edit any simplenews content', 'view own unpublished content', 'delete any simplenews content', 'administer simplenews settings'));
  1853. $this->drupalLogin($this->user);
  1854. }
  1855. /**
  1856. * Tests that sending a minimal implementation of the source interface works.
  1857. */
  1858. function testSendMinimalSourceImplementation() {
  1859. // Create a basic plaintext test source and send it.
  1860. $plain_source = new SimplenewsSourceTest('plain');
  1861. simplenews_send_source($plain_source);
  1862. $mails = $this->drupalGetMails();
  1863. $mail = $mails[0];
  1864. // Assert resulting mail.
  1865. $this->assertEqual('simplenews_node', $mail['id']);
  1866. $this->assertEqual('simplenews', $mail['module']);
  1867. $this->assertEqual('node', $mail['key']);
  1868. $this->assertEqual($plain_source->getRecipient(), $mail['to']);
  1869. $this->assertEqual($plain_source->getFromFormatted(), $mail['from']);
  1870. $this->assertEqual($plain_source->getLanguage(), $mail['language']);
  1871. $this->assertTrue($mail['params']['plain']);
  1872. $this->assertFalse(isset($mail['params']['plaintext']));
  1873. $this->assertFalse(isset($mail['params']['attachments']));
  1874. $this->assertEqual($plain_source->getSubject(), $mail['subject']);
  1875. $this->assertTrue(strpos($mail['body'], 'the plain body') !== FALSE);
  1876. $this->assertTrue(strpos($mail['body'], 'the plain footer') !== FALSE);
  1877. $html_source = new SimplenewsSourceTest('html');
  1878. simplenews_send_source($html_source);
  1879. $mails = $this->drupalGetMails();
  1880. $mail = $mails[1];
  1881. // Assert resulting mail.
  1882. $this->assertEqual('simplenews_node', $mail['id']);
  1883. $this->assertEqual('simplenews', $mail['module']);
  1884. $this->assertEqual('node', $mail['key']);
  1885. $this->assertEqual($plain_source->getRecipient(), $mail['to']);
  1886. $this->assertEqual($plain_source->getFromFormatted(), $mail['from']);
  1887. $this->assertEqual($plain_source->getLanguage(), $mail['language']);
  1888. $this->assertEqual(NULL, $mail['params']['plain']);
  1889. $this->assertTrue(isset($mail['params']['plaintext']));
  1890. $this->assertTrue(strpos($mail['params']['plaintext'], 'the plain body') !== FALSE);
  1891. $this->assertTrue(strpos($mail['params']['plaintext'], 'the plain footer') !== FALSE);
  1892. $this->assertTrue(isset($mail['params']['attachments']));
  1893. $this->assertEqual('example://test.png', $mail['params']['attachments'][0]['uri']);
  1894. $this->assertEqual($plain_source->getSubject(), $mail['subject']);
  1895. $this->assertTrue(strpos($mail['body'], 'the body') !== FALSE);
  1896. $this->assertTrue(strpos($mail['body'], 'the footer') !== FALSE);
  1897. }
  1898. /**
  1899. * Test sending a newsletter to 100 recipients with caching enabled.
  1900. */
  1901. function testSendCaching() {
  1902. $this->setUpSubscribers(100);
  1903. // Enable build caching.
  1904. $edit = array(
  1905. 'simplenews_source_cache' => 'SimplenewsSourceCacheBuild',
  1906. );
  1907. $this->drupalPost('admin/config/services/simplenews/settings/mail', $edit, t('Save configuration'));
  1908. $edit = array(
  1909. 'title' => $this->randomName(),
  1910. 'body[und][0][value]' => "Mail token: <strong>[simplenews-subscriber:mail]</strong>",
  1911. );
  1912. $this->drupalPost('node/add/simplenews', $edit, ('Save'));
  1913. $this->assertTrue(preg_match('|node/(\d+)$|', $this->getUrl(), $matches), 'Node created');
  1914. $node = node_load($matches[1]);
  1915. // Add node to spool.
  1916. simplenews_add_node_to_spool($node);
  1917. // Unsubscribe one of the recipients to make sure that he doesn't receive
  1918. // the mail.
  1919. simplenews_unsubscribe_user(array_shift($this->subscribers), $this->getRandomNewsletter(), FALSE, 'test');
  1920. $before = microtime(TRUE);
  1921. simplenews_mail_spool();
  1922. $after = microtime(TRUE);
  1923. // Make sure that 99 mails have been sent.
  1924. $this->assertEqual(99, count($this->drupalGetMails()));
  1925. // Test that tokens are correctly replaced.
  1926. foreach (array_slice($this->drupalGetMails(), 0, 3) as $mail) {
  1927. // Make sure that the same mail was used in the body token as it has been
  1928. // sent to. Also verify that the mail is plaintext.
  1929. $this->assertTrue(strpos($mail['body'], '*' . $mail['to'] . '*') !== FALSE);
  1930. $this->assertFalse(strpos($mail['body'], '<strong>'));
  1931. // Make sure the body is only attached once.
  1932. $this->assertEqual(1, preg_match_all('/Mail token/', $mail['body'], $matches));
  1933. $this->assertTrue(strpos($mail['body'], t('Unsubscribe from this newsletter')));
  1934. }
  1935. // Report time. @todo: Find a way to actually do some assertions here.
  1936. $this->pass(t('Mails have been sent in @sec seconds with build caching enabled.', array('@sec' => round($after - $before, 3))));
  1937. }
  1938. /**
  1939. * Send a newsletter with the HTML format.
  1940. */
  1941. function testSendHTML() {
  1942. $this->setUpSubscribers(5);
  1943. // Use custom testing mail system to support HTML mails.
  1944. variable_set('mail_system', array('default-system' => 'SimplenewsHTMLTestingMailSystem'));
  1945. // Set the format to HTML.
  1946. $this->drupalGet('admin/config/services/simplenews');
  1947. $this->clickLink(t('edit newsletter category'));
  1948. $edit_category = array(
  1949. 'format' => 'html',
  1950. // Use umlaut to provoke mime encoding.
  1951. 'from_name' => 'Drupäl',
  1952. // @todo: This shouldn't be necessary, default value is missing. Probably
  1953. // should not be required.
  1954. 'from_address' => $this->randomEmail(),
  1955. );
  1956. $this->drupalPost(NULL, $edit_category, t('Save'));
  1957. $edit = array(
  1958. 'title' => $this->randomName(),
  1959. 'body[und][0][value]' => "Mail token: <strong>[simplenews-subscriber:mail]</strong>",
  1960. );
  1961. $this->drupalPost('node/add/simplenews', $edit, ('Save'));
  1962. $this->assertTrue(preg_match('|node/(\d+)$|', $this->getUrl(), $matches), 'Node created');
  1963. $node = node_load($matches[1]);
  1964. // Add node to spool.
  1965. simplenews_add_node_to_spool($node);
  1966. // Send mails.
  1967. simplenews_mail_spool();
  1968. // Make sure that 5 mails have been sent.
  1969. $this->assertEqual(5, count($this->drupalGetMails()));
  1970. // Test that tokens are correctly replaced.
  1971. foreach (array_slice($this->drupalGetMails(), 0, 3) as $mail) {
  1972. // Verify title.
  1973. $this->assertTrue(strpos($mail['body'], '<h2>' . $node->title . '</h2>') !== FALSE);
  1974. // Make sure that the same mail was used in the body token as it has been
  1975. // sent to.
  1976. $this->assertTrue(strpos($mail['body'], '<strong>' . $mail['to'] . '</strong>') !== FALSE);
  1977. // Make sure the body is only attached once.
  1978. $this->assertEqual(1, preg_match_all('/Mail token/', $mail['body'], $matches));
  1979. // Check the plaintext version.
  1980. $this->assertTrue(strpos($mail['params']['plaintext'], $mail['to']) !== FALSE);
  1981. $this->assertFalse(strpos($mail['params']['plaintext'], '<strong>'));
  1982. // Make sure the body is only attached once.
  1983. $this->assertEqual(1, preg_match_all('/Mail token/', $mail['params']['plaintext'], $matches));
  1984. // The mail system is responsible for mime encoding, make sure the from
  1985. // address is not yet encoded.
  1986. $this->assertEqual('"' . $edit_category['from_name'] . '" <' . $edit_category['from_address'] . '>', $mail['from']);
  1987. // @todo: Improve this check, there are currently two spaces, not sure
  1988. // where they are coming from.
  1989. $this->assertTrue(strpos($mail['body'], 'class="newsletter-footer"'));
  1990. }
  1991. }
  1992. /**
  1993. * Send a newsletter with the category set to hidden.
  1994. */
  1995. function testSendHidden() {
  1996. $this->setUpSubscribers(5);
  1997. // Set the format to HTML.
  1998. $this->drupalGet('admin/config/services/simplenews');
  1999. $this->clickLink(t('edit newsletter category'));
  2000. $edit = array(
  2001. 'opt_inout' => 'hidden',
  2002. // @todo: This shouldn't be necessary.
  2003. 'from_address' => $this->randomEmail(),
  2004. );
  2005. $this->drupalPost(NULL, $edit, t('Save'));
  2006. $edit = array(
  2007. 'title' => $this->randomName(),
  2008. 'body[und][0][value]' => "Mail token: <strong>[simplenews-subscriber:mail]</strong>",
  2009. );
  2010. $this->drupalPost('node/add/simplenews', $edit, ('Save'));
  2011. $this->assertTrue(preg_match('|node/(\d+)$|', $this->getUrl(), $matches), 'Node created');
  2012. $node = node_load($matches[1]);
  2013. // Add node to spool.
  2014. simplenews_add_node_to_spool($node);
  2015. // Send mails.
  2016. simplenews_mail_spool();
  2017. // Make sure that 5 mails have been sent.
  2018. $this->assertEqual(5, count($this->drupalGetMails()));
  2019. // Test that tokens are correctly replaced.
  2020. foreach (array_slice($this->drupalGetMails(), 0, 3) as $mail) {
  2021. // Verify the footer is not displayed for hidden newsletters.
  2022. $this->assertFalse(strpos($mail['body'], t('Unsubscribe from this newsletter')));
  2023. }
  2024. }
  2025. /**
  2026. * Test with disabled caching.
  2027. */
  2028. function testSendNoCaching() {
  2029. $this->setUpSubscribers(100);
  2030. // Disable caching.
  2031. $edit = array(
  2032. 'simplenews_source_cache' => 'SimplenewsSourceCacheNone',
  2033. );
  2034. $this->drupalPost('admin/config/services/simplenews/settings/mail', $edit, t('Save configuration'));
  2035. $edit = array(
  2036. 'title' => $this->randomName(),
  2037. 'body[und][0][value]' => "Mail token: <strong>[simplenews-subscriber:mail]</strong>",
  2038. );
  2039. $this->drupalPost('node/add/simplenews', $edit, ('Save'));
  2040. $this->assertTrue(preg_match('|node/(\d+)$|', $this->getUrl(), $matches), 'Node created');
  2041. $node = node_load($matches[1]);
  2042. // Add node to spool.
  2043. simplenews_add_node_to_spool($node);
  2044. $before = microtime(TRUE);
  2045. simplenews_mail_spool();
  2046. $after = microtime(TRUE);
  2047. // Make sure that 100 mails have been sent.
  2048. $this->assertEqual(100, count($this->drupalGetMails()));
  2049. // Test that tokens are correctly replaced.
  2050. foreach (array_slice($this->drupalGetMails(), 0, 3) as $mail) {
  2051. // Make sure that the same mail was used in the body token as it has been
  2052. // sent to. Also verify that the mail is plaintext.
  2053. $this->assertTrue(strpos($mail['body'], '*' . $mail['to'] . '*') !== FALSE);
  2054. $this->assertFalse(strpos($mail['body'], '<strong>'));
  2055. // Make sure the body is only attached once.
  2056. $this->assertEqual(1, preg_match_all('/Mail token/', $mail['body'], $matches));
  2057. }
  2058. // Report time. @todo: Find a way to actually do some assertions here.
  2059. $this->pass(t('Mails have been sent in @sec seconds with caching disabled.', array('@sec' => round($after - $before, 3))));
  2060. }
  2061. }