Added jobs for user settings manipulation

This commit is contained in:
Marcin Kurczewski 2014-05-14 17:21:12 +02:00
parent b811e76318
commit 2e12e4f39d
12 changed files with 342 additions and 37 deletions

View file

@ -38,14 +38,15 @@ class JobArgs
const ARG_NEW_THUMB_CONTENT = 'new-thumb-content';
const ARG_NEW_TAG_NAMES = 'new-tag-names';
const ARG_NEW_POST_SCORE = 'new-post-score';
const ARG_SOURCE_TAG_NAME = 'source-tag-name';
const ARG_TARGET_TAG_NAME = 'target-tag-name';
const ARG_NEW_ACCESS_RANK = 'new-access-rank';
const ARG_NEW_EMAIL = 'new-email';
const ARG_NEW_USER_NAME = 'new-user-name';
const ARG_NEW_PASSWORD = 'new-password';
const ARG_NEW_SETTINGS = 'new-settings';
const ARG_NEW_POST_SCORE = 'new-post-score';
const ARG_SOURCE_TAG_NAME = 'source-tag-name';
const ARG_TARGET_TAG_NAME = 'target-tag-name';
public static function Alternative()
{

View file

@ -0,0 +1,44 @@
<?php
class EditUserSettingsJob extends AbstractJob
{
protected $userRetriever;
public function __construct()
{
$this->userRetriever = new UserRetriever($this);
}
public function execute()
{
$newSettings = $this->getArgument(JobArgs::ARG_NEW_SETTINGS);
if (!is_array($newSettings))
throw new SimpleException('Expected array');
$user = $this->userRetriever->retrieve();
foreach ($newSettings as $key => $value)
{
$user->getSettings()->set($key, $value);
}
return UserModel::save($user);
}
public function getRequiredArguments()
{
return JobArgs::Conjunction(
$this->userRetriever->getRequiredArguments(),
JobArgs::ARG_NEW_SETTINGS);
}
public function getRequiredPrivileges()
{
return new Privilege(
Privilege::ChangeUserSettings,
Access::getIdentity($this->userRetriever->retrieve()));
}
public function isAuthenticationRequired()
{
return true;
}
}

View file

@ -0,0 +1,33 @@
<?php
class GetUserSettingsJob extends AbstractJob
{
protected $userRetriever;
public function __construct()
{
$this->userRetriever = new UserRetriever($this);
}
public function execute()
{
$user = $this->userRetriever->retrieve();
return $user->getSettings()->getAllAsArray();
}
public function getRequiredArguments()
{
return $this->userRetriever->getRequiredArguments();
}
public function getRequiredPrivileges()
{
return new Privilege(
Privilege::ChangeUserSettings,
Access::getIdentity($this->userRetriever->retrieve()));
}
public function isAuthenticationRequired()
{
return true;
}
}

View file

@ -71,30 +71,48 @@ class UserController
{
$this->genericView($identifier, 'settings');
$user = getContext()->transport->user;
Access::assert(new Privilege(
Privilege::ChangeUserSettings,
Access::getIdentity($user)));
$suppliedSafety = InputHelper::get('safety');
if (!is_array($suppliedSafety))
$suppliedSafety = [];
foreach (PostSafety::getAll() as $safety)
$user->getSettings()->enableSafety($safety, in_array($safety->toInteger(), $suppliedSafety));
$desiredSafety = PostSafety::makeFlags($suppliedSafety);
$user->getSettings()->enableEndlessScrolling(InputHelper::get('endless-scrolling'));
$user->getSettings()->enablePostTagTitles(InputHelper::get('post-tag-titles'));
$user->getSettings()->enableHidingDislikedPosts(InputHelper::get('hide-disliked-posts'));
$user = Api::run(
new EditUserSettingsJob(),
$this->appendUserIdentifierArgument(
[
JobArgs::ARG_NEW_SETTINGS =>
[
UserSettings::SETTING_SAFETY => $desiredSafety,
UserSettings::SETTING_ENDLESS_SCROLLING => InputHelper::get('endless-scrolling'),
UserSettings::SETTING_POST_TAG_TITLES => InputHelper::get('post-tag-titles'),
UserSettings::SETTING_HIDE_DISLIKED_POSTS => InputHelper::get('hide-disliked-posts'),
]
], $identifier));
if ($user->getAccessRank()->toInteger() != AccessRank::Anonymous)
UserModel::save($user);
getContext()->transport->user = $user;
if ($user->getId() == Auth::getCurrentUser()->getId())
Auth::setCurrentUser($user);
Messenger::message('Browsing settings updated!');
}
public function toggleSafetyAction($safety)
{
$safety = new PostSafety($safety);
$safety->validate();
$user = Auth::getCurrentUser();
$user->getSettings()->enableSafety($safety, !$user->getSettings()->hasEnabledSafety($safety));
$desiredSafety = $user->getSettings()->get(UserSettings::SETTING_SAFETY);
$user = Api::run(
new EditUserSettingsJob(),
[
JobArgs::ARG_USER_ENTITY => Auth::getCurrentUser(),
JobArgs::ARG_NEW_SETTINGS => [UserSettings::SETTING_SAFETY => $desiredSafety],
]);
Auth::setCurrentUser($user);
}
public function editAction($identifier)
{
$this->genericView($identifier, 'edit');
@ -174,24 +192,6 @@ class UserController
$this->appendUserIdentifierArgument([], $identifier));
}
public function toggleSafetyAction($safety)
{
$user = Auth::getCurrentUser();
Access::assert(new Privilege(
Privilege::ChangeUserSettings,
Access::getIdentity($user)));
$safety = new PostSafety($safety);
$safety->validate();
$user->getSettings()->enableSafety($safety, !$user->getSettings()->hasEnabledSafety($safety));
if ($user->getAccessRank()->toInteger() != AccessRank::Anonymous)
UserModel::save($user);
Auth::setCurrentUser($user);
}
public function registrationView()
{
$context = getContext();

View file

@ -27,6 +27,18 @@ class PostSafety extends Enum implements IValidatable
return self::_toString($this->safety);
}
public static function makeFlags($safetyCodes)
{
if (!is_array($safetyCodes))
return 0;
$flags = 0;
foreach (self::getAll() as $safety)
if (in_array($safety->toInteger(), $safetyCodes))
$flags |= $safety->toFlag();
return $flags;
}
public static function getAll()
{
return array_map(function($constantName)

View file

@ -21,6 +21,7 @@ class UserSettings implements IValidatable
$serialized = $this->getAllAsSerializedString();
if (strlen($serialized) > 200)
throw new SimpleException('Too much data');
$this->ensureCorrectTypes();
}

View file

@ -211,6 +211,12 @@ class ApiArgumentTest extends AbstractFullApiTest
$this->getUserSelector());
}
public function testGetUserSettingsJob()
{
$this->testArguments(new GetUserSettingsJob(),
$this->getUserSelector());
}
public function testListCommentsJob()
{
$this->testArguments(new ListCommentsJob(),
@ -280,6 +286,14 @@ class ApiArgumentTest extends AbstractFullApiTest
$this->getUserSelector()));
}
public function testEditUserSettingsJob()
{
$this->testArguments(new EditUserSettingsJob(),
JobArgs::Conjunction(
$this->getUserSelector(),
JobArgs::ARG_NEW_SETTINGS));
}
public function testPreviewCommentJob()
{
$this->testArguments(new PreviewCommentJob(),

View file

@ -24,6 +24,7 @@ class ApiAuthTest extends AbstractFullApiTest
$this->testAuth(new EditUserJob(), false);
$this->testAuth(new EditUserNameJob(), false);
$this->testAuth(new EditUserPasswordJob(), false);
$this->testAuth(new EditUserSettingsJob(), true);
$this->testAuth(new FeaturePostJob(), true);
$this->testAuth(new FlagPostJob(), false);
$this->testAuth(new FlagUserJob(), false);
@ -32,6 +33,7 @@ class ApiAuthTest extends AbstractFullApiTest
$this->testAuth(new GetPostJob(), false);
$this->testAuth(new GetPostThumbJob(), false);
$this->testAuth(new GetUserJob(), false);
$this->testAuth(new GetUserSettingsJob(), true);
$this->testAuth(new ListCommentsJob(), false);
$this->testAuth(new ListLogsJob(), false);
$this->testAuth(new ListPostsJob(), false);

View file

@ -25,6 +25,7 @@ class ApiEmailRequirementsTest extends AbstractFullApiTest
$this->testRegularEmailRequirement(new EditUserJob());
$this->testRegularEmailRequirement(new EditUserNameJob());
$this->testRegularEmailRequirement(new EditUserPasswordJob());
$this->testRegularEmailRequirement(new EditUserSettingsJob());
$this->testRegularEmailRequirement(new FeaturePostJob());
$this->testRegularEmailRequirement(new FlagPostJob());
$this->testRegularEmailRequirement(new FlagUserJob());
@ -33,6 +34,7 @@ class ApiEmailRequirementsTest extends AbstractFullApiTest
$this->testRegularEmailRequirement(new GetPostJob());
$this->testRegularEmailRequirement(new GetPostThumbJob());
$this->testRegularEmailRequirement(new GetUserJob());
$this->testRegularEmailRequirement(new GetUserSettingsJob());
$this->testRegularEmailRequirement(new ListCommentsJob());
$this->testRegularEmailRequirement(new ListLogsJob());
$this->testRegularEmailRequirement(new ListPostsJob());

View file

@ -133,8 +133,10 @@ class ApiPrivilegeTest extends AbstractFullApiTest
$this->testDynamicUserPrivilege(new EditUserEmailJob(), new Privilege(Privilege::ChangeUserEmail));
$this->testDynamicUserPrivilege(new EditUserNameJob(), new Privilege(Privilege::ChangeUserName));
$this->testDynamicUserPrivilege(new EditUserPasswordJob(), new Privilege(Privilege::ChangeUserPassword));
$this->testDynamicUserPrivilege(new EditUserSettingsJob(), new Privilege(Privilege::ChangeUserSettings));
$this->testDynamicUserPrivilege(new FlagUserJob(), new Privilege(Privilege::FlagUser));
$this->testDynamicUserPrivilege(new GetUserJob(), new Privilege(Privilege::ViewUser));
$this->testDynamicUserPrivilege(new GetUserSettingsJob(), new Privilege(Privilege::ChangeUserSettings));
$this->testDynamicUserPrivilege(new ToggleUserBanJob(), new Privilege(Privilege::BanUser));
}

View file

@ -0,0 +1,112 @@
<?php
class EditUserSettingsJobTest extends AbstractTest
{
public function testEditing()
{
$this->grantAccess('changeUserSettings');
$user = $this->userMocker->mockSingle();
$this->login($user);
$expectedSafety = (new PostSafety(PostSafety::Sketchy))->toFlag();
$user = $this->assert->doesNotThrow(function() use ($user, $expectedSafety)
{
return Api::run(
new EditUserSettingsJob(),
[
JobArgs::ARG_USER_NAME => $user->getName(),
JobArgs::ARG_NEW_SETTINGS =>
[
UserSettings::SETTING_SAFETY => $expectedSafety,
UserSettings::SETTING_ENDLESS_SCROLLING => true,
UserSettings::SETTING_POST_TAG_TITLES => true,
UserSettings::SETTING_HIDE_DISLIKED_POSTS => true,
]
]);
});
$settings = $user->getSettings();
$this->assert->areEqual($expectedSafety, $settings->get(UserSettings::SETTING_SAFETY));
$this->assert->isTrue($settings->get(UserSettings::SETTING_ENDLESS_SCROLLING));
$this->assert->isTrue($settings->get(UserSettings::SETTING_POST_TAG_TITLES));
$this->assert->isTrue($settings->get(UserSettings::SETTING_HIDE_DISLIKED_POSTS));
}
public function testSettingAdditional()
{
$this->grantAccess('changeUserSettings');
$user = $this->userMocker->mockSingle();
$this->login($user);
$user = $this->assert->doesNotThrow(function() use ($user)
{
return Api::run(
new EditUserSettingsJob(),
[
JobArgs::ARG_USER_NAME => $user->getName(),
JobArgs::ARG_NEW_SETTINGS =>
[
'additional' => 'rubbish',
]
]);
});
$settings = $user->getSettings();
$expectedSafety = (new PostSafety(PostSafety::Safe))->toFlag();
$this->assert->areEqual($expectedSafety, $settings->get(UserSettings::SETTING_SAFETY));
$this->assert->isTrue($settings->get(UserSettings::SETTING_ENDLESS_SCROLLING));
$this->assert->isFalse($settings->get(UserSettings::SETTING_POST_TAG_TITLES));
$this->assert->isFalse($settings->get(UserSettings::SETTING_HIDE_DISLIKED_POSTS));
$this->assert->areEqual('rubbish', $settings->get('additional'));
}
public function testSettingBadValues()
{
$this->grantAccess('changeUserSettings');
$user = $this->userMocker->mockSingle();
$this->login($user);
$user = $this->assert->doesNotThrow(function() use ($user)
{
return Api::run(
new EditUserSettingsJob(),
[
JobArgs::ARG_USER_NAME => $user->getName(),
JobArgs::ARG_NEW_SETTINGS =>
[
UserSettings::SETTING_SAFETY => 'rubbish',
UserSettings::SETTING_ENDLESS_SCROLLING => 'rubbish',
UserSettings::SETTING_POST_TAG_TITLES => 'rubbish',
UserSettings::SETTING_HIDE_DISLIKED_POSTS => 'rubbish',
]
]);
});
$settings = $user->getSettings();
$expectedSafety = (new PostSafety(PostSafety::Safe))->toFlag();
$this->assert->areEqual($expectedSafety, $settings->get(UserSettings::SETTING_SAFETY));
$this->assert->isTrue($settings->get(UserSettings::SETTING_ENDLESS_SCROLLING));
$this->assert->isFalse($settings->get(UserSettings::SETTING_POST_TAG_TITLES));
$this->assert->isFalse($settings->get(UserSettings::SETTING_HIDE_DISLIKED_POSTS));
}
public function testSettingTooLongData()
{
$this->grantAccess('changeUserSettings');
$user = $this->userMocker->mockSingle();
$this->login($user);
$this->assert->throws(function() use ($user)
{
return Api::run(
new EditUserSettingsJob(),
[
JobArgs::ARG_USER_NAME => $user->getName(),
JobArgs::ARG_NEW_SETTINGS =>
[
'additional' => str_repeat('rubbish', 50),
]]);
}, 'Too much data');
}
}

View file

@ -0,0 +1,82 @@
<?php
class GetUserSettingsJobTest extends AbstractTest
{
public function testRetrieving()
{
$this->grantAccess('changeUserSettings');
$user = $this->userMocker->mockSingle();
$this->login($user);
$settings = $this->assert->doesNotThrow(function() use ($user)
{
return Api::run(
new GetUserSettingsJob(),
[
JobArgs::ARG_USER_NAME => $user->getName(),
]);
});
$expectedSafety = (new PostSafety(PostSafety::Safe))->toFlag();
$this->assert->areEqual($expectedSafety, $settings[UserSettings::SETTING_SAFETY]);
$this->assert->isTrue($settings[UserSettings::SETTING_ENDLESS_SCROLLING]);
$this->assert->isFalse($settings[UserSettings::SETTING_POST_TAG_TITLES]);
$this->assert->isFalse($settings[UserSettings::SETTING_HIDE_DISLIKED_POSTS]);
}
public function testSwitchingSafety()
{
$this->grantAccess('changeUserSettings');
$user = $this->userMocker->mockSingle();
$this->login($user);
$user->getSettings()->enableSafety(new PostSafety(PostSafety::Sketchy), true);
UserModel::save($user);
$settings = $this->assert->doesNotThrow(function() use ($user)
{
return Api::run(
new GetUserSettingsJob(),
[
JobArgs::ARG_USER_NAME => $user->getName(),
]);
});
$expectedSafety =
((new PostSafety(PostSafety::Safe))->toFlag()
| (new PostSafety(PostSafety::Sketchy))->toFlag());
$this->assert->areEqual($expectedSafety, $settings[UserSettings::SETTING_SAFETY]);
$this->assert->isTrue($settings[UserSettings::SETTING_ENDLESS_SCROLLING]);
$this->assert->isFalse($settings[UserSettings::SETTING_POST_TAG_TITLES]);
$this->assert->isFalse($settings[UserSettings::SETTING_HIDE_DISLIKED_POSTS]);
}
public function testSwitchingSafety2()
{
$this->grantAccess('changeUserSettings');
$user = $this->userMocker->mockSingle();
$this->login($user);
$user->getSettings()->enableSafety(new PostSafety(PostSafety::Sketchy), true);
$user->getSettings()->enableSafety(new PostSafety(PostSafety::Safe), false);
UserModel::save($user);
$settings = $this->assert->doesNotThrow(function() use ($user)
{
return Api::run(
new GetUserSettingsJob(),
[
JobArgs::ARG_USER_NAME => $user->getName(),
]);
});
$expectedSafety = (new PostSafety(PostSafety::Sketchy))->toFlag();
$this->assert->areEqual($expectedSafety, $settings[UserSettings::SETTING_SAFETY]);
$this->assert->isTrue($settings[UserSettings::SETTING_ENDLESS_SCROLLING]);
$this->assert->isFalse($settings[UserSettings::SETTING_POST_TAG_TITLES]);
$this->assert->isFalse($settings[UserSettings::SETTING_HIDE_DISLIKED_POSTS]);
}
}