CRM-15798 adjust membership date calculation for multiyear membership
[civicrm-core.git] / tests / phpunit / api / v3 / MembershipTest.php
CommitLineData
6a488035
TO
1<?php
2/*
3 +--------------------------------------------------------------------+
39de6fd5 4 | CiviCRM version 4.6 |
6a488035 5 +--------------------------------------------------------------------+
06a1bc01 6 | Copyright CiviCRM LLC (c) 2004-2014 |
6a488035
TO
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
9 | |
10 | CiviCRM is free software; you can copy, modify, and distribute it |
11 | under the terms of the GNU Affero General Public License |
12 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
13 | |
14 | CiviCRM is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. |
18 | |
19 | You should have received a copy of the GNU Affero General Public |
20 | License and the CiviCRM Licensing Exception along |
21 | 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 +--------------------------------------------------------------------+
d25dd0ee 26 */
6a488035
TO
27
28/**
29 * Test APIv3 civicrm_membership functions
30 *
6c6e6187
TO
31 * @package CiviCRM_APIv3
32 * @subpackage API_Member
6a488035
TO
33 */
34
35
36require_once 'CiviTest/CiviUnitTestCase.php';
37
4cbe18b8
EM
38/**
39 * Class api_v3_MembershipTest
40 */
6a488035
TO
41class api_v3_MembershipTest extends CiviUnitTestCase {
42 protected $_apiversion;
43 protected $_contactID;
d54576ed
EM
44 protected $_membershipID;
45 protected $_membershipID2;
46 protected $_membershipID3;
6a488035 47 protected $_membershipTypeID;
8c33a68c 48 protected $_membershipTypeID2;
6a488035 49 protected $_membershipStatusID;
6a488035
TO
50 protected $_entity;
51 protected $_params;
b7c9bc4c 52
6a488035
TO
53
54 public function setUp() {
2ea0abec 55 // Connect to the database.
6a488035
TO
56 parent::setUp();
57 $this->_apiversion = 3;
58 $this->_contactID = $this->individualCreate();
75638074 59 $this->_membershipTypeID = $this->membershipTypeCreate(array('member_of_contact_id' => $this->_contactID));
5896d037
TO
60 $this->_membershipTypeID2 = $this->membershipTypeCreate(array(
61 'period_type' => 'fixed',
2ea0abec 62 // Ie. 1 March.
5896d037 63 'fixed_period_start_day' => '301',
2ea0abec 64 // Ie. 11 Nov.
21dfd5f5 65 'fixed_period_rollover_day' => '1111',
5896d037 66 ));
6a488035
TO
67 $this->_membershipStatusID = $this->membershipStatusCreate('test status');
68
6a488035
TO
69 CRM_Member_PseudoConstant::membershipType(NULL, TRUE);
70 CRM_Member_PseudoConstant::membershipStatus(NULL, NULL, 'name', TRUE);
71 CRM_Core_PseudoConstant::activityType(TRUE, TRUE, TRUE, 'name');
72
73 $this->_entity = 'Membership';
74 $this->_params = array(
75 'contact_id' => $this->_contactID,
76 'membership_type_id' => $this->_membershipTypeID,
77 'join_date' => '2009-01-21',
78 'start_date' => '2009-01-21',
79 'end_date' => '2009-12-21',
80 'source' => 'Payment',
81 'is_override' => 1,
82 'status_id' => $this->_membershipStatusID,
6a488035
TO
83 );
84 }
85
00be9182 86 public function tearDown() {
6a488035 87 $this->quickCleanup(array(
5896d037
TO
88 'civicrm_membership',
89 'civicrm_membership_payment',
90 'civicrm_membership_log',
771f3245 91 ),
92 TRUE
6a488035
TO
93 );
94 $this->membershipStatusDelete($this->_membershipStatusID);
8c33a68c 95 $this->membershipTypeDelete(array('id' => $this->_membershipTypeID2));
6a488035
TO
96 $this->membershipTypeDelete(array('id' => $this->_membershipTypeID));
97 $this->contactDelete($this->_contactID);
98
99 }
100
101 /**
2ea0abec 102 * Test membership deletion.
6a488035 103 */
00be9182 104 public function testMembershipDelete() {
6a488035 105 $membershipID = $this->contactMembershipCreate($this->_params);
3506b6cd 106 $this->assertDBRowExist('CRM_Member_DAO_Membership', $membershipID);
6a488035 107 $params = array(
21dfd5f5 108 'id' => $membershipID,
6a488035 109 );
d54576ed 110 $this->callAPIAndDocument('membership', 'delete', $params, __FUNCTION__, __FILE__);
3506b6cd 111 $this->assertDBRowNotExist('CRM_Member_DAO_Membership', $membershipID);
6a488035
TO
112 }
113
00be9182 114 public function testMembershipDeleteEmpty() {
d54576ed 115 $this->callAPIFailure('membership', 'delete', array());
6a488035
TO
116 }
117
00be9182 118 public function testMembershipDeleteInvalidID() {
d54576ed 119 $this->callAPIFailure('membership', 'delete', array('id' => 'blah'));
6a488035
TO
120 }
121
122 /**
2ea0abec 123 * Test civicrm_membership_delete() with invalid Membership Id.
6a488035 124 */
00be9182 125 public function testMembershipDeleteWithInvalidMembershipId() {
6a488035 126 $membershipId = 'membership';
d54576ed 127 $this->callAPIFailure('membership', 'delete', $membershipId);
6a488035
TO
128 }
129
130 /**
2ea0abec 131 * Test membership get.
6a488035 132 */
00be9182 133 public function testContactMembershipsGet() {
6a488035 134 $this->_membershipID = $this->contactMembershipCreate($this->_params);
2ea0abec 135 $this->callAPISuccess('membership', 'get', array());
6c6e6187 136 $this->callAPISuccess('Membership', 'Delete', array('id' => $this->_membershipID));
6a488035
TO
137 }
138
139 /**
140 * Test civicrm_membership_get with params not array.
2ea0abec 141 *
6a488035
TO
142 * Gets treated as contact_id, memberships expected.
143 */
00be9182 144 public function testGetWithParamsContactId() {
6a488035
TO
145 $this->_membershipID = $this->contactMembershipCreate($this->_params);
146 $params = array(
147 'contact_id' => $this->_contactID,
6a488035 148 );
771f3245 149 $membership = $this->callAPISuccess('membership', 'get', $params);
6a488035
TO
150
151 $result = $membership['values'][$this->_membershipID];
771f3245 152 $this->callAPISuccess('Membership', 'Delete', array(
6a488035 153 'id' => $this->_membershipID,
5896d037 154 ));
6a488035
TO
155 $this->assertEquals($result['contact_id'], $this->_contactID, "In line " . __LINE__);
156 $this->assertEquals($result['membership_type_id'], $this->_membershipTypeID, "In line " . __LINE__);
157 $this->assertEquals($result['status_id'], $this->_membershipStatusID, "In line " . __LINE__);
158 $this->assertEquals($result['join_date'], '2009-01-21', "In line " . __LINE__);
159 $this->assertEquals($result['start_date'], '2009-01-21', "In line " . __LINE__);
160 $this->assertEquals($result['end_date'], '2009-12-21', "In line " . __LINE__);
161 $this->assertEquals($result['source'], 'Payment', "In line " . __LINE__);
162 $this->assertEquals($result['is_override'], 1, "In line " . __LINE__);
163 }
164
b4529041 165 /**
166 * Test civicrm_membership_get with params not array.
2ea0abec 167 *
b4529041 168 * Gets treated as contact_id, memberships expected.
169 */
00be9182 170 public function testGetInSyntax() {
b4529041 171 $this->_membershipID = $this->contactMembershipCreate($this->_params);
172 $this->_membershipID2 = $this->contactMembershipCreate($this->_params);
173 $this->_membershipID3 = $this->contactMembershipCreate($this->_params);
174 $params = array(
175 'id' => array('IN' => array($this->_membershipID, $this->_membershipID3)),
176 );
177 $membership = $this->callAPISuccess('membership', 'get', $params);
178 $this->assertEquals(2, $membership['count']);
179 $this->assertEquals(array($this->_membershipID, $this->_membershipID3), array_keys($membership['values']));
180 $params = array(
181 'id' => array('NOT IN' => array($this->_membershipID, $this->_membershipID3)),
182 );
183 $membership = $this->callAPISuccess('membership', 'get', $params);
184 $this->assertEquals(1, $membership['count']);
185 $this->assertEquals(array($this->_membershipID2), array_keys($membership['values']));
b4529041 186 }
187
caca32ba 188 /**
189 * Test civicrm_membership_get with params not array.
190 * Gets treated as contact_id, memberships expected.
191 */
00be9182 192 public function testGetInSyntaxOnContactID() {
caca32ba 193 $this->_membershipID = $this->contactMembershipCreate($this->_params);
194 $contact2 = $this->individualCreate();
195 $contact3 = $this->individualCreate(array('first_name' => 'Scout', 'last_name' => 'Canine'));
196 $this->_membershipID2 = $this->contactMembershipCreate(array_merge($this->_params, array('contact_id' => $contact2)));
197 $this->_membershipID3 = $this->contactMembershipCreate(array_merge($this->_params, array('contact_id' => $contact3)));
198 $params = array(
199 'contact_id' => array('IN' => array($this->_contactID, $contact3)),
200 );
201 $membership = $this->callAPISuccess('membership', 'get', $params);
202 $this->assertEquals(2, $membership['count']);
203 $this->assertEquals(array($this->_membershipID, $this->_membershipID3), array_keys($membership['values']));
204 $params = array(
205 'contact_id' => array('NOT IN' => array($this->_contactID, $contact3)),
206 );
207 $membership = $this->callAPISuccess('membership', 'get', $params);
208 $this->assertEquals(1, $membership['count']);
209 $this->assertEquals(array($this->_membershipID2), array_keys($membership['values']));
210 }
5896d037 211
caca32ba 212 /**
213 * Test civicrm_membership_get with params not array.
214 * Gets treated as contact_id, memberships expected.
215 */
00be9182 216 public function testGetWithParamsMemberShipTypeId() {
d54576ed 217 $this->callAPISuccess($this->_entity, 'create', $this->_params);
6a488035
TO
218 $params = array(
219 'membership_type_id' => $this->_membershipTypeID,
6a488035 220 );
771f3245 221 $membership = $this->callAPISuccess('membership', 'get', $params);
d54576ed 222 $this->callAPISuccess('Membership', 'Delete', array(
6a488035 223 'id' => $membership['id'],
771f3245 224 ));
6a488035
TO
225 $result = $membership['values'][$membership['id']];
226 $this->assertEquals($result['contact_id'], $this->_contactID, "In line " . __LINE__);
227 $this->assertEquals($result['membership_type_id'], $this->_membershipTypeID, "In line " . __LINE__);
228 $this->assertEquals($result['status_id'], $this->_membershipStatusID, "In line " . __LINE__);
229 $this->assertEquals($result['join_date'], '2009-01-21', "In line " . __LINE__);
230 $this->assertEquals($result['start_date'], '2009-01-21', "In line " . __LINE__);
231 $this->assertEquals($result['end_date'], '2009-12-21', "In line " . __LINE__);
232 $this->assertEquals($result['source'], 'Payment', "In line " . __LINE__);
233 $this->assertEquals($result['is_override'], 1, "In line " . __LINE__);
234 $this->assertEquals($result['id'], $membership['id']);
235 }
5896d037 236
a73daeff
E
237 /**
238 * Test civicrm_membership_get with params not array.
239 * Gets treated as contact_id, memberships expected.
240 */
00be9182 241 public function testGetWithParamsMemberShipTypeIdContactID() {
a73daeff
E
242 $params = $this->_params;
243 $this->callAPISuccess($this->_entity, 'create', $params);
244 $params['membership_type_id'] = $this->_membershipTypeID2;
245 $this->callAPISuccess($this->_entity, 'create', $params);
246 $this->callAPISuccessGetCount('membership', array('contact_id' => $this->_contactID), 2);
247 $params = array(
248 'membership_type_id' => $this->_membershipTypeID,
249 'contact_id' => $this->_contactID,
250 );
251 $result = $this->callAPISuccess('membership', 'getsingle', $params);
252 $this->assertEquals($result['contact_id'], $this->_contactID);
253 $this->assertEquals($result['membership_type_id'], $this->_membershipTypeID);
6a488035 254
a73daeff
E
255 $params = array(
256 'membership_type_id' => $this->_membershipTypeID2,
257 'contact_id' => $this->_contactID,
258 );
259 $result = $this->callAPISuccess('membership', 'getsingle', $params);
260 $this->assertEquals($result['contact_id'], $this->_contactID);
261 $this->assertEquals($result['membership_type_id'], $this->_membershipTypeID2);
262 }
5896d037 263
6a488035 264 /**
100fef9d 265 * Check with complete array + custom field
6a488035
TO
266 * Note that the test is written on purpose without any
267 * variables specific to participant so it can be replicated into other entities
268 * and / or moved to the automated test suite
269 */
00be9182 270 public function testGetWithParamsMemberShipIdAndCustom() {
6a488035
TO
271 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
272
273 $params = $this->_params;
274 $params['custom_' . $ids['custom_field_id']] = "custom string";
275
771f3245 276 $result = $this->callAPISuccess($this->_entity, 'create', $params);
6a488035 277
771f3245 278 $getParams = array('membership_type_id' => $params['membership_type_id']);
279 $check = $this->callAPIAndDocument($this->_entity, 'get', $getParams, __FUNCTION__, __FILE__);
6a488035
TO
280 $this->assertEquals("custom string", $check['values'][$result['id']]['custom_' . $ids['custom_field_id']], ' in line ' . __LINE__);
281
d54576ed 282 $this->callAPISuccess('Membership', 'Delete', array(
6a488035 283 'id' => $result['id'],
771f3245 284 ));
6a488035
TO
285 }
286
287 /**
288 * Test civicrm_membership_get with proper params.
289 * Memberships expected.
290 */
00be9182 291 public function testGet() {
6a488035
TO
292 $membershipID = $this->contactMembershipCreate($this->_params);
293 $params = array(
294 'contact_id' => $this->_contactID,
6a488035
TO
295 );
296
771f3245 297 $membership = $this->callAPISuccess('membership', 'get', $params);
6a488035 298 $result = $membership['values'][$membershipID];
771f3245 299 $this->callAPISuccess('Membership', 'Delete', array(
6a488035 300 'id' => $membership['id'],
771f3245 301 ));
6a488035
TO
302 $this->assertEquals($result['join_date'], '2009-01-21', "In line " . __LINE__);
303 $this->assertEquals($result['contact_id'], $this->_contactID, "In line " . __LINE__);
304 $this->assertEquals($result['membership_type_id'], $this->_membershipTypeID, "In line " . __LINE__);
305 $this->assertEquals($result['status_id'], $this->_membershipStatusID, "In line " . __LINE__);
306
307 $this->assertEquals($result['start_date'], '2009-01-21', "In line " . __LINE__);
308 $this->assertEquals($result['end_date'], '2009-12-21', "In line " . __LINE__);
309 $this->assertEquals($result['source'], 'Payment', "In line " . __LINE__);
310 $this->assertEquals($result['is_override'], 1, "In line " . __LINE__);
311 }
312
313
314 /**
315 * Test civicrm_membership_get with proper params.
316 * Memberships expected.
317 */
00be9182 318 public function testGetWithId() {
6a488035
TO
319 $membershipID = $this->contactMembershipCreate($this->_params);
320 $params = array(
321 'contact_id' => $this->_contactID,
d54576ed 322 'id' => $this->_membershipID,
6a488035
TO
323 'return' => 'id',
324 );
771f3245 325 $result = $this->callAPISuccess('membership', 'get', $params);
6a488035
TO
326 $this->assertEquals($membershipID, $result['id']);
327 $params = array(
328 'contact_id' => $this->_contactID,
d54576ed 329 'membership_id' => $this->_membershipID,
6a488035
TO
330 'return' => 'membership_id',
331 );
771f3245 332 $result = $this->callAPISuccess('membership', 'get', $params);
6a488035 333 $this->assertEquals($membershipID, $result['id']);
6a488035
TO
334 }
335
336 /**
337 * Test civicrm_membership_get for only active.
338 * Memberships expected.
339 */
00be9182 340 public function testGetOnlyActive() {
5896d037 341 $description = "Demonstrates use of 'filter' active_only' param";
6a488035 342 $this->_membershipID = $this->contactMembershipCreate($this->_params);
5896d037
TO
343 $subfile = 'filterIsCurrent';
344 $params = array(
6a488035
TO
345 'contact_id' => $this->_contactID,
346 'active_only' => 1,
6a488035
TO
347 );
348
771f3245 349 $membership = $this->callAPISuccess('membership', 'get', $params);
a73daeff
E
350 $this->assertEquals($membership['values'][$this->_membershipID]['status_id'], $this->_membershipStatusID);
351 $this->assertEquals($membership['values'][$this->_membershipID]['contact_id'], $this->_contactID);
6a488035
TO
352 $params = array(
353 'contact_id' => $this->_contactID,
354 'filters' => array(
355 'is_current' => 1,
356 ),
6a488035
TO
357 );
358
771f3245 359 $membership = $this->callAPIAndDocument('membership', 'get', $params, __FUNCTION__, __FILE__, $description, $subfile);
a73daeff
E
360 $this->assertEquals($membership['values'][$this->_membershipID]['status_id'], $this->_membershipStatusID);
361 $this->assertEquals($membership['values'][$this->_membershipID]['contact_id'], $this->_contactID);
6a488035 362
6c6e6187 363 $this->callAPISuccess('Membership', 'Delete', array('id' => $this->_membershipID));
6a488035
TO
364 }
365
366 /**
367 * Test civicrm_membership_get for non exist contact.
368 * empty Memberships.
369 */
00be9182 370 public function testGetNoContactExists() {
6a488035
TO
371 $params = array(
372 'contact_id' => 55555,
6a488035
TO
373 );
374
771f3245 375 $membership = $this->callAPISuccess('membership', 'get', $params);
6a488035
TO
376 $this->assertEquals($membership['count'], 0, "In line " . __LINE__);
377 }
378
379 /**
380 * Test civicrm_membership_get with relationship.
381 * get Memberships.
382 */
00be9182 383 public function testGetWithRelationship() {
6a488035 384 $membershipOrgId = $this->organizationCreate(NULL);
e4d5f1e2 385 $memberContactId = $this->individualCreate();
6a488035
TO
386
387 $relTypeParams = array(
388 'name_a_b' => 'Relation 1',
389 'name_b_a' => 'Relation 2',
390 'description' => 'Testing relationship type',
391 'contact_type_a' => 'Organization',
392 'contact_type_b' => 'Individual',
393 'is_reserved' => 1,
394 'is_active' => 1,
6a488035
TO
395 );
396 $relTypeID = $this->relationshipTypeCreate($relTypeParams);
397
398 $params = array(
399 'name' => 'test General',
400 'duration_unit' => 'year',
401 'duration_interval' => 1,
402 'period_type' => 'rolling',
403 'member_of_contact_id' => $membershipOrgId,
404 'domain_id' => 1,
5896d037 405 'financial_type_id' => 1,
6a488035
TO
406 'relationship_type_id' => $relTypeID,
407 'relationship_direction' => 'b_a',
408 'is_active' => 1,
6a488035 409 );
771f3245 410 $memType = $this->callAPISuccess('membership_type', 'create', $params);
6a488035
TO
411
412 $params = array(
413 'contact_id' => $memberContactId,
414 'membership_type_id' => $memType['id'],
415 'join_date' => '2009-01-21',
416 'start_date' => '2009-01-21',
417 'end_date' => '2009-12-21',
418 'source' => 'Payment',
419 'is_override' => 1,
420 'status_id' => $this->_membershipStatusID,
6a488035
TO
421 );
422 $membershipID = $this->contactMembershipCreate($params);
423
424 $params = array(
425 'contact_id' => $memberContactId,
426 'membership_type_id' => $memType['id'],
6a488035
TO
427 );
428
771f3245 429 $result = $this->callAPISuccess('membership', 'get', $params);
6a488035
TO
430
431 $membership = $result['values'][$membershipID];
771f3245 432 $this->assertEquals($this->_membershipStatusID, $membership['status_id']);
d54576ed 433 $this->callAPISuccess('Membership', 'Delete', array(
6a488035 434 'id' => $membership['id'],
5896d037 435 ));
6a488035
TO
436 $this->membershipTypeDelete(array('id' => $memType['id']));
437 $this->relationshipTypeDelete($relTypeID);
438 $this->contactDelete($membershipOrgId);
439 $this->contactDelete($memberContactId);
440 }
441
4cc99d00 442 /**
443 * Test civicrm_membership_create with relationships.
444 * create/get Memberships.
445 *
446 * Test suite for CRM-14758: API ( contact, create ) does not always create related membership
447 * and max_related property for Membership_Type and Membership entities
448 */
00be9182 449 public function testCreateWithRelationship() {
4cc99d00 450 // Create membership type: inherited through employment, max_related = 2
451 $params = array(
452 'name_a_b' => 'Employee of',
453 );
454 $result = $this->callAPISuccess('relationship_type', 'get', $params);
455 $relationshipTypeId = $result['id'];
456 $membershipOrgId = $this->organizationCreate();
457 $params = array(
458 'name' => 'Corporate Membership',
459 'duration_unit' => 'year',
460 'duration_interval' => 1,
461 'period_type' => 'rolling',
462 'member_of_contact_id' => $membershipOrgId,
463 'domain_id' => 1,
464 'financial_type_id' => 1,
465 'relationship_type_id' => $relationshipTypeId,
466 'relationship_direction' => 'b_a',
467 'max_related' => 2,
468 'is_active' => 1,
469 );
470 $result = $this->callAPISuccess('membership_type', 'create', $params);
471 $membershipTypeId = $result['id'];
472
473 // Create employer and first employee
474 $employerId[0] = $this->organizationCreate(array(), 1);
475 $memberContactId[0] = $this->individualCreate(array('employer_id' => $employerId[0]), 0);
476
477 // Create organization's membership
478 $params = array(
479 'contact_id' => $employerId[0],
480 'membership_type_id' => $membershipTypeId,
481 'source' => 'Test suite',
482 'start_date' => date('Y-m-d'),
483 'end_date' => "+1 year",
484 );
485 $OrganizationMembershipID = $this->contactMembershipCreate($params);
486
487 // Check that the employee inherited the membership
488 $params = array(
489 'contact_id' => $memberContactId[0],
490 'membership_type_id' => $membershipTypeId,
491 );
492
493 $result = $this->callAPISuccess('membership', 'get', $params);
494
495 $this->assertEquals(1, $result['count']);
496 $result = $result['values'][$result['id']];
497 $this->assertEquals($OrganizationMembershipID, $result['owner_membership_id']);
498
499 // Create second employee
500 $memberContactId[1] = $this->individualCreate(array('employer_id' => $employerId[0]), 1);
501
502 // Check that the employee inherited the membership
503 $params = array(
504 'contact_id' => $memberContactId[1],
505 'membership_type_id' => $membershipTypeId,
506 );
507 $result = $this->callAPISuccess('membership', 'get', $params);
4cc99d00 508 // If it fails here CRM-14758 is not fixed
509 $this->assertEquals(1, $result['count']);
510 $result = $result['values'][$result['id']];
511 $this->assertEquals($OrganizationMembershipID, $result['owner_membership_id']);
512
513 // Create third employee
932a6904 514 $memberContactId[2] = $this->individualCreate(array('employer_id' => $employerId[0]), 2);
4cc99d00 515
516 // Check that employee does NOT inherit the membership (max_related = 2)
517 $params = array(
518 'contact_id' => $memberContactId[2],
519 'membership_type_id' => $membershipTypeId,
520 );
521 $result = $this->callAPISuccess('membership', 'get', $params);
522 $this->assertEquals(0, $result['count']);
523
524 // Increase max_related for the employer's membership
525 $params = array(
526 'id' => $OrganizationMembershipID,
527 'max_related' => 3,
528 );
529 $this->contactMembershipCreate($params);
530
531 // Check that the employee inherited the membership
532 $params = array(
533 'contact_id' => $memberContactId[2],
534 'membership_type_id' => $membershipTypeId,
535 );
536 $result = $this->callAPISuccess('membership', 'get', $params);
537 $this->assertEquals(1, $result['count']);
538 $result = $result['values'][$result['id']];
539 $this->assertEquals($OrganizationMembershipID, $result['owner_membership_id']);
540
541 // First employee moves to a new job
542 $employerId[1] = $this->organizationCreate(array(), 2);
543 $params = array(
544 'id' => $memberContactId[0],
545 'employer_id' => $employerId[1],
546 );
547 $this->callAPISuccess('contact', 'create', $params);
548
549 // Check that employee does NO LONGER inherit the membership
550 $params = array(
551 'contact_id' => $memberContactId[0],
552 'membership_type_id' => $membershipTypeId,
553 );
554 $result = $this->callAPISuccess('membership', 'get', $params);
555 $this->assertEquals(0, $result['count']);
556
557 // Tear down - reverse of creation to be safe
558 $this->contactDelete($memberContactId[2]);
559 $this->contactDelete($memberContactId[1]);
560 $this->contactDelete($memberContactId[0]);
561 $this->contactDelete($employerId[1]);
562 $this->contactDelete($employerId[0]);
563 $this->membershipTypeDelete(array('id' => $membershipTypeId));
564 $this->contactDelete($membershipOrgId);
565 }
566
37eda84b 567 /**
568 * We are checking for no enotices + only id & end_date returned
569 */
00be9182 570 public function testMembershipGetWithReturn() {
d54576ed 571 $this->contactMembershipCreate($this->_params);
37eda84b 572 $result = $this->callAPISuccess('membership', 'get', array('return' => 'end_date'));
6c6e6187 573 foreach ($result['values'] as $membership) {
37eda84b 574 $this->assertEquals(array('id', 'end_date'), array_keys($membership));
575 }
576 }
6a488035
TO
577 ///////////////// civicrm_membership_create methods
578
579 /**
580 * Test civicrm_contact_memberships_create with empty params.
581 * Error expected.
582 */
00be9182 583 public function testCreateWithEmptyParams() {
6a488035 584 $params = array();
d54576ed 585 $this->callAPIFailure('membership', 'create', $params);
6a488035
TO
586 }
587
588 /**
6a488035
TO
589 * If is_overide is passed in status must also be passed in
590 */
00be9182 591 public function testCreateOverrideNoStatus() {
6a488035
TO
592 $params = $this->_params;
593 unset($params['status_id']);
d54576ed 594 $this->callAPIFailure('membership', 'create', $params);
6a488035
TO
595 }
596
00be9182 597 public function testMembershipCreateMissingRequired() {
6a488035
TO
598 $params = array(
599 'membership_type_id' => '1',
600 'join_date' => '2006-01-21',
601 'start_date' => '2006-01-21',
602 'end_date' => '2006-12-21',
603 'source' => 'Payment',
604 'status_id' => '2',
6a488035
TO
605 );
606
d54576ed 607 $this->callAPIFailure('membership', 'create', $params);
6a488035
TO
608 }
609
00be9182 610 public function testMembershipCreate() {
6a488035
TO
611 $params = array(
612 'contact_id' => $this->_contactID,
613 'membership_type_id' => $this->_membershipTypeID,
614 'join_date' => '2006-01-21',
615 'start_date' => '2006-01-21',
616 'end_date' => '2006-12-21',
617 'source' => 'Payment',
618 'is_override' => 1,
619 'status_id' => $this->_membershipStatusID,
6a488035
TO
620 );
621
771f3245 622 $result = $this->callAPIAndDocument('membership', 'create', $params, __FUNCTION__, __FILE__);
6a488035 623 $this->getAndCheck($params, $result['id'], $this->_entity);
6a488035
TO
624 $this->assertNotNull($result['id']);
625 $this->assertEquals($this->_contactID, $result['values'][$result['id']]['contact_id'], " in line " . __LINE__);
626 $this->assertEquals($result['id'], $result['values'][$result['id']]['id'], " in line " . __LINE__);
627 }
5896d037 628
28a04ea9 629 /**
630 * Check for useful message if contact doesn't exist
631 */
00be9182 632 public function testMembershipCreateWithInvalidContact() {
6a488035
TO
633 $params = array(
634 'contact_id' => 999,
635 'membership_type_id' => $this->_membershipTypeID,
636 'join_date' => '2006-01-21',
637 'start_date' => '2006-01-21',
638 'end_date' => '2006-12-21',
639 'source' => 'Payment',
640 'is_override' => 1,
641 'status_id' => $this->_membershipStatusID,
6a488035
TO
642 );
643
d54576ed 644 $this->callAPIFailure('membership', 'create', $params,
771f3245 645 'contact_id is not valid : 999'
646 );
6a488035 647 }
5896d037 648
00be9182 649 public function testMembershipCreateWithInvalidStatus() {
6a488035
TO
650 $params = $this->_params;
651 $params['status_id'] = 999;
d54576ed 652 $this->callAPIFailure('membership', 'create', $params,
771f3245 653 "'999' is not a valid option for field status_id"
654 );
6a488035
TO
655 }
656
00be9182 657 public function testMembershipCreateWithInvalidType() {
6a488035
TO
658 $params = $this->_params;
659 $params['membership_type_id'] = 999;
660
d54576ed 661 $this->callAPIFailure('membership', 'create', $params,
771f3245 662 "'999' is not a valid option for field membership_type_id"
663 );
6a488035
TO
664 }
665
666 /**
100fef9d 667 * Check with complete array + custom field
6a488035
TO
668 * Note that the test is written on purpose without any
669 * variables specific to participant so it can be replicated into other entities
670 * and / or moved to the automated test suite
671 */
00be9182 672 public function testCreateWithCustom() {
6a488035
TO
673 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
674
675 $params = $this->_params;
676 $params['custom_' . $ids['custom_field_id']] = "custom string";
677
771f3245 678 $result = $this->callAPIAndDocument($this->_entity, 'create', $params, __FUNCTION__, __FILE__);
5896d037
TO
679 $check = $this->callAPISuccess($this->_entity, 'get', array(
680 'id' => $result['id'],
21dfd5f5 681 'contact_id' => $this->_contactID,
5896d037 682 ));
6a488035 683 $this->assertEquals("custom string", $check['values'][$result['id']]['custom_' . $ids['custom_field_id']], ' in line ' . __LINE__);
6a488035
TO
684 }
685
686 /**
687 * Test civicrm_contact_memberships_create with membership id (edit
688 * membership).
689 * success expected.
690 */
00be9182 691 public function testMembershipCreateWithId() {
6a488035
TO
692 $membershipID = $this->contactMembershipCreate($this->_params);
693 $params = array(
694 'id' => $membershipID,
695 'contact_id' => $this->_contactID,
696 'membership_type_id' => $this->_membershipTypeID,
697 'join_date' => '2006-01-21',
698 'start_date' => '2006-01-21',
699 'end_date' => '2006-12-21',
700 'source' => 'Payment',
701 'is_override' => 1,
702 'status_id' => $this->_membershipStatusID,
6a488035
TO
703 );
704
771f3245 705 $result = $this->callAPISuccess('membership', 'create', $params);
706 $this->callAPISuccess('Membership', 'Delete', array(
6a488035 707 'id' => $result['id'],
771f3245 708 ));
6a488035
TO
709 $this->assertEquals($result['id'], $membershipID, "in line " . __LINE__);
710 }
711
712 /**
713 * Test civicrm_contact_memberships_create with membership id (edit
714 * membership).
715 * success expected.
716 */
00be9182 717 public function testMembershipCreateUpdateWithIdNoContact() {
6a488035
TO
718 $membershipID = $this->contactMembershipCreate($this->_params);
719 $params = array(
720 'id' => $membershipID,
721 'membership_type_id' => $this->_membershipTypeID,
722 'contact_id' => $this->_contactID,
723 'join_date' => '2006-01-21',
724 'start_date' => '2006-01-21',
725 'end_date' => '2006-12-21',
726 'source' => 'Payment',
727 'is_override' => 1,
728 'status_id' => $this->_membershipStatusID,
6a488035
TO
729 );
730
771f3245 731 $result = $this->callAPISuccess('membership', 'create', $params);
732 $this->callAPISuccess('Membership', 'Delete', array(
6a488035 733 'id' => $result['id'],
5896d037 734 ));
771f3245 735
6a488035
TO
736 $this->assertEquals($result['id'], $membershipID, "in line " . __LINE__);
737 }
738
739 /**
740 * Test civicrm_contact_memberships_create with membership id (edit
741 * membership).
742 * success expected.
743 */
00be9182 744 public function testMembershipCreateUpdateWithIdNoDates() {
6a488035
TO
745 $membershipID = $this->contactMembershipCreate($this->_params);
746 $params = array(
747 'id' => $membershipID,
748 'contact_id' => $this->_contactID,
749 'membership_type_id' => $this->_membershipTypeID,
750 'source' => 'Payment',
751 'is_override' => 1,
752 'status_id' => $this->_membershipStatusID,
6a488035
TO
753 );
754
771f3245 755 $result = $this->callAPISuccess('membership', 'create', $params);
756 $this->callAPISuccess('Membership', 'Delete', array(
6a488035 757 'id' => $result['id'],
5896d037 758 ));
6a488035
TO
759 $this->assertEquals($result['id'], $membershipID, "in line " . __LINE__);
760 }
761
762 /**
763 * Test civicrm_contact_memberships_create with membership id (edit
764 * membership).
765 * success expected.
766 */
00be9182 767 public function testMembershipCreateUpdateWithIdNoDatesNoType() {
6a488035
TO
768 $membershipID = $this->contactMembershipCreate($this->_params);
769 $params = array(
770 'id' => $membershipID,
771 'source' => 'not much here',
772 'contact_id' => $this->_contactID,
773 'is_override' => 1,
774 'status_id' => $this->_membershipStatusID,
6a488035
TO
775 );
776
771f3245 777 $result = $this->callAPISuccess('membership', 'create', $params);
778 $this->callAPISuccess('Membership', 'Delete', array(
6a488035 779 'id' => $result['id'],
771f3245 780 ));
6a488035
TO
781 $this->assertEquals($result['id'], $membershipID, "in line " . __LINE__);
782 }
783
784 /**
785 * Test civicrm_contact_memberships_create with membership id (edit
786 * membership).
787 * success expected.
788 */
00be9182 789 public function testMembershipCreateUpdateWithIDAndSource() {
6a488035
TO
790 $membershipID = $this->contactMembershipCreate($this->_params);
791 $params = array(
792 'id' => $membershipID,
793 'source' => 'changed',
794 'contact_id' => $this->_contactID,
6c6e6187 795 'status_id' => $this->_membershipStatusID,
5896d037 796 'membership_type_id' => $this->_membershipTypeID,
6a488035
TO
797 'skipStatusCal' => 1,
798 );
771f3245 799 $result = $this->callAPISuccess('membership', 'create', $params);
6a488035 800 $this->assertEquals($result['id'], $membershipID, "in line " . __LINE__);
771f3245 801 $this->callAPISuccess('Membership', 'Delete', array(
6a488035 802 'id' => $result['id'],
5896d037 803 ));
6a488035
TO
804 }
805
806 /**
100fef9d 807 * Change custom field using update
6a488035 808 */
00be9182 809 public function testUpdateWithCustom() {
6a488035
TO
810 $ids = $this->entityCustomGroupWithSingleFieldCreate(__FUNCTION__, __FILE__);
811
812 $params = $this->_params;
813 $params['custom_' . $ids['custom_field_id']] = "custom string";
771f3245 814 $result = $this->callAPIAndDocument($this->_entity, 'create', $params, __FUNCTION__, __FILE__);
5896d037
TO
815 $result = $this->callAPISuccess($this->_entity, 'create', array(
816 'id' => $result['id'],
21dfd5f5 817 'custom_' . $ids['custom_field_id'] => "new custom",
5896d037
TO
818 ));
819 $check = $this->callAPISuccess($this->_entity, 'get', array(
820 'id' => $result['id'],
21dfd5f5 821 'contact_id' => $this->_contactID,
5896d037 822 ));
6a488035
TO
823
824 $this->assertEquals("new custom", $check['values'][$result['id']]['custom_' . $ids['custom_field_id']], ' in line ' . __LINE__);
d54576ed 825 $this->callAPISuccess('Membership', 'Delete', array(
6a488035 826 'id' => $check['id'],
5896d037 827 ));
6a488035
TO
828
829 $this->customFieldDelete($ids['custom_field_id']);
830 $this->customGroupDelete($ids['custom_group_id']);
831 }
832
93c482a4
EM
833 /**
834 * per CRM-15746 check that the id can be altered in an update hook
835 */
28a04ea9 836 public function testMembershipUpdateCreateHookCRM15746() {
93c482a4
EM
837 $this->hookClass->setHook('civicrm_pre', array($this, 'hook_civicrm_pre_update_create_membership'));
838 $result = $this->callAPISuccess('membership', 'create', $this->_params);
839 $this->callAPISuccess('membership', 'create', array('id' => $result['id'], 'end_date' => '1 year ago'));
840 $this->callAPISuccessGetCount('membership', array(), 2);
841 $this->hookClass->reset();
842 $this->callAPISuccess('membership', 'create', array('id' => $result['id'], 'end_date' => '1 year ago'));
843 $this->callAPISuccessGetCount('membership', array(), 2);
844 }
845
2ea0abec
EM
846 /**
847 * Custom hook for update membership.
848 *
849 * @param string $op
850 * @param object $objectName
851 * @param int $id
852 * @param array $params
853 *
854 * @throws \Exception
855 */
28a04ea9 856 public function hook_civicrm_pre_update_create_membership($op, $objectName, $id, &$params) {
93c482a4
EM
857 if ($objectName == 'Membership' && $op == 'edit') {
858 $existingMembership = $this->callAPISuccessGetSingle('membership', array('id' => $params['id']));
859 unset($params['id'], $params['membership_id']);
6c6e6187 860 $params['join_date'] = $params['membership_start_date'] = $params['start_date'] = date('Ymd000000', strtotime($existingMembership['start_date']));
93c482a4
EM
861 $params = array_merge($existingMembership, $params);
862 $params['id'] = NULL;
863 }
864 }
865
6a488035
TO
866 /**
867 * Test civicrm_contact_memberships_create Invalid membership data
868 * Error expected.
869 */
00be9182 870 public function testMembershipCreateInvalidMemData() {
6a488035
TO
871 //membership_contact_id as string
872 $params = array(
873 'membership_contact_id' => 'Invalid',
874 'membership_type_id' => $this->_membershipTypeID,
875 'join_date' => '2011-01-21',
876 'start_date' => '2010-01-21',
877 'end_date' => '2008-12-21',
878 'source' => 'Payment',
879 'is_override' => 1,
5896d037
TO
880 'status_id' => $this->_membershipStatusID,
881 );
6a488035 882
d54576ed 883 $this->callAPIFailure('membership', 'create', $params);
6a488035
TO
884
885 //membership_contact_id which is no in contact table
886 $params['membership_contact_id'] = 999;
d54576ed 887 $this->callAPIFailure('membership', 'create', $params);
6a488035
TO
888
889 //invalid join date
890 unset($params['membership_contact_id']);
891 $params['join_date'] = "invalid";
d54576ed 892 $this->callAPIFailure('Membership', 'Create', $params);
6a488035
TO
893 }
894
895 /**
896 * Test civicrm_contact_memberships_create with membership_contact_id
897 * membership).
898 * Success expected.
899 */
00be9182 900 public function testMembershipCreateWithMemContact() {
6a488035
TO
901 $params = array(
902 'membership_contact_id' => $this->_contactID,
903 'membership_type_id' => $this->_membershipTypeID,
904 'join_date' => '2011-01-21',
905 'start_date' => '2010-01-21',
906 'end_date' => '2008-12-21',
907 'source' => 'Payment',
908 'is_override' => 1,
909 'status_id' => $this->_membershipStatusID,
6a488035
TO
910 );
911
771f3245 912 $result = $this->callAPISuccess('membership', 'create', $params);
6a488035 913
d54576ed 914 $this->callAPISuccess('Membership', 'Delete', array(
6a488035 915 'id' => $result['id'],
771f3245 916 ));
6a488035 917 }
5896d037 918
cc73900e 919 /**
920 * Test civicrm_contact_memberships_create with membership_contact_id
921 * membership).
922 * Success expected.
923 */
00be9182 924 public function testMembershipCreateValidMembershipTypeString() {
cc73900e 925 $params = array(
926 'membership_contact_id' => $this->_contactID,
927 'membership_type_id' => 'General',
928 'join_date' => '2011-01-21',
929 'start_date' => '2010-01-21',
930 'end_date' => '2008-12-21',
931 'source' => 'Payment',
932 'is_override' => 1,
933 'status_id' => $this->_membershipStatusID,
934 );
935
936 $result = $this->callAPISuccess('membership', 'create', $params);
937 $this->assertEquals($this->_membershipTypeID, $result['values'][$result['id']]['membership_type_id']);
d54576ed 938 $this->callAPISuccess('Membership', 'Delete', array(
cc73900e 939 'id' => $result['id'],
940 ));
941 }
942
943 /**
944 * Test civicrm_contact_memberships_create with membership_contact_id
945 * membership).
946 * Success expected.
947 */
00be9182 948 public function testMembershipCreateInValidMembershipTypeString() {
cc73900e 949 $params = array(
950 'membership_contact_id' => $this->_contactID,
951 'membership_type_id' => 'invalid',
952 'join_date' => '2011-01-21',
953 'start_date' => '2010-01-21',
954 'end_date' => '2008-12-21',
955 'source' => 'Payment',
956 'is_override' => 1,
957 'status_id' => $this->_membershipStatusID,
958 );
959
d54576ed 960 $this->callAPIFailure('membership', 'create', $params);
cc73900e 961 }
6a488035 962
cc73900e 963 /**
8c33a68c 964 * Test that if membership join date is not set it defaults to today
cc73900e 965 */
00be9182 966 public function testEmptyJoinDate() {
8c33a68c 967 unset($this->_params['join_date'], $this->_params['is_override']);
968 $result = $this->callAPISuccess($this->_entity, 'create', $this->_params);
969 $result = $this->callAPISuccess($this->_entity, 'getsingle', array('id' => $result['id']));
970 $this->assertEquals(date('Y-m-d', strtotime('now')), $result['join_date']);
971 $this->assertEquals('2009-01-21', $result['start_date']);
972 $this->assertEquals('2009-12-21', $result['end_date']);
cc73900e 973 }
5896d037 974
cc73900e 975 /**
8c33a68c 976 * Test that if membership start date is not set it defaults to correct end date
977 * - fixed
cc73900e 978 */
00be9182 979 public function testEmptyStartDateFixed() {
8c33a68c 980 unset($this->_params['start_date'], $this->_params['is_override']);
981 $this->_params['membership_type_id'] = $this->_membershipTypeID2;
982 $result = $this->callAPISuccess($this->_entity, 'create', $this->_params);
983 $result = $this->callAPISuccess($this->_entity, 'getsingle', array('id' => $result['id']));
984 $this->assertEquals('2009-01-21', $result['join_date']);
985 $this->assertEquals('2008-03-01', $result['start_date']);
986 $this->assertEquals('2009-12-21', $result['end_date']);
987 }
cc73900e 988
8c33a68c 989 /**
990 * Test that if membership start date is not set it defaults to correct end date
991 * - fixed
992 */
2ea0abec
EM
993 public function testEmptyStartEndDateFixedOneYear() {
994 unset($this->_params['start_date'], $this->_params['is_override'], $this->_params['end_date']);
995 $this->callAPISuccess('membership_type', 'create', array('id' => $this->_membershipTypeID2, 'duration_interval' => 1));
996 $this->_params['membership_type_id'] = $this->_membershipTypeID2;
997 $result = $this->callAPISuccess($this->_entity, 'create', $this->_params);
998 $result = $this->callAPISuccess($this->_entity, 'getsingle', array('id' => $result['id']));
999 $this->assertEquals('2009-01-21', $result['join_date']);
1000 $this->assertEquals('2008-03-01', $result['start_date']);
1001 $this->assertEquals('2010-02-28', $result['end_date']);
1002 }
1003
1004 /**
1005 * Test that if membership start date is not set it defaults to correct end date for rolling memberships.
1006 */
00be9182 1007 public function testEmptyStartDateRolling() {
8c33a68c 1008 unset($this->_params['start_date'], $this->_params['is_override']);
1009 $result = $this->callAPISuccess($this->_entity, 'create', $this->_params);
1010 $result = $this->callAPISuccess($this->_entity, 'getsingle', array('id' => $result['id']));
1011 $this->assertEquals('2009-01-21', $result['join_date']);
1012 $this->assertEquals('2009-01-21', $result['start_date']);
1013 $this->assertEquals('2009-12-21', $result['end_date']);
cc73900e 1014 }
5896d037 1015
8c33a68c 1016 /**
1017 * Test that if membership end date is not set it defaults to correct end date
1018 * - rolling
1019 */
00be9182 1020 public function testEmptyEndDateFixed() {
8c33a68c 1021 unset($this->_params['start_date'], $this->_params['is_override'], $this->_params['end_date']);
1022 $this->_params['membership_type_id'] = $this->_membershipTypeID2;
1023 $result = $this->callAPISuccess($this->_entity, 'create', $this->_params);
1024 $result = $this->callAPISuccess($this->_entity, 'getsingle', array('id' => $result['id']));
1025 $this->assertEquals('2009-01-21', $result['join_date']);
1026 $this->assertEquals('2008-03-01', $result['start_date']);
1027 $this->assertEquals('2010-02-28', $result['end_date']);
1028 }
5896d037 1029
8c33a68c 1030 /**
1031 * Test that if membership end date is not set it defaults to correct end date
1032 * - rolling
1033 */
00be9182 1034 public function testEmptyEndDateRolling() {
8c33a68c 1035 unset($this->_params['is_override'], $this->_params['end_date']);
1036 $this->_params['membership_type_id'] = $this->_membershipTypeID;
1037 $result = $this->callAPISuccess($this->_entity, 'create', $this->_params);
1038 $result = $this->callAPISuccess($this->_entity, 'getsingle', array('id' => $result['id']));
1039 $this->assertEquals('2009-01-21', $result['join_date']);
1040 $this->assertEquals('2009-01-21', $result['start_date']);
1041 $this->assertEquals('2010-01-20', $result['end_date']);
1042 }
1043
1044
1045 /**
452b9e04 1046 * Test that if dates are set they not over-ridden if id is passed in
8c33a68c 1047 */
6c6e6187 1048 public function testMembershipDatesNotOverridden() {
8c33a68c 1049 $result = $this->callAPISuccess($this->_entity, 'create', $this->_params);
1050 unset($this->_params['end_date'], $this->_params['start_date']);
1051 $this->_params['id'] = $result['id'];
1052 $this->callAPISuccess($this->_entity, 'create', $this->_params);
1053 $result = $this->callAPISuccess($this->_entity, 'getsingle', array('id' => $result['id']));
1054 $this->assertEquals('2009-01-21', $result['join_date']);
1055 $this->assertEquals('2009-01-21', $result['start_date']);
1056 $this->assertEquals('2009-12-21', $result['end_date']);
1057
6c6e6187 1058 }
96025800 1059
6a488035 1060}