PageRenderTime 26ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/extensions/ContributionTracking/tests/ContributionTrackingProcessorTest.php

https://github.com/ChuguluGames/mediawiki-svn
PHP | 429 lines | 284 code | 50 blank | 95 comment | 6 complexity | 8c197189c7d3da1de7e03bc12acd5117 MD5 | raw file
  1. <?php
  2. /**
  3. * Tests for the ContributionTrackingProcessor class. This class is used by both
  4. * the interstitial page and the API to process donation requests, determine
  5. * where the donor should be sent next, and send them there with all the
  6. * required information in a format accepted by the gateway.
  7. * @group Fundraising
  8. * @group Splunge
  9. * @author Katie Horn <khorn@wikimedia.org>
  10. */
  11. class ContributionTrackingProcessorTest extends MediaWikiTestCase {
  12. /**
  13. * tests the rekey function in the ContributionTrackingProcessor.
  14. */
  15. function testRekey() {
  16. $start = array(
  17. 'bears' => 'green',
  18. 'emus' => 'purple'
  19. );
  20. $expected = array(
  21. 'llamas' => 'green',
  22. 'emus' => 'purple'
  23. );
  24. ContributionTrackingProcessor::rekey( $start, 'bears', 'llamas' );
  25. $this->assertEquals( $start, $expected, "Rekey is not working as expected." );
  26. }
  27. /**
  28. * Tests the stage_checkbox function
  29. * $start coming out as $expected will tell us that it works as expected
  30. * with both existing and non-existant keys
  31. */
  32. function testStageCheckbox() {
  33. $start = array(
  34. 'bears' => 'green',
  35. 'emus' => 'purple'
  36. );
  37. $expected = array(
  38. 'bears' => 1,
  39. 'emus' => 'purple'
  40. );
  41. ContributionTrackingProcessor::stage_checkbox( $start, 'bears' );
  42. ContributionTrackingProcessor::stage_checkbox( $start, 'llamas' );
  43. $this->assertEquals( $start, $expected, "stage_checkbox is not working as expected." );
  44. }
  45. /**
  46. * tests the stage_contribution function, and as a by-product,
  47. * the getContributionDefaults function as well.
  48. * Asserts that:
  49. * A staged contribution with no relevant fields will come back equal
  50. * to exactly the defaults
  51. * A staged contribution with some relevant fields will come back as
  52. * the defaults, with keys overwritten by the supplied fields where they
  53. * exist
  54. * A staged contribution with some relevant fields and some irrelevant
  55. * fields will come back as the defaults, with relevant keys overwritten by
  56. * the supplied fields where they exist. The irrelevant fields should not
  57. * come back at all.
  58. * A staged contribution with boolean (checkbox) fields will come back
  59. * with those values either set to "1" or "0", depending solely on whether
  60. * they exist in the supplied parameters or not.
  61. */
  62. function testStageContribution() {
  63. $start = array(
  64. 'bears' => 'green',
  65. 'emus' => 'purple'
  66. );
  67. $expected = ContributionTrackingProcessor::getContributionDefaults();
  68. $result = ContributionTrackingProcessor::stage_contribution( $start );
  69. $this->assertEquals( $expected, $result, "Staged Contribution with no defined fields should be exactly all the default values." );
  70. $additional = array(
  71. 'note' => 'B Flat',
  72. 'referrer' => 'phpunit_processor',
  73. 'anonymous' => 'Raspberries'
  74. );
  75. $expected = array(
  76. 'note' => 'B Flat',
  77. 'referrer' => 'phpunit_processor',
  78. 'anonymous' => 1,
  79. 'utm_source' => null,
  80. 'utm_medium' => null,
  81. 'utm_campaign' => null,
  82. 'optout' => 0,
  83. 'language' => null,
  84. 'owa_session' => null,
  85. 'owa_ref' => null,
  86. 'ts' => null,
  87. );
  88. $result = ContributionTrackingProcessor::stage_contribution( $additional );
  89. $this->assertEquals( $expected, $result, "Contribution not staging properly." );
  90. $start = array_merge( $start, $additional );
  91. $result = ContributionTrackingProcessor::stage_contribution( $start );
  92. $this->assertEquals( $expected, $result, "Contribution not staging properly." );
  93. $complete = array(
  94. 'note' => 'Batman',
  95. 'referrer' => 'phpunit_processor',
  96. 'anonymous' => 'of course',
  97. 'utm_source' => 'batcave',
  98. 'utm_medium' => 'Alfred',
  99. 'utm_campaign' => 'Joker',
  100. 'language' => 'squeak!',
  101. 'owa_session' => 'arghargh',
  102. 'owa_ref' => 'test',
  103. 'ts' => '11235813'
  104. );
  105. $expected = $complete;
  106. $expected['anonymous'] = 1;
  107. $expected['optout'] = 0;
  108. $result = ContributionTrackingProcessor::stage_contribution( $complete );
  109. $this->assertEquals( $expected, $result, "Contribution not staging properly." );
  110. }
  111. /**
  112. * Tests saveNewContribution()
  113. * Assertions:
  114. * saveNewContributions returns a number.
  115. * Each parameter saved to the contribution_tracking table is identical
  116. * to the value we were trying to save, in the row matching the ID returned
  117. * from saveNewContribution.
  118. * The owa_ref URL value is stored in the owa_ref table, and referenced
  119. * by the correct id in the owa_ref column
  120. *
  121. */
  122. function testSaveNewContribution() {
  123. //TODO: Test inserting pure garbage.
  124. $complete = array(
  125. 'note' => 'Batman is pretty awesome.',
  126. 'referrer' => 'phpunit_processor',
  127. 'anonymous' => 'of course',
  128. 'utm_source' => 'batcave',
  129. 'utm_medium' => 'Alfred',
  130. 'utm_campaign' => 'Joker',
  131. 'language' => 'squeak!',
  132. 'owa_session' => 'arghargh',
  133. 'owa_ref' => 'test'
  134. );
  135. $table1_check = $complete;
  136. $table1_check['anonymous'] = 1;
  137. $table1_check['optout'] = 0;
  138. unset( $table1_check['owa_ref'] );
  139. $id = ContributionTrackingProcessor::saveNewContribution( $complete );
  140. $this->assertTrue( is_numeric( $id ), "Returned value is not an ID." );
  141. $db = ContributionTrackingProcessor::contributionTrackingConnection();
  142. $row = $db->selectRow( 'contribution_tracking', '*', array( 'id' => $id ) );
  143. foreach ( $table1_check as $key => $value ) {
  144. $this->assertEquals( $value, $row->$key, "$key does not match in the database." );
  145. }
  146. $row = $db->selectRow( 'contribution_tracking_owa_ref', '*', array( 'id' => $row->owa_ref ) );
  147. $this->assertEquals( $complete['owa_ref'], $row->url, "OWA Reference lookup does not match" );
  148. }
  149. /**
  150. * tests the getRepostFields function.
  151. * Assertions:
  152. * getRepostFields returns an array.
  153. * getRepostFields returns expected fields for a one-time paypal
  154. * donation.
  155. * getRepostFields returns expected fields for a one-time paypal
  156. * donation.
  157. * getRepostFields returns expected fields for a one-time paypal
  158. * donation.
  159. * getRepostFields returns translated fields (when they will be
  160. * displayed by the gateway) and return-to's for the specified language.
  161. *
  162. */
  163. function testGetRepostFields() {
  164. //TODO: More here.
  165. $minimal = array(
  166. 'referrer' => 'phpunit_processor',
  167. 'gateway' => 'paypal',
  168. 'amount' => '8.80'
  169. );
  170. $returnTitle = Title::newFromText( 'Donate-thanks/en' );
  171. $expected = array(
  172. 'action' => 'https://www.paypal.com/cgi-bin/webscr',
  173. 'fields' => array(
  174. 'business' => 'donations@wikimedia.org',
  175. 'item_number' => 'DONATE',
  176. 'no_note' => 0,
  177. 'return' => wfExpandUrl( $returnTitle->getFullUrl(), PROTO_HTTP ),
  178. 'currency_code' => 'USD',
  179. 'cmd' => '_xclick',
  180. 'notify_url' => 'https://civicrm.wikimedia.org/fundcore_gateway/paypal',
  181. 'item_name' => 'One-time donation',
  182. 'amount' => '8.80',
  183. 'custom' => '',
  184. )
  185. );
  186. $ret = ContributionTrackingProcessor::getRepostFields( $minimal );
  187. $this->assertTrue( is_array( $ret ), "Returned value is not an array" );
  188. $this->assertEquals( $ret, $expected, "Fields for reposting (Paypal, one-time) do not match expected fields" );
  189. //test paypal recurring
  190. $minimal['recurring_paypal'] = true;
  191. $expected['fields']['t3'] = 'M';
  192. $expected['fields']['p3'] = '1';
  193. $expected['fields']['srt'] = '12';
  194. $expected['fields']['src'] = '1';
  195. $expected['fields']['sra'] = '1';
  196. $expected['fields']['cmd'] = '_xclick-subscriptions';
  197. $expected['fields']['item_name'] = 'Recurring monthly donation';
  198. $expected['fields']['a3'] = '8.80';
  199. unset( $expected['fields']['amount'] );
  200. $ret = ContributionTrackingProcessor::getRepostFields( $minimal );
  201. $this->assertEquals( $ret, $expected, "Fields for reposting (Paypal, recurring) do not match expected fields" );
  202. //test moneybookers... just in case anybody cares anymore.
  203. unset( $minimal['recurring_paypal'] );
  204. $minimal['gateway'] = 'moneybookers';
  205. $expected = array(
  206. 'action' => 'https://www.moneybookers.com/app/payment.pl',
  207. 'fields' => Array
  208. (
  209. 'merchant_fields' => 'os0',
  210. 'pay_to_email' => 'donation@wikipedia.org',
  211. 'status_url' => 'https://civicrm.wikimedia.org/fundcore_gateway/moneybookers',
  212. 'language' => 'en',
  213. 'detail1_description' => 'One-time donation',
  214. 'detail1_text' => 'DONATE',
  215. 'currency' => 'USD',
  216. 'amount' => '8.80',
  217. 'custom' => '',
  218. )
  219. );
  220. $ret = ContributionTrackingProcessor::getRepostFields( $minimal );
  221. $this->assertEquals( $ret, $expected, "Fields for reposting (moneybookers, one-time) do not match expected fields" );
  222. //test alternate language
  223. $minimal['gateway'] = 'paypal';
  224. $minimal['language'] = 'ja'; //japanese.
  225. $returnTitle = Title::newFromText( 'Donate-thanks/ja' );
  226. $expected = array(
  227. 'action' => 'https://www.paypal.com/cgi-bin/webscr',
  228. 'fields' => array(
  229. 'business' => 'donations@wikimedia.org',
  230. 'item_number' => 'DONATE',
  231. 'no_note' => 0,
  232. 'return' => wfExpandUrl( $returnTitle->getFullUrl(), PROTO_HTTP ), //Important to the language test.
  233. 'currency_code' => 'USD',
  234. 'cmd' => '_xclick',
  235. 'notify_url' => 'https://civicrm.wikimedia.org/fundcore_gateway/paypal',
  236. 'item_name' => '1回だけ寄付', //This should be translated.
  237. 'amount' => '8.80',
  238. 'custom' => '',
  239. )
  240. );
  241. $ret = ContributionTrackingProcessor::getRepostFields( $minimal );
  242. $this->assertEquals( $ret, $expected, "Fields for reposting (paypal, one-time, language=ja) do not match expected fields" );
  243. //test T-shirtness
  244. $minimal['gateway'] = 'paypal';
  245. $minimal['language'] = 'en';
  246. $minimal['tshirt'] = true;
  247. $minimal['size'] = 'medium';
  248. $minimal['premium_language'] = 'ja';
  249. $returnTitle = Title::newFromText( 'Donate-thanks/en' );
  250. $expected = array(
  251. 'action' => 'https://www.paypal.com/cgi-bin/webscr',
  252. 'fields' => array(
  253. 'business' => 'donations@wikimedia.org',
  254. 'item_number' => 'DONATE',
  255. 'no_note' => 0,
  256. 'return' => wfExpandUrl( $returnTitle->getFullUrl(), PROTO_HTTP ),
  257. 'currency_code' => 'USD',
  258. 'cmd' => '_xclick',
  259. 'notify_url' => 'https://civicrm.wikimedia.org/fundcore_gateway/paypal',
  260. 'item_name' => 'One-time donation',
  261. 'amount' => '8.80',
  262. 'custom' => '',
  263. 'on0' => 'Shirt size',
  264. 'os0' => 'medium',
  265. 'on1' => 'Shirt language',
  266. 'os1' => 'ja',
  267. 'no_shipping' => 2
  268. )
  269. );
  270. $ret = ContributionTrackingProcessor::getRepostFields( $minimal );
  271. $this->assertEquals( $ret, $expected, "Fields for reposting (paypal, one-time, T-shirt) do not match expected fields" );
  272. }
  273. /**
  274. * tests the stage_repost function
  275. * Assertions:
  276. * Garbage in, defaults out.
  277. * The recurring_paypal key is treated like a boolean
  278. */
  279. function testStageRepost() {
  280. $start = array(
  281. 'bears' => 'green',
  282. 'emus' => 'purple'
  283. );
  284. ContributionTrackingProcessor::getLanguage( array( 'language' => 'en' ) );
  285. $expected = ContributionTrackingProcessor::getRepostDefaults();
  286. $expected['item_name'] = 'One-time donation';
  287. $expected['notify_url'] = 'https://civicrm.wikimedia.org/fundcore_gateway/paypal';
  288. $result = ContributionTrackingProcessor::stage_repost( $start );
  289. $this->assertEquals( $expected, $result, "Staged Repost with no defined fields should be exactly all the default values." );
  290. $additional = array(
  291. 'gateway' => 'testgateway',
  292. 'recurring_paypal' => 'raspberries',
  293. 'amount' => '6.60'
  294. );
  295. $expected = array(
  296. 'gateway' => 'testgateway',
  297. 'tshirt' => false,
  298. 'size' => false,
  299. 'premium_language' => false,
  300. 'currency_code' => 'USD',
  301. 'return' => 'Donate-thanks/en',
  302. 'fname' => '',
  303. 'lname' => '',
  304. 'email' => '',
  305. 'recurring_paypal' => '1',
  306. 'amount' => '6.60',
  307. 'amount_given' => '',
  308. 'contribution_tracking_id' => '',
  309. 'notify_url' => 'https://civicrm.wikimedia.org/fundcore_gateway/paypal',
  310. 'item_name' => 'Recurring monthly donation'
  311. );
  312. $result = ContributionTrackingProcessor::stage_repost( $additional );
  313. $this->assertEquals( $expected, $result, "Repost not staging properly." );
  314. unset( $additional['recurring_paypal'] );
  315. $expected['recurring_paypal'] = 0;
  316. $expected['item_name'] = 'One-time donation';
  317. $result = ContributionTrackingProcessor::stage_repost( $additional );
  318. $this->assertEquals( $expected, $result, "Repost not staging properly." );
  319. }
  320. /**
  321. * tests the get_owa_ref_id function
  322. * Assertions:
  323. * The unique add comes back with a numeric id.
  324. * The second call also comes back with a numeric id.
  325. * The insert and the lookup come back with the same numeric id.
  326. */
  327. function testGetOWARefID() {
  328. $testRef = "test_ref_" . time();
  329. $id_1 = ContributionTrackingProcessor::get_owa_ref_id( $testRef ); //add
  330. $id_2 = ContributionTrackingProcessor::get_owa_ref_id( $testRef ); //get
  331. $this->assertTrue( is_numeric( $id_1 ), "First id is not numeric: Problem adding OWA Ref URL" );
  332. $this->assertTrue( is_numeric( $id_2 ), "Second id is not numeric: Problem retrieving OWA Ref ID" );
  333. $this->assertEquals( $id_1, $id_2, "IDs do not match." );
  334. }
  335. /**
  336. * tests the getLanguage function.
  337. * NOTE: Static vars are involved here.
  338. * Assertions:
  339. * getLanguage with no parameters returns english (if none of the
  340. * previous tests set the var differently. Static vars have tricky initial
  341. * conditions...)
  342. * Passing getLanguage a different language than the one previously in
  343. * use will cause the var to reset to the explicit language. Messages should
  344. * be sent in the new language.
  345. */
  346. function testGetLanguage() {
  347. $messageKey = 'contributiontracking';
  348. $messageBG = 'Проследяване на дарението';
  349. $messageEN = 'Contribution tracking';
  350. $code = ContributionTrackingProcessor::getLanguage();
  351. $this->assertEquals( $code, 'en', "Default language is not US (or your test has a hangover)" );
  352. $params['language'] = 'bg';
  353. $code = ContributionTrackingProcessor::getLanguage( $params );
  354. $this->assertEquals( $params['language'], $code, "Returned language is not the one we just sent." );
  355. $message = ContributionTrackingProcessor::msg( $messageKey );
  356. $this->assertEquals( $message, $messageBG, "Returned language is not the one we just sent." );
  357. $params['language'] = 'en';
  358. $code = ContributionTrackingProcessor::getLanguage( $params );
  359. $this->assertEquals( $params['language'], $code, "Returned language is not the one we just sent." );
  360. $message = ContributionTrackingProcessor::msg( $messageKey );
  361. $this->assertEquals( $message, $messageEN, "Returned language is not the one we just sent." );
  362. }
  363. /**
  364. * Helper function that recursively sorts arrays by key. Nice for debugging
  365. * failed assertEquals, where you're comparing large arrays.
  366. * @param array $array The array you want to recursively ksort.
  367. * @return array The ksorted array.
  368. */
  369. function deepKSort( $array ) {
  370. foreach ( $array as $key => $value ) {
  371. if ( is_array( $value ) ) {
  372. $array[$key] = $this->deepKSort( $value );
  373. }
  374. }
  375. ksort( $array );
  376. return $array;
  377. }
  378. }
  379. ?>