/**
  * @return string content
  * @param EmailMessage object $emailMessage
  * @param User object $user
  */
 public static function renderEmailMessageToMatchContent(EmailMessage $emailMessage, $user)
 {
     $userCanAccessContacts = RightsUtil::canUserAccessModule('ContactsModule', $user);
     $userCanAccessLeads = RightsUtil::canUserAccessModule('LeadsModule', $user);
     $userCanCreateContact = RightsUtil::doesUserHaveAllowByRightName('ContactsModule', ContactsModule::getCreateRight(), $user);
     $userCanCreateLead = RightsUtil::doesUserHaveAllowByRightName('LeadsModule', LeadsModule::getCreateRight(), $user);
     if ($userCanAccessLeads && $userCanAccessContacts) {
         $selectForm = new AnyContactSelectForm();
     } elseif (!$userCanAccessLeads && $userCanAccessContacts) {
         $selectForm = new ContactSelectForm();
     } else {
         $selectForm = new LeadSelectForm();
     }
     if ($userCanCreateContact && $userCanCreateLead) {
         $gridSize = 3;
     } elseif ($userCanCreateContact || $userCanCreateLead) {
         $gridSize = 2;
     } else {
         $gridSize = 1;
     }
     $contact = new Contact();
     self::resolveEmailAddressAndNameToContact($emailMessage, $contact);
     $view = new ArchivedEmailMatchingView('default', 'emailMessages', $emailMessage, $contact, $selectForm, $userCanAccessLeads, $userCanAccessContacts, $userCanCreateContact, $userCanCreateLead, $gridSize);
     return $view->render();
 }
 public function testArePermissionsFlushedOnRemovingParentFromChildRole()
 {
     Contact::deleteAll();
     try {
         $role = Role::getByName('Parent');
         $role->delete();
     } catch (NotFoundException $e) {
     }
     try {
         $user = User::getByUsername('jim');
         $user->delete();
     } catch (NotFoundException $e) {
     }
     try {
         $user = User::getByUsername('jane');
         $user->delete();
     } catch (NotFoundException $e) {
     }
     // we could have used helpers to do a lot of the following stuff (such as creating users, roles,
     // etc) but we wanted to mimic user's interaction as closely as possible. Hence using walkthroughs
     // for everything
     // create Parent and Child Roles, Create Jim to be member of Child role
     // create parent role
     $this->resetGetArray();
     $this->setPostArray(array('Role' => array('name' => 'Parent')));
     $this->runControllerWithRedirectExceptionAndGetUrl('/zurmo/role/create');
     $parentRole = Role::getByName('Parent');
     $this->assertNotNull($parentRole);
     $this->assertEquals('Parent', strval($parentRole));
     $parentRoleId = $parentRole->id;
     // create child role
     $this->resetGetArray();
     $this->setPostArray(array('Role' => array('name' => 'Child', 'role' => array('id' => $parentRoleId))));
     $this->runControllerWithRedirectExceptionAndGetUrl('/zurmo/role/create');
     $childRole = Role::getByName('Child');
     $this->assertNotNull($childRole);
     $this->assertEquals('Child', strval($childRole));
     $parentRole->forgetAll();
     $parentRole = Role::getById($parentRoleId);
     $childRoleId = $childRole->id;
     $childRole->forgetAll();
     $childRole = Role::getById($childRoleId);
     $this->assertEquals($childRole->id, $parentRole->roles[0]->id);
     // create jim's user
     $this->resetGetArray();
     $this->setPostArray(array('UserPasswordForm' => array('firstName' => 'Some', 'lastName' => 'Body', 'username' => 'jim', 'newPassword' => 'myPassword123', 'newPassword_repeat' => 'myPassword123', 'officePhone' => '456765421', 'userStatus' => 'Active', 'role' => array('id' => $childRoleId))));
     $this->runControllerWithRedirectExceptionAndGetContent('/users/default/create');
     $jim = User::getByUsername('jim');
     $this->assertNotNull($jim);
     $childRole->forgetAll();
     $childRole = Role::getById($childRoleId);
     $this->assertEquals($childRole->id, $jim->role->id);
     // give jim rights to contact's module
     $jim->setRight('ContactsModule', ContactsModule::getAccessRight());
     $jim->setRight('ContactsModule', ContactsModule::getCreateRight());
     $this->assertTrue($jim->save());
     $jim->forgetAll();
     $jim = User::getByUsername('jim');
     // create jane's user
     $this->resetGetArray();
     $this->setPostArray(array('UserPasswordForm' => array('firstName' => 'Some', 'lastName' => 'Body', 'username' => 'jane', 'newPassword' => 'myPassword123', 'newPassword_repeat' => 'myPassword123', 'officePhone' => '456765421', 'userStatus' => 'Active', 'role' => array('id' => $parentRoleId))));
     $this->runControllerWithRedirectExceptionAndGetContent('/users/default/create');
     $jane = User::getByUsername('jane');
     $this->assertNotNull($jane);
     $parentRole->forgetAll();
     $parentRole = Role::getById($parentRoleId);
     $this->assertEquals($parentRole->id, $jane->role->id);
     // give jane rights to contact's module, we need to do this because once the link between parent and child
     // role is broken jane won't be able to access the listview of contacts
     $jane->setRight('ContactsModule', ContactsModule::getAccessRight());
     $this->assertTrue($jane->save());
     $jane->forgetAll();
     $jane = User::getByUsername('jane');
     // create a contact from jim's account
     // create ContactStates
     ContactsModule::loadStartingData();
     // ensure contact states have been created
     $this->assertEquals(6, count(ContactState::GetAll()));
     $this->logoutCurrentUserLoginNewUserAndGetByUsername('jim');
     // go ahead and create contact with parent role given readwrite.
     $startingState = ContactsUtil::getStartingState();
     $this->resetGetArray();
     $this->setPostArray(array('Contact' => array('firstName' => 'Jim', 'lastName' => 'Doe', 'officePhone' => '456765421', 'state' => array('id' => $startingState->id))));
     $url = $this->runControllerWithRedirectExceptionAndGetUrl('/contacts/default/create');
     $jimDoeContactId = intval(substr($url, strpos($url, 'id=') + 3));
     $jimDoeContact = Contact::getById($jimDoeContactId);
     $this->assertNotNull($jimDoeContact);
     $this->resetPostArray();
     $this->setGetArray(array('id' => $jimDoeContactId));
     $content = $this->runControllerWithNoExceptionsAndGetContent('/contacts/default/details');
     $this->assertContains('Who can read and write Owner', $content);
     // create a contact using jane which she would see at all times
     $this->logoutCurrentUserLoginNewUserAndGetByUsername('jane');
     $this->resetGetArray();
     $this->setPostArray(array('Contact' => array('firstName' => 'Jane', 'lastName' => 'Doe', 'officePhone' => '456765421', 'state' => array('id' => $startingState->id))));
     $url = $this->runControllerWithRedirectExceptionAndGetUrl('/contacts/default/create');
     $janeDoeContactId = intval(substr($url, strpos($url, 'id=') + 3));
     $janeDoeContact = Contact::getById($jimDoeContactId);
     $this->assertNotNull($janeDoeContact);
     $this->resetPostArray();
     $this->setGetArray(array('id' => $janeDoeContactId));
     $content = $this->runControllerWithNoExceptionsAndGetContent('/contacts/default/details');
     $this->assertContains('Who can read and write Owner', $content);
     // ensure jim can see that contact everywhere
     // jim should have access to see contact on list view
     $this->logoutCurrentUserLoginNewUserAndGetByUsername('jim');
     $this->resetGetArray();
     // get the page, ensure the name of contact does show up there.
     $content = $this->runControllerWithNoExceptionsAndGetContent('/contacts/default');
     $this->assertContains('Jim Doe</a></td><td>', $content);
     $this->assertNotContains('Jane Doe</a></td><td>', $content);
     // jim should have access to jimDoeContact's detail view
     $this->setGetArray(array('id' => $jimDoeContactId));
     $this->runControllerWithNoExceptionsAndGetContent('/contacts/default/details');
     // jim should have access to jimDoeContact's edit view
     $this->runControllerWithNoExceptionsAndGetContent('/contacts/default/edit');
     // jim should not have access to janeDoeContact's detail view
     $this->setGetArray(array('id' => $janeDoeContactId));
     try {
         $this->runControllerWithNoExceptionsAndGetContent('/contacts/default/details');
         $this->fail('Accessing details action should have thrown ExitException');
     } catch (ExitException $e) {
         // just cleanup buffer
         $this->endAndGetOutputBuffer();
     }
     // jim should have access to janeDoeContact's edit view
     try {
         $this->runControllerWithNoExceptionsAndGetContent('/contacts/default/edit');
         $this->fail('Accessing edit action should have thrown ExitException');
     } catch (ExitException $e) {
         // just cleanup buffer
         $this->endAndGetOutputBuffer();
     }
     // ensure jane can see that contact everywhere
     // jane should have access to see contact on list view
     $this->logoutCurrentUserLoginNewUserAndGetByUsername('jane');
     $this->resetGetArray();
     // get the page, ensure the name of contact does show up there.
     $content = $this->runControllerWithNoExceptionsAndGetContent('/contacts/default');
     $this->assertContains('Jim Doe</a></td><td>', $content);
     $this->assertContains('Jane Doe</a></td><td>', $content);
     // jane should have access to jimDoeContact's detail view
     $this->setGetArray(array('id' => $jimDoeContactId));
     $this->runControllerWithNoExceptionsAndGetContent('/contacts/default/details');
     // jane should have access to jimDoeContact's edit view
     $this->runControllerWithNoExceptionsAndGetContent('/contacts/default/edit');
     // jane should have access to janeDoeContact's detail view
     $this->setGetArray(array('id' => $janeDoeContactId));
     $this->runControllerWithNoExceptionsAndGetContent('/contacts/default/details');
     // jane should have access to janeDoeContact's edit view
     $this->runControllerWithNoExceptionsAndGetContent('/contacts/default/edit');
     // unlink Parent role from child
     $this->logoutCurrentUserLoginNewUserAndGetByUsername('super');
     $this->setGetArray(array('id' => $childRoleId));
     $this->setPostArray(array('Role' => array('name' => 'Child', 'role' => array('id' => ''))));
     $this->runControllerWithRedirectExceptionAndGetUrl('/zurmo/role/edit');
     $childRole = Role::getByName('Child');
     $this->assertNotNull($childRole);
     $this->assertEquals('Child', strval($childRole));
     $parentRole->forgetAll();
     $parentRole = Role::getById($parentRoleId);
     $this->assertNotNull($parentRole);
     $this->assertCount(0, $parentRole->roles);
     // ensure jim can still see that contact everywhere
     // jim should have access to see contact on list view
     $this->logoutCurrentUserLoginNewUserAndGetByUsername('jim');
     $this->resetGetArray();
     // get the page, ensure the name of contact does show up there.
     $content = $this->runControllerWithNoExceptionsAndGetContent('/contacts/default');
     $this->assertContains('Jim Doe</a></td><td>', $content);
     $this->assertNotContains('Jane Doe</a></td><td>', $content);
     // jim should have access to jimDoeContact's detail view
     $this->setGetArray(array('id' => $jimDoeContactId));
     $this->runControllerWithNoExceptionsAndGetContent('/contacts/default/details');
     // jim should have access to jimDoeContact's edit view
     $this->runControllerWithNoExceptionsAndGetContent('/contacts/default/edit');
     // jim should not have access to janeDoeContact's detail view
     $this->setGetArray(array('id' => $janeDoeContactId));
     try {
         $this->runControllerWithNoExceptionsAndGetContent('/contacts/default/details');
         $this->fail('Accessing details action should have thrown ExitException');
     } catch (ExitException $e) {
         // just cleanup buffer
         $this->endAndGetOutputBuffer();
     }
     // jim should have access to janeDoeContact's edit view
     try {
         $this->runControllerWithNoExceptionsAndGetContent('/contacts/default/edit');
         $this->fail('Accessing edit action should have thrown ExitException');
     } catch (ExitException $e) {
         // just cleanup buffer
         $this->endAndGetOutputBuffer();
     }
     // ensure jane can not see that contact anywhere
     // jane should have access to see contact on list view
     $this->logoutCurrentUserLoginNewUserAndGetByUsername('jane');
     $this->resetGetArray();
     // get the page, ensure the name of contact does not show up there.
     $content = $this->runControllerWithNoExceptionsAndGetContent('/contacts/default');
     $this->assertNotContains('Jim Doe</a></td><td>', $content);
     $this->assertContains('Jane Doe</a></td><td>', $content);
     // jane should have access to janeDoeContact's detail view
     $this->setGetArray(array('id' => $janeDoeContactId));
     $this->runControllerWithNoExceptionsAndGetContent('/contacts/default/details');
     // jane should have access to janeDoeContact's edit view
     $this->runControllerWithNoExceptionsAndGetContent('/contacts/default/edit');
     // jane should not have access to jimDoeContact's detail view
     $this->setGetArray(array('id' => $jimDoeContactId));
     try {
         $this->runControllerWithNoExceptionsAndGetContent('/contacts/default/details');
         $this->fail('Accessing details action should have thrown ExitException');
     } catch (ExitException $e) {
         // just cleanup buffer
         $this->endAndGetOutputBuffer();
     }
     // jane should not have access to jimDoeContact's edit view
     try {
         $this->runControllerWithNoExceptionsAndGetContent('/contacts/default/edit');
         $this->fail('Accessing edit action should have thrown ExitException');
     } catch (ExitException $e) {
         // just cleanup buffer
         $this->endAndGetOutputBuffer();
     }
 }
 public function resolveRecordSharingPerformanceTime($count)
 {
     $groupMembers = array();
     // create group
     $this->resetGetArray();
     $this->setPostArray(array('Group' => array('name' => "Group {$count}")));
     $this->runControllerWithRedirectExceptionAndGetUrl('/zurmo/group/create');
     $group = Group::getByName("Group {$count}");
     $this->assertNotNull($group);
     $this->assertEquals("Group {$count}", strval($group));
     $group->setRight('ContactsModule', ContactsModule::getAccessRight());
     $group->setRight('ContactsModule', ContactsModule::getCreateRight());
     $group->setRight('ContactsModule', ContactsModule::getDeleteRight());
     $this->assertTrue($group->save());
     $groupId = $group->id;
     $group->forgetAll();
     $group = Group::getById($groupId);
     $this->resetGetArray();
     for ($i = 0; $i < $count; $i++) {
         $username = static::$baseUsername . "_{$i}_of_{$count}";
         // Populate group
         $this->setPostArray(array('UserPasswordForm' => array('firstName' => 'Some', 'lastName' => 'Body', 'username' => $username, 'newPassword' => 'myPassword123', 'newPassword_repeat' => 'myPassword123', 'officePhone' => '456765421', 'userStatus' => 'Active')));
         $this->runControllerWithRedirectExceptionAndGetContent('/users/default/create');
         $user = User::getByUsername($username);
         $this->assertNotNull($user);
         $groupMembers['usernames'][] = $user->username;
         $groupMembers['ids'][] = $user->id;
     }
     $this->assertCount($count, $groupMembers['ids']);
     // set user's group
     $this->setGetArray(array('id' => $groupId));
     $this->setPostArray(array('GroupUserMembershipForm' => array('userMembershipData' => $groupMembers['ids'])));
     $this->runControllerWithRedirectExceptionAndGetUrl('/zurmo/group/editUserMembership');
     $group->forgetAll();
     $group = Group::getById($groupId);
     $this->assertCount($count, $group->users);
     foreach ($groupMembers['ids'] as $userId) {
         $user = User::getById($userId);
         $this->assertEquals($group->id, $user->groups[0]->id);
         $this->assertTrue(RightsUtil::doesUserHaveAllowByRightName('ContactsModule', ContactsModule::getAccessRight(), $user));
         $this->assertTrue(RightsUtil::doesUserHaveAllowByRightName('ContactsModule', ContactsModule::getCreateRight(), $user));
         $this->assertTrue(RightsUtil::doesUserHaveAllowByRightName('ContactsModule', ContactsModule::getDeleteRight(), $user));
     }
     $this->clearAllCaches();
     // go ahead and create contact with group given readwrite, use group's first member to confirm he has create access
     $this->logoutCurrentUserLoginNewUserAndGetByUsername($groupMembers['usernames'][0]);
     $this->resetGetArray();
     $startingState = ContactsUtil::getStartingState();
     $this->setPostArray(array('Contact' => array('firstName' => 'John', 'lastName' => 'Doe', 'officePhone' => '456765421', 'state' => array('id' => $startingState->id), 'explicitReadWriteModelPermissions' => array('type' => ExplicitReadWriteModelPermissionsUtil::MIXED_TYPE_NONEVERYONE_GROUP, 'nonEveryoneGroup' => $groupId))));
     $startTime = microtime(true);
     $url = $this->runControllerWithRedirectExceptionAndGetUrl('/contacts/default/create');
     $timeTakenForSave = microtime(true) - $startTime;
     $johnDoeContactId = intval(substr($url, strpos($url, 'id=') + 3));
     $johnDoeContact = Contact::getById($johnDoeContactId);
     $this->assertNotNull($johnDoeContact);
     $this->resetPostArray();
     $this->setGetArray(array('id' => $johnDoeContactId));
     $content = $this->runControllerWithNoExceptionsAndGetContent('/contacts/default/details');
     $this->assertContains('Who can read and write ' . strval($group), $content);
     $this->clearAllCaches();
     $this->resetPostArray();
     // ensure group members have access
     foreach ($groupMembers['usernames'] as $member) {
         $user = $this->logoutCurrentUserLoginNewUserAndGetByUsername($member);
         $this->assertNotNull($user);
         $this->setGetArray(array('id' => $johnDoeContactId));
         $this->runControllerWithNoExceptionsAndGetContent('/contacts/default/details');
         $this->runControllerWithNoExceptionsAndGetContent('/contacts/default/edit');
     }
     return $timeTakenForSave;
 }
 /**
  * @depends testListContacts
  */
 public function testUnprivilegedUserViewUpdateDeleteContacts()
 {
     Yii::app()->user->userModel = User::getByUsername('super');
     $notAllowedUser = UserTestHelper::createBasicUser('Steven');
     $notAllowedUser->setRight('UsersModule', UsersModule::RIGHT_LOGIN_VIA_WEB_API);
     $saved = $notAllowedUser->save();
     $authenticationData = $this->login('steven', 'steven');
     $headers = array('Accept: application/json', 'ZURMO_SESSION_ID: ' . $authenticationData['sessionId'], 'ZURMO_TOKEN: ' . $authenticationData['token'], 'ZURMO_API_REQUEST_TYPE: REST');
     $everyoneGroup = Group::getByName(Group::EVERYONE_GROUP_NAME);
     $this->assertTrue($everyoneGroup->save());
     $contacts = Contact::getByName('Michael Smith with just owner');
     $this->assertEquals(1, count($contacts));
     $data['department'] = "Support";
     // Test with unprivileged user to view, edit and delete account.
     $authenticationData = $this->login('steven', 'steven');
     $headers = array('Accept: application/json', 'ZURMO_SESSION_ID: ' . $authenticationData['sessionId'], 'ZURMO_TOKEN: ' . $authenticationData['token'], 'ZURMO_API_REQUEST_TYPE: REST');
     $response = $this->createApiCallWithRelativeUrl('read/' . $contacts[0]->id, 'GET', $headers);
     $response = json_decode($response, true);
     $this->assertEquals(ApiResponse::STATUS_FAILURE, $response['status']);
     $this->assertEquals('You do not have rights to perform this action.', $response['message']);
     $response = $this->createApiCallWithRelativeUrl('update/' . $contacts[0]->id, 'PUT', $headers, array('data' => $data));
     $response = json_decode($response, true);
     $this->assertEquals(ApiResponse::STATUS_FAILURE, $response['status']);
     $this->assertEquals('You do not have rights to perform this action.', $response['message']);
     $response = $this->createApiCallWithRelativeUrl('delete/' . $contacts[0]->id, 'DELETE', $headers);
     $response = json_decode($response, true);
     $this->assertEquals(ApiResponse::STATUS_FAILURE, $response['status']);
     $this->assertEquals('You do not have rights to perform this action.', $response['message']);
     //now check if user have rights, but no permissions.
     $notAllowedUser->setRight('ContactsModule', ContactsModule::getAccessRight());
     $notAllowedUser->setRight('ContactsModule', ContactsModule::getCreateRight());
     $notAllowedUser->setRight('ContactsModule', ContactsModule::getDeleteRight());
     $saved = $notAllowedUser->save();
     $this->assertTrue($saved);
     $response = $this->createApiCallWithRelativeUrl('read/' . $contacts[0]->id, 'GET', $headers);
     $response = json_decode($response, true);
     $this->assertEquals(ApiResponse::STATUS_FAILURE, $response['status']);
     $this->assertEquals('You do not have permissions for this action.', $response['message']);
     $response = $this->createApiCallWithRelativeUrl('update/' . $contacts[0]->id, 'PUT', $headers, array('data' => $data));
     $response = json_decode($response, true);
     $this->assertEquals(ApiResponse::STATUS_FAILURE, $response['status']);
     $this->assertEquals('You do not have permissions for this action.', $response['message']);
     $response = $this->createApiCallWithRelativeUrl('delete/' . $contacts[0]->id, 'DELETE', $headers);
     $response = json_decode($response, true);
     $this->assertEquals(ApiResponse::STATUS_FAILURE, $response['status']);
     $this->assertEquals('You do not have permissions for this action.', $response['message']);
     // Allow everyone group to read/write contact
     $authenticationData = $this->login();
     $headers = array('Accept: application/json', 'ZURMO_SESSION_ID: ' . $authenticationData['sessionId'], 'ZURMO_TOKEN: ' . $authenticationData['token'], 'ZURMO_API_REQUEST_TYPE: REST');
     unset($data);
     $data['explicitReadWriteModelPermissions'] = array('type' => ExplicitReadWriteModelPermissionsUtil::MIXED_TYPE_EVERYONE_GROUP);
     $response = $this->createApiCallWithRelativeUrl('update/' . $contacts[0]->id, 'PUT', $headers, array('data' => $data));
     $response = json_decode($response, true);
     $this->assertEquals(ApiResponse::STATUS_SUCCESS, $response['status']);
     $authenticationData = $this->login('steven', 'steven');
     $headers = array('Accept: application/json', 'ZURMO_SESSION_ID: ' . $authenticationData['sessionId'], 'ZURMO_TOKEN: ' . $authenticationData['token'], 'ZURMO_API_REQUEST_TYPE: REST');
     $response = $this->createApiCallWithRelativeUrl('read/' . $contacts[0]->id, 'GET', $headers);
     $response = json_decode($response, true);
     $this->assertEquals(ApiResponse::STATUS_SUCCESS, $response['status']);
     unset($data);
     $data['department'] = "Support";
     $response = $this->createApiCallWithRelativeUrl('update/' . $contacts[0]->id, 'PUT', $headers, array('data' => $data));
     $response = json_decode($response, true);
     $this->assertEquals(ApiResponse::STATUS_SUCCESS, $response['status']);
     $this->assertEquals('Support', $response['data']['department']);
     // Test with privileged user
     $authenticationData = $this->login();
     $headers = array('Accept: application/json', 'ZURMO_SESSION_ID: ' . $authenticationData['sessionId'], 'ZURMO_TOKEN: ' . $authenticationData['token'], 'ZURMO_API_REQUEST_TYPE: REST');
     //Test Delete
     $response = $this->createApiCallWithRelativeUrl('delete/' . $contacts[0]->id, 'DELETE', $headers);
     $response = json_decode($response, true);
     $this->assertEquals(ApiResponse::STATUS_SUCCESS, $response['status']);
     $response = $this->createApiCallWithRelativeUrl('read/' . $contacts[0]->id, 'GET', $headers);
     $response = json_decode($response, true);
     $this->assertEquals(ApiResponse::STATUS_FAILURE, $response['status']);
 }
 public function testArePermissionsFlushedOnRemovingParentFromChildGroup()
 {
     // cleanup
     Contact::deleteAll();
     try {
         $group = Group::getByName('Child');
         $group->delete();
     } catch (NotFoundException $e) {
     }
     try {
         $user = User::getByUsername('jim');
         $user->delete();
     } catch (NotFoundException $e) {
     }
     // we could have used helpers to do a lot of the following stuff (such as creating users, groups,
     // etc) but we wanted to mimic user's interaction as closely as possible. Hence using walkthroughs
     // for everything
     // create Parent and Child Groups, Create Jim to be member of Child group
     // create parent group
     $this->resetGetArray();
     $this->setPostArray(array('Group' => array('name' => 'Parent')));
     $this->runControllerWithRedirectExceptionAndGetUrl('/zurmo/group/create');
     $parentGroup = Group::getByName('Parent');
     $this->assertNotNull($parentGroup);
     $this->assertEquals('Parent', strval($parentGroup));
     $parentGroupId = $parentGroup->id;
     // create child group
     $this->resetGetArray();
     $this->setPostArray(array('Group' => array('name' => 'Child', 'group' => array('id' => $parentGroupId))));
     $this->runControllerWithRedirectExceptionAndGetUrl('/zurmo/group/create');
     $childGroup = Group::getByName('Child');
     $this->assertNotNull($childGroup);
     $this->assertEquals('Child', strval($childGroup));
     $parentGroup->forgetAll();
     $parentGroup = Group::getById($parentGroupId);
     // give child rights for contacts module
     $childGroup->setRight('ContactsModule', ContactsModule::getAccessRight());
     $childGroup->setRight('ContactsModule', ContactsModule::getCreateRight());
     $this->assertTrue($childGroup->save());
     $childGroupId = $childGroup->id;
     $childGroup->forgetAll();
     $childGroup = Group::getById($childGroupId);
     $this->assertContains($childGroup, $parentGroup->groups);
     // create jim's user
     $this->resetGetArray();
     $this->setPostArray(array('UserPasswordForm' => array('firstName' => 'Some', 'lastName' => 'Body', 'username' => 'jim', 'newPassword' => 'myPassword123', 'newPassword_repeat' => 'myPassword123', 'officePhone' => '456765421', 'userStatus' => 'Active')));
     $this->runControllerWithRedirectExceptionAndGetContent('/users/default/create');
     $jim = User::getByUsername('jim');
     $this->assertNotNull($jim);
     // set jim's group to child group
     $this->setGetArray(array('id' => $childGroup->id));
     $this->setPostArray(array('GroupUserMembershipForm' => array('userMembershipData' => array($jim->id))));
     $this->runControllerWithRedirectExceptionAndGetUrl('/zurmo/group/editUserMembership');
     $jim->forgetAll();
     $jim = User::getByUsername('jim');
     $this->assertNotNull($jim);
     $childGroup->forgetAll();
     $childGroup = Group::getById($childGroupId);
     $this->assertContains($childGroup, $jim->groups);
     // create a contact with permissions to Parent group
     // create ContactStates
     ContactsModule::loadStartingData();
     // ensure contact states have been created
     $this->assertEquals(6, count(ContactState::GetAll()));
     // go ahead and create contact with parent group given readwrite.
     $startingState = ContactsUtil::getStartingState();
     $this->resetGetArray();
     $this->setPostArray(array('Contact' => array('firstName' => 'John', 'lastName' => 'Doe', 'officePhone' => '456765421', 'state' => array('id' => $startingState->id), 'explicitReadWriteModelPermissions' => array('type' => ExplicitReadWriteModelPermissionsUtil::MIXED_TYPE_NONEVERYONE_GROUP, 'nonEveryoneGroup' => $parentGroupId))));
     $url = $this->runControllerWithRedirectExceptionAndGetUrl('/contacts/default/create');
     $johnDoeContactId = intval(substr($url, strpos($url, 'id=') + 3));
     $johnDoeContact = Contact::getById($johnDoeContactId);
     $this->assertNotNull($johnDoeContact);
     $this->resetPostArray();
     $this->setGetArray(array('id' => $johnDoeContactId));
     $content = $this->runControllerWithNoExceptionsAndGetContent('/contacts/default/details');
     $this->assertContains('Who can read and write Parent', $content);
     // create a contact using jim which he would see at all times
     $this->logoutCurrentUserLoginNewUserAndGetByUsername('jim');
     $this->resetGetArray();
     $this->setPostArray(array('Contact' => array('firstName' => 'Jim', 'lastName' => 'Doe', 'officePhone' => '456765421', 'state' => array('id' => $startingState->id))));
     $url = $this->runControllerWithRedirectExceptionAndGetUrl('/contacts/default/create');
     $jimDoeContactId = intval(substr($url, strpos($url, 'id=') + 3));
     $jimDoeContact = Contact::getById($jimDoeContactId);
     $this->assertNotNull($jimDoeContact);
     $this->resetPostArray();
     $this->setGetArray(array('id' => $jimDoeContactId));
     $this->runControllerWithNoExceptionsAndGetContent('/contacts/default/details');
     // ensure jim can see that contact everywhere
     // jim should have access to see contact on list view
     $this->resetGetArray();
     // get the page, ensure the name of contact does show up there.
     $content = $this->runControllerWithNoExceptionsAndGetContent('/contacts/default');
     $this->assertContains('John Doe</a></td><td>', $content);
     $this->assertContains('Jim Doe</a></td><td>', $content);
     // jim should have access to jimDoeContact's detail view
     $this->setGetArray(array('id' => $jimDoeContactId));
     $this->runControllerWithNoExceptionsAndGetContent('/contacts/default/details');
     // jim should have access to jimDoeContact's edit view
     $this->runControllerWithNoExceptionsAndGetContent('/contacts/default/edit');
     // jim should have access to johnDoeContact's detail view
     $this->setGetArray(array('id' => $johnDoeContactId));
     $this->runControllerWithNoExceptionsAndGetContent('/contacts/default/details');
     // jim should have access to johnDoeContact's edit view
     $this->runControllerWithNoExceptionsAndGetContent('/contacts/default/edit');
     // unlink Parent group from child
     $this->logoutCurrentUserLoginNewUserAndGetByUsername('super');
     $this->setGetArray(array('id' => $childGroupId));
     $this->setPostArray(array('Group' => array('name' => 'Child', 'group' => array('id' => ''))));
     $this->runControllerWithRedirectExceptionAndGetUrl('/zurmo/group/edit');
     $childGroup = Group::getByName('Child');
     $this->assertNotNull($childGroup);
     $this->assertEquals('Child', strval($childGroup));
     $parentGroup->forgetAll();
     $parentGroup = Group::getById($parentGroupId);
     $this->assertNotContains($childGroup, $parentGroup->groups);
     // ensure jim can not see that contact anywhere
     // jim should not have access to see contact on list view
     $this->logoutCurrentUserLoginNewUserAndGetByUsername('jim');
     $this->resetGetArray();
     // get the page, ensure the name of contact does not show up there.
     $content = $this->runControllerWithNoExceptionsAndGetContent('/contacts/default');
     $this->assertNotContains('John Doe</a></td><td>', $content);
     $this->assertContains('Jim Doe</a></td><td>', $content);
     // jim should have access to jimDoeContact's detail view
     $this->setGetArray(array('id' => $jimDoeContactId));
     $this->runControllerWithNoExceptionsAndGetContent('/contacts/default/details');
     // jim should have access to jimDoeContact's edit view
     $this->runControllerWithNoExceptionsAndGetContent('/contacts/default/edit');
     // jim should not have access to johnDoeContact's detail view
     $this->setGetArray(array('id' => $johnDoeContactId));
     try {
         $this->runControllerWithNoExceptionsAndGetContent('/contacts/default/details');
         $this->fail('Accessing details action should have thrown ExitException');
     } catch (ExitException $e) {
         // just cleanup buffer
         $this->endAndGetOutputBuffer();
     }
     // jim should not have access to johnDoeContact's edit view
     try {
         $this->runControllerWithNoExceptionsAndGetContent('/contacts/default/edit');
         $this->fail('Accessing edit action should have thrown ExitException');
     } catch (ExitException $e) {
         // just cleanup buffer
         $this->endAndGetOutputBuffer();
     }
 }