| 1 | <?php |
| 2 | |
| 3 | /* |
| 4 | +--------------------------------------------------------------------+ |
| 5 | | CiviCRM version 4.3 | |
| 6 | +--------------------------------------------------------------------+ |
| 7 | | Copyright CiviCRM LLC (c) 2004-2013 | |
| 8 | +--------------------------------------------------------------------+ |
| 9 | | This file is a part of CiviCRM. | |
| 10 | | | |
| 11 | | CiviCRM is free software; you can copy, modify, and distribute it | |
| 12 | | under the terms of the GNU Affero General Public License | |
| 13 | | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. | |
| 14 | | | |
| 15 | | CiviCRM is distributed in the hope that it will be useful, but | |
| 16 | | WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 17 | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | |
| 18 | | See the GNU Affero General Public License for more details. | |
| 19 | | | |
| 20 | | You should have received a copy of the GNU Affero General Public | |
| 21 | | License along with this program; if not, contact CiviCRM LLC | |
| 22 | | at info[AT]civicrm[DOT]org. If you have questions about the | |
| 23 | | GNU Affero General Public License or the licensing of CiviCRM, | |
| 24 | | see the CiviCRM license FAQ at http://civicrm.org/licensing | |
| 25 | +--------------------------------------------------------------------+ |
| 26 | */ |
| 27 | |
| 28 | require_once 'CiviTest/CiviSeleniumTestCase.php'; |
| 29 | |
| 30 | |
| 31 | |
| 32 | class WebTest_Contribute_OfflineContributionTest extends CiviSeleniumTestCase { |
| 33 | |
| 34 | protected $captureScreenshotOnFailure = TRUE; |
| 35 | protected $screenshotPath = '/var/www/api.dev.civicrm.org/public/sc'; |
| 36 | protected $screenshotUrl = 'http://api.dev.civicrm.org/sc/'; |
| 37 | |
| 38 | protected function setUp() { |
| 39 | parent::setUp(); |
| 40 | } |
| 41 | |
| 42 | function testStandaloneContributeAdd() { |
| 43 | // This is the path where our testing install resides. |
| 44 | // The rest of URL is defined in CiviSeleniumTestCase base class, in |
| 45 | // class attributes. |
| 46 | $this->open( $this->sboxPath ); |
| 47 | |
| 48 | // Logging in. Remember to wait for page to load. In most cases, |
| 49 | // you can rely on 30000 as the value that allows your test to pass, however, |
| 50 | // sometimes your test might fail because of this. In such cases, it's better to pick one element |
| 51 | // somewhere at the end of page and use waitForElementPresent on it - this assures you, that whole |
| 52 | // page contents loaded and you can continue your test execution. |
| 53 | $this->webtestLogin(); |
| 54 | |
| 55 | // Create a contact to be used as soft creditor |
| 56 | $softCreditFname = substr(sha1(rand()), 0, 7); |
| 57 | $softCreditLname = substr(sha1(rand()), 0, 7); |
| 58 | $this->webtestAddContact( $softCreditFname, $softCreditLname, false ); |
| 59 | |
| 60 | //financial account for check |
| 61 | $this->open($this->sboxPath . 'civicrm/admin/options/payment_instrument?group=payment_instrument&reset=1'); |
| 62 | $this->waitForPageToLoad(); |
| 63 | $financialAccount = $this->getText("xpath=//div[@id='payment_instrument']/div[2]/table/tbody//tr/td[1][text()='Check']/../td[3]"); |
| 64 | |
| 65 | // Add new Financial Account |
| 66 | $orgName = 'Alberta '.substr(sha1(rand()), 0, 7); |
| 67 | $financialAccountTitle = 'Financial Account '.substr(sha1(rand()), 0, 4); |
| 68 | $financialAccountDescription = "{$financialAccountTitle} Description"; |
| 69 | $accountingCode = 1033; |
| 70 | $financialAccountType = 'Asset'; |
| 71 | $taxDeductible = FALSE; |
| 72 | $isActive = FALSE; |
| 73 | $isTax = TRUE; |
| 74 | $taxRate = 9; |
| 75 | $isDefault = FALSE; |
| 76 | |
| 77 | //Add new organisation |
| 78 | if($orgName) { |
| 79 | $this->webtestAddOrganization($orgName); |
| 80 | } |
| 81 | |
| 82 | $this->_testAddFinancialAccount($financialAccountTitle, |
| 83 | $financialAccountDescription, |
| 84 | $accountingCode, |
| 85 | $orgName, |
| 86 | $financialAccountType, |
| 87 | $taxDeductible, |
| 88 | $isActive, |
| 89 | $isTax, |
| 90 | $taxRate, |
| 91 | $isDefault |
| 92 | ); |
| 93 | |
| 94 | $firstName = 'John'.substr(sha1(rand()), 0, 7); |
| 95 | $lastName = 'Dsouza'.substr(sha1(rand()), 0, 7); |
| 96 | $this->webtestAddContact($firstName, $lastName); |
| 97 | |
| 98 | $this->waitForElementPresent("css=li#tab_contribute a"); |
| 99 | $this->click("css=li#tab_contribute a"); |
| 100 | $this->waitForElementPresent("link=Record Contribution (Check, Cash, EFT ...)"); |
| 101 | $this->click("link=Record Contribution (Check, Cash, EFT ...)"); |
| 102 | $this->waitForPageToLoad($this->getTimeoutMsec()); |
| 103 | |
| 104 | // select financial type |
| 105 | $this->select("financial_type_id", "value=1"); |
| 106 | |
| 107 | // fill in Received Date |
| 108 | $this->webtestFillDate('receive_date'); |
| 109 | |
| 110 | // source |
| 111 | $this->type("source", "Mailer 1"); |
| 112 | |
| 113 | // total amount |
| 114 | $this->type("total_amount", "100"); |
| 115 | |
| 116 | // select payment instrument type = Check and enter chk number |
| 117 | $this->select("payment_instrument_id", "value=4"); |
| 118 | $this->waitForElementPresent("check_number"); |
| 119 | $this->type("check_number", "check #1041"); |
| 120 | |
| 121 | $this->type("trxn_id", "P20901X1" . rand(100, 10000)); |
| 122 | |
| 123 | // soft credit |
| 124 | $this->click("soft_credit_to"); |
| 125 | $this->type("soft_credit_to", $softCreditFname); |
| 126 | $this->typeKeys("soft_credit_to", $softCreditFname); |
| 127 | $this->waitForElementPresent("css=div.ac_results-inner li"); |
| 128 | $this->click("css=div.ac_results-inner li"); |
| 129 | |
| 130 | //Custom Data |
| 131 | // $this->click('CIVICRM_QFID_3_6'); |
| 132 | |
| 133 | //Additional Detail section |
| 134 | $this->click("AdditionalDetail"); |
| 135 | $this->waitForElementPresent("thankyou_date"); |
| 136 | |
| 137 | $this->type("note", "This is a test note."); |
| 138 | $this->type("non_deductible_amount", "10.00"); |
| 139 | $this->type("fee_amount", "0"); |
| 140 | $this->type("net_amount", "0"); |
| 141 | $this->type("invoice_id", time()); |
| 142 | $this->webtestFillDate('thankyou_date'); |
| 143 | |
| 144 | //Honoree section |
| 145 | $this->click("Honoree"); |
| 146 | $this->waitForElementPresent("honor_email"); |
| 147 | |
| 148 | $this->click("CIVICRM_QFID_1_2"); |
| 149 | $this->select("honor_prefix_id", "label=Ms."); |
| 150 | $this->type("honor_first_name", "Foo"); |
| 151 | $this->type("honor_last_name", "Bar"); |
| 152 | $this->type("honor_email", "foo@bar.com"); |
| 153 | |
| 154 | //Premium section |
| 155 | $this->click("Premium"); |
| 156 | $this->waitForElementPresent("fulfilled_date"); |
| 157 | $this->select("product_name[0]", "label=Coffee Mug ( MUG-101 )"); |
| 158 | $this->select("product_name[1]", "label=Black"); |
| 159 | $this->webtestFillDate('fulfilled_date'); |
| 160 | |
| 161 | // Clicking save. |
| 162 | $this->click("_qf_Contribution_upload"); |
| 163 | $this->waitForPageToLoad($this->getTimeoutMsec()); |
| 164 | |
| 165 | // Is status message correct? |
| 166 | $this->assertTrue($this->isTextPresent("The contribution record has been saved."), "Status message didn't show up after saving!"); |
| 167 | |
| 168 | // verify if Membership is created |
| 169 | $this->waitForElementPresent( "xpath=//div[@id='Contributions']//table//tbody/tr[1]/td[8]/span/a[text()='View']" ); |
| 170 | |
| 171 | //click through to the Membership view screen |
| 172 | $this->click( "xpath=//div[@id='Contributions']//table/tbody/tr[1]/td[8]/span/a[text()='View']" ); |
| 173 | $this->waitForElementPresent("_qf_ContributionView_cancel-bottom"); |
| 174 | |
| 175 | $expected = array('Financial Type' => 'Donation', |
| 176 | 'Total Amount' => '100.00', |
| 177 | 'Contribution Status' => 'Completed', |
| 178 | 'Paid By' => 'Check', |
| 179 | 'Check Number' => 'check #1041', |
| 180 | 'Non-deductible Amount' => '10.00', |
| 181 | 'Received Into' => $financialAccount, |
| 182 | 'Soft Credit To' => "{$softCreditFname} {$softCreditLname}" |
| 183 | ); |
| 184 | foreach($expected as $label => $value) { |
| 185 | $this->verifyText("xpath=id('ContributionView')/div[2]/table[1]/tbody//tr/td[1][text()='$label']/../td[2]", preg_quote($value)); |
| 186 | } |
| 187 | |
| 188 | // go to soft creditor contact view page |
| 189 | $this->click("xpath=id('ContributionView')/div[2]/table[1]/tbody//tr/td[1][text()='Soft Credit To']/../td[2]/a[text()='{$softCreditFname} {$softCreditLname}']"); |
| 190 | |
| 191 | // go to contribution tab |
| 192 | $this->waitForElementPresent("css=li#tab_contribute a"); |
| 193 | $this->click("css=li#tab_contribute a"); |
| 194 | $this->waitForElementPresent("link=Record Contribution (Check, Cash, EFT ...)"); |
| 195 | |
| 196 | // verify soft credit details |
| 197 | $expected = array( 3 => 'Donation', |
| 198 | 2 => '100.00', |
| 199 | 5 => 'Completed', |
| 200 | 1 => "{$firstName} {$lastName}" |
| 201 | ); |
| 202 | foreach($expected as $value => $label) { |
| 203 | $this->verifyText("xpath=id('Search')/div[2]/table[2]/tbody/tr[2]/td[$value]", preg_quote($label)); |
| 204 | } |
| 205 | } |
| 206 | |
| 207 | function testDeductibleAmount() { |
| 208 | // This is the path where our testing install resides. |
| 209 | // The rest of URL is defined in CiviSeleniumTestCase base class, in |
| 210 | // class attributes. |
| 211 | $this->open( $this->sboxPath ); |
| 212 | |
| 213 | // Logging in. Remember to wait for page to load. In most cases, |
| 214 | // you can rely on 30000 as the value that allows your test to pass, however, |
| 215 | // sometimes your test might fail because of this. In such cases, it's better to pick one element |
| 216 | // somewhere at the end of page and use waitForElementPresent on it - this assures you, that whole |
| 217 | // page contents loaded and you can continue your test execution. |
| 218 | $this->webtestLogin(); |
| 219 | |
| 220 | //add authorize .net payment processor |
| 221 | $processorName = 'Webtest AuthNet' . substr(sha1(rand()), 0, 7); |
| 222 | $this->webtestAddPaymentProcessor($processorName, 'AuthNet'); |
| 223 | |
| 224 | $this->open($this->sboxPath . "civicrm/admin/contribute/managePremiums?action=add&reset=1"); |
| 225 | $premiumName = 'test Premium' . substr(sha1(rand()), 0, 7); |
| 226 | $this->addPremium($premiumName, 'SKU', 3, 12, NULL, NULL); |
| 227 | |
| 228 | $firstName = 'John'.substr(sha1(rand()), 0, 7); |
| 229 | $lastName = 'Dsouza'.substr(sha1(rand()), 0, 7); |
| 230 | $this->webtestAddContact($firstName, $lastName); |
| 231 | |
| 232 | //scenario 1 : is_deductible = 0 and non deductible amount is entered |
| 233 | $scenario1 = array( |
| 234 | 'financial_type' => 'Campaign Contribution', |
| 235 | 'total_amount' => 111, |
| 236 | 'non_deductible_amount' => 15 |
| 237 | ); |
| 238 | $this->_doOfflineContribution($scenario1, $firstName, $lastName, $processorName); |
| 239 | |
| 240 | $checkScenario1 = array( |
| 241 | 'From' => "{$firstName} {$lastName}", |
| 242 | 'Financial Type' => 'Campaign Contribution', |
| 243 | 'Total Amount' => 111, |
| 244 | 'Non-deductible Amount' => 15 |
| 245 | ); |
| 246 | $this->_verifyAmounts($checkScenario1); |
| 247 | |
| 248 | //scenario 2 : is_deductible = TRUE and premium is set and premium is greater than total amount |
| 249 | $scenario2 = array( |
| 250 | 'financial_type' => 'Donation', |
| 251 | 'total_amount' => 10, |
| 252 | 'premium' => "{$premiumName} ( SKU )" |
| 253 | ); |
| 254 | $this->_doOfflineContribution($scenario2, $firstName, $lastName, $processorName); |
| 255 | |
| 256 | $checkScenario2 = array( |
| 257 | 'From' => "{$firstName} {$lastName}", |
| 258 | 'Financial Type' => 'Donation', |
| 259 | 'Total Amount' => 10, |
| 260 | 'Non-deductible Amount' => 10 |
| 261 | ); |
| 262 | $this->_verifyAmounts($checkScenario2); |
| 263 | |
| 264 | //scenario 3 : is_deductible = TRUE and premium is set and premium is less than total amount |
| 265 | $scenario3 = array( |
| 266 | 'financial_type' => 'Donation', |
| 267 | 'total_amount' => 123, |
| 268 | 'premium' => "{$premiumName} ( SKU )" |
| 269 | ); |
| 270 | $this->_doOfflineContribution($scenario3, $firstName, $lastName, $processorName); |
| 271 | |
| 272 | $checkScenario3 = array( |
| 273 | 'From' => "{$firstName} {$lastName}", |
| 274 | 'Financial Type' => 'Donation', |
| 275 | 'Total Amount' => 123, |
| 276 | 'Non-deductible Amount' => 12 |
| 277 | ); |
| 278 | $this->_verifyAmounts($checkScenario3); |
| 279 | |
| 280 | //scenario 4 : is_deductible = TRUE and premium is not set |
| 281 | $scenario4 = array( |
| 282 | 'financial_type' => 'Donation', |
| 283 | 'total_amount' => 123, |
| 284 | ); |
| 285 | $this->_doOfflineContribution($scenario4, $firstName, $lastName, $processorName); |
| 286 | |
| 287 | $checkScenario4 = array( |
| 288 | 'From' => "{$firstName} {$lastName}", |
| 289 | 'Financial Type' => 'Donation', |
| 290 | 'Total Amount' => 123, |
| 291 | 'Non-deductible Amount' => '0.00' |
| 292 | ); |
| 293 | $this->_verifyAmounts($checkScenario4); |
| 294 | |
| 295 | //scenario 5 : is_deductible = FALSE, non_deductible_amount = the total amount |
| 296 | $scenario5 = array( |
| 297 | 'financial_type' => 'Campaign Contribution', |
| 298 | 'total_amount' => 555, |
| 299 | ); |
| 300 | $this->_doOfflineContribution($scenario5, $firstName, $lastName, $processorName); |
| 301 | |
| 302 | $checkScenario5 = array( |
| 303 | 'From' => "{$firstName} {$lastName}", |
| 304 | 'Financial Type' => 'Campaign Contribution', |
| 305 | 'Total Amount' => 555, |
| 306 | 'Non-deductible Amount' => 555 |
| 307 | ); |
| 308 | $this->_verifyAmounts($checkScenario5); |
| 309 | } |
| 310 | |
| 311 | //common function for doing offline contribution |
| 312 | function _doOfflineContribution($params, $firstName, $lastName, $processorName) { |
| 313 | |
| 314 | $this->waitForElementPresent("css=li#tab_contribute a"); |
| 315 | $this->click("css=li#tab_contribute a"); |
| 316 | $this->waitForElementPresent("link=Submit Credit Card Contribution"); |
| 317 | $this->click("link=Submit Credit Card Contribution"); |
| 318 | $this->waitForPageToLoad($this->getTimeoutMsec()); |
| 319 | |
| 320 | // since we don't have live credentials we will switch to test mode |
| 321 | $url = $this->getLocation(); |
| 322 | $url = str_replace('mode=live', 'mode=test', $url); |
| 323 | $this->open($url); |
| 324 | |
| 325 | // start filling out contribution form |
| 326 | $this->waitForElementPresent('payment_processor_id'); |
| 327 | $this->select('payment_processor_id', "label={$processorName}"); |
| 328 | |
| 329 | // select financial type |
| 330 | $this->select("financial_type_id", "label={$params['financial_type']}"); |
| 331 | |
| 332 | // total amount |
| 333 | $this->type("total_amount", "{$params['total_amount']}"); |
| 334 | |
| 335 | // enter credit card info on form |
| 336 | $this->webtestAddCreditCardDetails(); |
| 337 | |
| 338 | // billing address |
| 339 | $this->webtestAddBillingDetails($firstName, NULL, $lastName); |
| 340 | |
| 341 | if ($nonDeductibleAmt = CRM_Utils_Array::value('non_deductible_amount', $params)) { |
| 342 | $this->click("AdditionalDetail"); |
| 343 | $this->waitForElementPresent("thankyou_date"); |
| 344 | $this->type("note", "This is a test note."); |
| 345 | $this->type("non_deductible_amount", "{$nonDeductibleAmt}"); |
| 346 | } |
| 347 | |
| 348 | if (CRM_Utils_Array::value('premium', $params)) { |
| 349 | //Premium section |
| 350 | $this->click("Premium"); |
| 351 | $this->waitForElementPresent("fulfilled_date"); |
| 352 | $this->select("product_name[0]", "label={$params['premium']}"); |
| 353 | } |
| 354 | // Clicking save. |
| 355 | $this->click("_qf_Contribution_upload"); |
| 356 | $this->waitForPageToLoad($this->getTimeoutMsec()); |
| 357 | |
| 358 | // Is status message correct? |
| 359 | $this->assertTrue($this->isTextPresent("The contribution record has been processed."), "Status message didn't show up after saving!"); |
| 360 | } |
| 361 | |
| 362 | //common function for verifing total_amount, and non_deductible_amount |
| 363 | function _verifyAmounts($verifyData) { |
| 364 | $this->waitForElementPresent( "xpath=//div[@id='Contributions']//table//tbody/tr[1]/td[8]/span/a[text()='View']" ); |
| 365 | $this->click( "xpath=//div[@id='Contributions']//table/tbody/tr[1]/td[8]/span/a[text()='View']" ); |
| 366 | $this->waitForPageToLoad($this->getTimeoutMsec()); |
| 367 | |
| 368 | foreach ($verifyData as $label => $value) { |
| 369 | $this->verifyText("xpath=//form[@id='ContributionView']//table/tbody/tr/td[text()='{$label}']/following-sibling::td", |
| 370 | preg_quote($value) |
| 371 | ); |
| 372 | } |
| 373 | |
| 374 | $this->click("_qf_ContributionView_cancel-top"); |
| 375 | $this->waitForPageToLoad($this->getTimeoutMsec()); |
| 376 | } |
| 377 | } |