Added jobs for user settings manipulation
This commit is contained in:
parent
b811e76318
commit
2e12e4f39d
12 changed files with 342 additions and 37 deletions
|
@ -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()
|
||||
{
|
||||
|
|
44
src/Api/Jobs/UserJobs/EditUserSettingsJob.php
Normal file
44
src/Api/Jobs/UserJobs/EditUserSettingsJob.php
Normal 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;
|
||||
}
|
||||
}
|
33
src/Api/Jobs/UserJobs/GetUserSettingsJob.php
Normal file
33
src/Api/Jobs/UserJobs/GetUserSettingsJob.php
Normal 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;
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -21,6 +21,7 @@ class UserSettings implements IValidatable
|
|||
$serialized = $this->getAllAsSerializedString();
|
||||
if (strlen($serialized) > 200)
|
||||
throw new SimpleException('Too much data');
|
||||
|
||||
$this->ensureCorrectTypes();
|
||||
}
|
||||
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
112
tests/Tests/JobTests/EditUserSettingsJobTest.php
Normal file
112
tests/Tests/JobTests/EditUserSettingsJobTest.php
Normal 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');
|
||||
}
|
||||
}
|
82
tests/Tests/JobTests/GetUserSettingsJobTest.php
Normal file
82
tests/Tests/JobTests/GetUserSettingsJobTest.php
Normal 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]);
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue