1<?php 2/* 3 * vim:set softtabstop=4 shiftwidth=4 expandtab: 4 * 5 * LICENSE: GNU Affero General Public License, version 3 (AGPL-3.0-or-later) 6 * Copyright 2001 - 2020 Ampache.org 7 * 8 * This program is free software: you can redistribute it and/or modify 9 * it under the terms of the GNU Affero General Public License as published by 10 * the Free Software Foundation, either version 3 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU Affero General Public License for more details. 17 * 18 * You should have received a copy of the GNU Affero General Public License 19 * along with this program. If not, see <https://www.gnu.org/licenses/>. 20 * 21 */ 22 23declare(strict_types=1); 24 25namespace Ampache\Module\Application\PrivateMessage; 26 27use Ampache\Config\ConfigContainerInterface; 28use Ampache\Config\ConfigurationKeyEnum; 29use Ampache\MockeryTestCase; 30use Ampache\Repository\Model\PrivateMessageInterface; 31use Ampache\Module\Application\Exception\AccessDeniedException; 32use Ampache\Module\Authorization\AccessLevelEnum; 33use Ampache\Module\Authorization\GuiGatekeeperInterface; 34use Ampache\Module\Util\UiInterface; 35use Ampache\Repository\PrivateMessageRepositoryInterface; 36use Mockery\MockInterface; 37use Psr\Http\Message\ServerRequestInterface; 38 39class SetIsReadActionTest extends MockeryTestCase 40{ 41 /** @var ConfigContainerInterface|MockInterface|null */ 42 private MockInterface $configContainer; 43 44 /** @var UiInterface|MockInterface|null */ 45 private MockInterface $ui; 46 47 /** @var PrivateMessageRepositoryInterface|MockInterface|null */ 48 private MockInterface $privateMessageRepository; 49 50 private ?SetIsReadAction $subject; 51 52 public function setUp(): void 53 { 54 $this->configContainer = $this->mock(ConfigContainerInterface::class); 55 $this->ui = $this->mock(UiInterface::class); 56 $this->privateMessageRepository = $this->mock(PrivateMessageRepositoryInterface::class); 57 58 $this->subject = new SetIsReadAction( 59 $this->configContainer, 60 $this->ui, 61 $this->privateMessageRepository 62 ); 63 } 64 65 public function testRunThrowsExceptionIfAccessIsDenied(): void 66 { 67 $this->expectException(AccessDeniedException::class); 68 69 $request = $this->mock(ServerRequestInterface::class); 70 $gatekeeper = $this->mock(GuiGatekeeperInterface::class); 71 72 $gatekeeper->shouldReceive('mayAccess') 73 ->with(AccessLevelEnum::TYPE_INTERFACE, AccessLevelEnum::LEVEL_USER) 74 ->once() 75 ->andReturnFalse(); 76 77 $this->subject->run($request, $gatekeeper); 78 } 79 80 public function testRunThrowsExceptionIfSocialFeaturesAreDisabled(): void 81 { 82 $this->expectException(AccessDeniedException::class); 83 84 $request = $this->mock(ServerRequestInterface::class); 85 $gatekeeper = $this->mock(GuiGatekeeperInterface::class); 86 87 $gatekeeper->shouldReceive('mayAccess') 88 ->with(AccessLevelEnum::TYPE_INTERFACE, AccessLevelEnum::LEVEL_USER) 89 ->once() 90 ->andReturnTrue(); 91 92 $this->configContainer->shouldReceive('isFeatureEnabled') 93 ->with(ConfigurationKeyEnum::SOCIABLE) 94 ->once() 95 ->andReturnFalse(); 96 97 $this->subject->run($request, $gatekeeper); 98 } 99 100 public function testRunReturnsNullIfDemoMode(): void 101 { 102 $request = $this->mock(ServerRequestInterface::class); 103 $gatekeeper = $this->mock(GuiGatekeeperInterface::class); 104 105 $gatekeeper->shouldReceive('mayAccess') 106 ->with(AccessLevelEnum::TYPE_INTERFACE, AccessLevelEnum::LEVEL_USER) 107 ->once() 108 ->andReturnTrue(); 109 110 $this->configContainer->shouldReceive('isFeatureEnabled') 111 ->with(ConfigurationKeyEnum::SOCIABLE) 112 ->once() 113 ->andReturnTrue(); 114 $this->configContainer->shouldReceive('isFeatureEnabled') 115 ->with(ConfigurationKeyEnum::DEMO_MODE) 116 ->once() 117 ->andReturnTrue(); 118 119 $this->assertNull( 120 $this->subject->run($request, $gatekeeper) 121 ); 122 } 123 124 public function testRunThrowsExceptionIfAccessToMessageIsDenied(): void 125 { 126 $messageId = 666; 127 128 $this->expectException(AccessDeniedException::class); 129 $this->expectExceptionMessage(sprintf('Unknown or unauthorized private message `%d`.', $messageId)); 130 131 $request = $this->mock(ServerRequestInterface::class); 132 $gatekeeper = $this->mock(GuiGatekeeperInterface::class); 133 $message = $this->mock(PrivateMessageInterface::class); 134 135 $gatekeeper->shouldReceive('mayAccess') 136 ->with(AccessLevelEnum::TYPE_INTERFACE, AccessLevelEnum::LEVEL_USER) 137 ->once() 138 ->andReturnTrue(); 139 $gatekeeper->shouldReceive('getUserId') 140 ->withNoArgs() 141 ->once() 142 ->andReturn(456); 143 144 $this->configContainer->shouldReceive('isFeatureEnabled') 145 ->with(ConfigurationKeyEnum::SOCIABLE) 146 ->once() 147 ->andReturnTrue(); 148 $this->configContainer->shouldReceive('isFeatureEnabled') 149 ->with(ConfigurationKeyEnum::DEMO_MODE) 150 ->once() 151 ->andReturnFalse(); 152 153 $request->shouldReceive('getQueryParams') 154 ->withNoArgs() 155 ->once() 156 ->andReturn(['read' => 1, 'msgs' => implode(',', [$messageId, 42])]); 157 158 $this->privateMessageRepository->shouldReceive('getById') 159 ->with($messageId) 160 ->once() 161 ->andReturn($message); 162 163 $message->shouldReceive('getRecipientUserId') 164 ->withNoArgs() 165 ->once() 166 ->andReturn(123); 167 168 $this->subject->run($request, $gatekeeper); 169 } 170 171 public function testRunSetsReadMode(): void 172 { 173 $messageId = 666; 174 $userId = 42; 175 $webPath = 'some-path'; 176 177 $request = $this->mock(ServerRequestInterface::class); 178 $gatekeeper = $this->mock(GuiGatekeeperInterface::class); 179 $message = $this->mock(PrivateMessageInterface::class); 180 181 $gatekeeper->shouldReceive('mayAccess') 182 ->with(AccessLevelEnum::TYPE_INTERFACE, AccessLevelEnum::LEVEL_USER) 183 ->once() 184 ->andReturnTrue(); 185 $gatekeeper->shouldReceive('getUserId') 186 ->withNoArgs() 187 ->once() 188 ->andReturn($userId); 189 190 $this->configContainer->shouldReceive('isFeatureEnabled') 191 ->with(ConfigurationKeyEnum::SOCIABLE) 192 ->once() 193 ->andReturnTrue(); 194 $this->configContainer->shouldReceive('isFeatureEnabled') 195 ->with(ConfigurationKeyEnum::DEMO_MODE) 196 ->once() 197 ->andReturnFalse(); 198 $this->configContainer->shouldReceive('getWebPath') 199 ->withNoArgs() 200 ->once() 201 ->andReturn($webPath); 202 203 $request->shouldReceive('getQueryParams') 204 ->withNoArgs() 205 ->once() 206 ->andReturn(['read' => 1, 'msgs' => (string) $messageId]); 207 208 $this->privateMessageRepository->shouldReceive('getById') 209 ->with($messageId) 210 ->once() 211 ->andReturn($message); 212 $this->privateMessageRepository->shouldReceive('setIsRead') 213 ->with($messageId, 1) 214 ->once(); 215 216 $message->shouldReceive('getRecipientUserId') 217 ->withNoArgs() 218 ->once() 219 ->andReturn($userId); 220 221 $this->ui->shouldReceive('showHeader') 222 ->withNoArgs() 223 ->once(); 224 $this->ui->shouldReceive('showConfirmation') 225 ->with( 226 'No Problem', 227 'Message\'s state has been changed', 228 sprintf( 229 '%s/browse.php?action=pvmsg', 230 $webPath 231 ) 232 ) 233 ->once(); 234 $this->ui->shouldReceive('showQueryStats') 235 ->withNoArgs() 236 ->once(); 237 $this->ui->shouldReceive('showFooter') 238 ->withNoArgs() 239 ->once(); 240 241 $this->subject->run($request, $gatekeeper); 242 } 243} 244