This commit is contained in:
frischler 2022-06-04 17:55:26 +02:00 committed by Igor Scheller
parent 2c0d516578
commit 71d183df01
15 changed files with 214 additions and 299 deletions

View File

@ -52,8 +52,8 @@ $route->post('/questions/new', 'QuestionsController@save');
// Messages
$route->get('/messages', 'MessagesController@index');
$route->post('/messages', 'MessagesController@toConversation');
$route->get('/messages/{user_id:\d+}', 'MessagesController@conversation');
$route->post('/messages', 'MessagesController@redirectToConversation');
$route->get('/messages/{user_id:\d+}', 'MessagesController@messagesOfConversation');
$route->post('/messages/{user_id:\d+}', 'MessagesController@send');
$route->post('/messages/{user_id:\d+}/{msg_id:\d+}', 'MessagesController@delete');

View File

@ -350,7 +350,7 @@ code {
}
.conversation {
height: 60vh;
height: 55vh;
overflow-x: hidden;
overflow-y: auto
}

View File

@ -155,5 +155,5 @@ msgstr "Eine Beschreibung findest du unter %2$s"
msgid "user.edit.success"
msgstr "Benutzer erfolgreich bearbeitet."
msgid "messages.delete.success"
msgid "message.delete.success"
msgstr "Nachricht erfolgreich gelöscht."

View File

@ -3031,17 +3031,20 @@ msgstr "Angekommen"
msgid "user.got_shirt"
msgstr "Shirt bekommen"
msgid "messages.title"
msgid "message.title"
msgstr "Nachrichten"
msgid "messages.choose.an.angel"
msgid "message.choose_angel"
msgstr "Wähle einen Engel"
msgid "messages.to.conversation"
msgid "message.to_conversation"
msgstr "Zur Konversation"
msgid "message.message"
msgstr "Nachricht"
msgid "angel"
msgstr "Engel"
msgid "message"
msgstr "Nachricht"
msgid "date"
msgstr "Datum"

View File

@ -153,5 +153,5 @@ msgstr "You can find a description at %2$s"
msgid "user.edit.success"
msgstr "User edited successfully."
msgid "messages.delete.success"
msgid "message.delete.success"
msgstr "Message successfully deleted."

View File

@ -301,17 +301,20 @@ msgstr "Arrived"
msgid "user.got_shirt"
msgstr "Got shirt"
msgid "messages.title"
msgid "message.title"
msgstr "Messages"
msgid "messages.choose.an.angel"
msgid "message.choose_angel"
msgstr "Choose an Angel"
msgid "messages.to.conversation"
msgid "message.to_conversation"
msgstr "To Conversation"
msgid "message.message"
msgstr "Message"
msgid "angel"
msgstr "Angel"
msgid "message"
msgstr "Message"
msgid "date"
msgstr "Date"

View File

@ -1063,11 +1063,6 @@ msgstr "Autor"
msgid "Subject"
msgstr "Assunto"
#: includes/pages/admin_news.php:33 includes/pages/user_messages.php:79
#: includes/pages/user_news.php:106 includes/pages/user_news.php:162
msgid "Message"
msgstr "Mensagem"
#: includes/pages/admin_news.php:34 includes/pages/user_news.php:163
msgid "Meeting"
msgstr "Reunião"
@ -1453,10 +1448,6 @@ msgstr "Por favor leia sobre as tarefas que pode realizar para nos ajudar."
msgid "Please sign up, if you want to help us!"
msgstr "Se você quer nos ajudar, por favor se registre!"
#: includes/pages/user_messages.php:4
msgid "Messages"
msgstr "Mensagens"
#: includes/pages/user_messages.php:26
msgid "Select recipient..."
msgstr "Selecionar recipiente..."

View File

@ -16,11 +16,15 @@
</div>
{% endmacro %}
{% macro user(user) %}
<a href="{{ url('users', {'action': 'view', 'user_id': user.id}) }}"
{% macro user(user, opt) %}
<a href="{{ opt.url|default(url('users', {'action': 'view', 'user_id': user.id})) }}"
{%- if not user.state.arrived %} class="text-muted"{% endif -%}
>
{{ _self.angel() }} {{ user.name }}
{%- if opt.show_pronoun_if_configured|default(false) and config('enable_pronoun')
and user.personalData.pronoun %}
({{ user.personalData.pronoun }})
{% endif -%}
</a>
{% endmacro %}

View File

@ -37,12 +37,17 @@
</div>
{%- endmacro %}
{% macro select(name, data, label, selected) %}
{% macro select(name, data, label, selected, opt) %}
<div class="mb-3">
{% if label -%}
<label class="form-label" for="{{ name }}">{{ label }}</label>
{% endif %}
<select id="{{ name }}" name="{{ name }}" class="form-control">
<select id="{{ name }}" name="{{ name }}"
class="form-control {%- if opt.class is defined %} {{ opt.class }}{% endif %}"
{%- if opt.required|default(false) %}required{%- endif -%}>
{%- if opt.default_option is defined %}
<option value="">{{ opt.default_option }}</option>
{% endif %}
{% for value,decription in data -%}
<option value="{{ value }}"{% if value == selected %} selected{% endif %}>{{ decription }}</option>
{% endfor %}

View File

@ -2,13 +2,13 @@
{% import 'macros/base.twig' as m %}
{% import 'macros/form.twig' as f %}
{% block title %}{{ __('messages.title') }}: {{ other_user.nameWithPronoun() }}{% endblock %}
{% block title %}{{ __('message.title') }}: {{ other_user.name }}{% endblock %}
{% block content %}
<div class="container">
<div class="page-header">
<h1>
{{ __('messages.title') }}: <span class="icon-icon_angel"></span> {{ other_user.nameWithPronoun() }}
{{ __('message.title') }}: {{ m.user(other_user, {'show_pronoun_if_configured': true}) }}
</h1>
</div>
@ -22,12 +22,12 @@
<div class="message alert alert-secondary position-relative">
<div>{{ msg.text | nl2br }}</div>
<div class="text-end">
<small class="opacity-75">{{ msg.created_at }}</small>
<small
class="opacity-75">{{ msg.created_at.format(__('Y-m-d H:i')) }}</small>
</div>
{% if msg.read == false %}
<span class="position-absolute top-0 start-100 translate-middle-x p-2 bg-danger rounded-circle">
<span class="visually-hidden">New alerts</span>
</span>
<span class="position-absolute top-0 start-100 translate-middle-x p-2
bg-danger rounded-circle"></span>
{% endif %}
</div>
</div>
@ -57,10 +57,11 @@
{{ csrf() }}
<div class="input-group">
<textarea class="form-control" id="text" name="text" required="" rows="1"></textarea>
<textarea class="form-control" id="text" name="text" required="" rows="2"></textarea>
{{ f.submit(m.icon('send-fill')) }}
</div>
</form>
</div>
</div>
</div>
{% endblock %}

View File

@ -2,7 +2,7 @@
{% import 'macros/base.twig' as m %}
{% import 'macros/form.twig' as f %}
{% block title %}{{ __('messages.title') }}{% endblock %}
{% block title %}{{ __('message.title') }}{% endblock %}
{% block content %}
<div class="container">
@ -15,15 +15,11 @@
{{ csrf() }}
<div class="row gx-2 mb-3">
<div class="col-auto">
<select id="user_id" name="user_id" class="form-control pe-5" required>
<option value="">{{ __('messages.choose.an.angel') }}</option>
{% for value,decription in users -%}
<option value="{{ value }}">{{ decription }}</option>
{% endfor %}
</select>
{{ f.select('user_id', users, null, null,
{ 'class': 'pe-5', 'required': true, 'default_option': __('message.choose_angel') }) }}
</div>
<div class="col">
{{ f.submit(__('messages.to.conversation'), {'btn_type': 'secondary'}) }}
{{ f.submit(__('message.to_conversation'), {'btn_type': 'secondary'}) }}
</div>
</div>
</form>
@ -32,27 +28,27 @@
<thead>
<tr>
<th>{{ __('angel') }}</th>
<th>{{ __('message') }}</th>
<th>{{ __('Date') }}</th>
<th>{{ __('message.message') }}</th>
<th>{{ __('date') }}</th>
</tr>
</thead>
<tbody>
{% for c in conversations %}
<tr>
<td>
<span class="icon-icon_angel"></span>
{{ c.other_user.nameWithPronoun() }}
{{ m.user(c.other_user, {'show_pronoun_if_configured': true, 'url': url('messages/' ~ c.other_user.id)}) }}
{% if c.unread_messages > 0 %}
<span class="badge bg-danger">{{ c.unread_messages }}</span>
{% endif %}
</td>
<td>
<a href="{{ url('messages/' ~ c.other_user.id) }}">
{{ c.latest_message.text|length > 100 ? c.latest_message.text|slice(0, 100) ~ '...' : c.latest_message.text }}
{{ c.latest_message.text|length > 100 ? c.latest_message.text|slice(0, 100) ~ '' : c.latest_message.text }}
</a>
</td>
<td>
{{ c.latest_message.created_at }}
{{ c.latest_message.created_at.format(__('Y-m-d H:i')) }}
</td>
</tr>
{% endfor %}

View File

@ -10,7 +10,6 @@ use Engelsystem\Http\Response;
use Engelsystem\Models\Message;
use Engelsystem\Models\User\User;
use Illuminate\Database\Query\Expression as QueryExpression;
use Psr\Log\LoggerInterface;
use Illuminate\Support\Collection;
use Engelsystem\Http\Exceptions\HttpForbidden;
@ -19,9 +18,6 @@ class MessagesController extends BaseController
/** @var Authenticator */
protected $auth;
/** @var LoggerInterface */
protected $log;
/** @var Redirector */
protected $redirect;
@ -47,7 +43,6 @@ class MessagesController extends BaseController
/**
* @param Authenticator $auth
* @param LoggerInterface $log
* @param Redirector $redirect
* @param Response $response
* @param Request $request
@ -57,7 +52,6 @@ class MessagesController extends BaseController
*/
public function __construct(
Authenticator $auth,
LoggerInterface $log,
Redirector $redirect,
Response $response,
Request $request,
@ -66,7 +60,6 @@ class MessagesController extends BaseController
User $user
) {
$this->auth = $auth;
$this->log = $log;
$this->redirect = $redirect;
$this->response = $response;
$this->request = $request;
@ -75,37 +68,41 @@ class MessagesController extends BaseController
$this->user = $user;
}
/**
* @return Response
*/
public function index(): Response
{
return $this->listConversations();
}
/**
* Returns a list of conversations of the current user, each containing the other participant,
* Returns a list of conversations of the current user, each containing the other user,
* the most recent message, and the number of unread messages.
*/
public function listConversations(): Response
{
$current_user = $this->auth->user();
$currentUser = $this->auth->user();
$latest_messages = $this->latestMessagePerConversation($current_user);
$numberOfUnreadMessages = $this->numberOfUnreadMessagesPerConversation($current_user);
$latestMessages = $this->latestMessagePerConversation($currentUser);
$numberOfUnreadMessages = $this->numberOfUnreadMessagesPerConversation($currentUser);
$conversations = [];
foreach ($latest_messages as $msg) {
$other_user = $msg->user_id == $current_user->id ? $msg->receiver : $msg->sender;
$unread_messages = $numberOfUnreadMessages[$other_user->id] ?? 0;
array_push($conversations, [
'other_user' => $other_user,
foreach ($latestMessages as $msg) {
$otherUser = $msg->user_id == $currentUser->id ? $msg->receiver : $msg->sender;
$unreadMessages = $numberOfUnreadMessages[$otherUser->id] ?? 0;
$conversations[] = [
'other_user' => $otherUser,
'latest_message' => $msg,
'unread_messages' => $unread_messages
]);
'unread_messages' => $unreadMessages,
];
}
$users = $this->user->orderBy('name')->get()
->except($current_user->id)
->except($currentUser->id)
->mapWithKeys(function ($u) {
return [ $u->id => $u->nameWithPronoun() ];
return [ $u->id => $u->name ];
});
return $this->response->withView(
@ -118,45 +115,44 @@ class MessagesController extends BaseController
}
/**
* Forwards to the conversation with the user of the given id.
* Redirects to the conversation with the user of the given id.
*/
public function toConversation(Request $request): Response
public function redirectToConversation(Request $request): Response
{
$data = $this->validate($request, ['user_id' => 'required|int']);
return $this->redirect->to('/messages/' . $data['user_id']);
}
/**
* Returns a list of messages between the current user and a user with the given id. The ids shall not be the same.
* Unread messages will be marked as read during this call. Still, they will be shown as unread in the frontend to
* highlight them to the user as new.
* Returns a list of messages between the current user and a user with the given id. Unread messages will be marked
* as read during this call. Still, they will be shown as unread in the frontend to highlight them to the user as new.
*/
public function conversation(Request $request): Response
public function messagesOfConversation(Request $request): Response
{
$current_user = $this->auth->user();
$other_user = $this->user->findOrFail($request->getAttribute('user_id'));
$currentUser = $this->auth->user();
$otherUser = $this->user->findOrFail($request->getAttribute('user_id'));
if ($current_user->id == $other_user->id) {
if ($currentUser->id == $otherUser->id) {
throw new HttpForbidden('You can not start a conversation with yourself.');
}
$messages = $this->message
->where(function ($q) use ($current_user, $other_user) {
$q->whereUserId($current_user->id)
->whereReceiverId($other_user->id);
->where(function ($query) use ($currentUser, $otherUser) {
$query->whereUserId($currentUser->id)
->whereReceiverId($otherUser->id);
})
->orWhere(function ($q) use ($current_user, $other_user) {
$q->whereUserId($other_user->id)
->whereReceiverId($current_user->id);
->orWhere(function ($query) use ($currentUser, $otherUser) {
$query->whereUserId($otherUser->id)
->whereReceiverId($currentUser->id);
})
->orderBy('created_at')
->get();
$unread_messages = $messages->filter(function ($m) use ($other_user) {
return $m->user_id == $other_user->id && !$m->read;
$unreadMessages = $messages->filter(function ($m) use ($otherUser) {
return $m->user_id == $otherUser->id && !$m->read;
});
foreach ($unread_messages as $msg) {
foreach ($unreadMessages as $msg) {
$msg->read = true;
$msg->save();
$msg->read = false; // change back to true to display it to the frontend one more time.
@ -164,7 +160,7 @@ class MessagesController extends BaseController
return $this->response->withView(
'pages/messages/conversation.twig',
['messages' => $messages, 'other_user' => $other_user]
['messages' => $messages, 'other_user' => $otherUser]
);
}
@ -173,72 +169,50 @@ class MessagesController extends BaseController
*/
public function send(Request $request): Response
{
$current_user = $this->auth->user();
$currentUser = $this->auth->user();
$data = $this->validate($request, ['text' => 'required']);
$other_user = $this->user->findOrFail($request->getAttribute('user_id'));
$otherUser = $this->user->findOrFail($request->getAttribute('user_id'));
if ($other_user->id == $current_user->id) {
if ($otherUser->id == $currentUser->id) {
throw new HttpForbidden('You can not send a message to yourself.');
}
$new_message = new Message();
$new_message->sender()->associate($current_user);
$new_message->receiver()->associate($other_user);
$new_message->text = $data['text'];
$new_message->read = false;
$new_message->save();
$newMessage = new Message();
$newMessage->sender()->associate($currentUser);
$newMessage->receiver()->associate($otherUser);
$newMessage->text = $data['text'];
$newMessage->read = false;
$newMessage->save();
$this->log->info(
'User {from} has written a message to user {to}',
[
'from' => $current_user->id,
'to' => $other_user->id
]
);
return $this->redirect->to('/messages/' . $other_user->id);
return $this->redirect->to('/messages/' . $otherUser->id);
}
/**
* Deletes a message from a given id, as long as this message was send by the current user. The given user_id
* The given user_id is used to redirect back to the conversation with that user.
* Deletes a message with a given id, as long as this message was send by the current user.
* The given user id is used to redirect back to the conversation with that user.
*/
public function delete(Request $request): Response
{
$current_user = $this->auth->user();
$other_user_id = $request->getAttribute('user_id');
$msg_id = $request->getAttribute('msg_id');
$msg = $this->message->findOrFail($msg_id);
$currentUser = $this->auth->user();
$otherUserId = $request->getAttribute('user_id');
$msgId = $request->getAttribute('msg_id');
$msg = $this->message->findOrFail($msgId);
if ($msg->user_id == $current_user->id) {
if ($msg->user_id == $currentUser->id) {
$msg->delete();
$this->log->info(
'User {from} deleted message {msg} in a conversation with user {to}',
[
'from' => $current_user->id,
'to' => $other_user_id,
'msg' => $msg_id
]
);
} else {
$this->log->warning(
'User {from} tried to delete message {msg} which was not written by them, ' .
'in a conversation with user {to}',
[
'from' => $current_user->id,
'to' => $other_user_id,
'msg' => $msg_id
]
);
throw new HttpForbidden('You can not delete a message you haven\'t send');
}
return $this->redirect->to('/messages/' . $other_user_id);
return $this->redirect->to('/messages/' . $otherUserId);
}
/**
* Returns the overall unread messages of the current user.
*/
public function numberOfUnreadMessages(): int
{
return $this->auth->user()
@ -247,9 +221,13 @@ class MessagesController extends BaseController
->count();
}
protected function numberOfUnreadMessagesPerConversation($current_user): Collection
/**
* The number of unread messages per conversation of the current user.
* @return Collection of unread message amounts. Each object with key=other user, value=amount of unread messages
*/
protected function numberOfUnreadMessagesPerConversation($currentUser): Collection
{
return $current_user->messagesReceived()
return $currentUser->messagesReceived()
->select('user_id', $this->raw('count(*) as amount'))
->where('read', false)
->groupBy('user_id')
@ -259,25 +237,38 @@ class MessagesController extends BaseController
});
}
protected function latestMessagePerConversation($current_user): Collection
/**
* Returns the latest message for each conversation,
* which were either send by or addressed to the current user.
* @return Collection of messages
*/
protected function latestMessagePerConversation($currentUser): Collection
{
$latest_message_ids = $this->message
/* requesting the IDs first, grouped by "conversation".
The more complex grouping is required for associating the messages to the correct conversations.
Without this, a database change might have been needed to realize the "conversations" concept. */
$latestMessageIds = $this->message
->select($this->raw('max(id) as last_id'))
->where('user_id', "=", $current_user->id)
->orWhere('receiver_id', "=", $current_user->id)
->where('user_id', '=', $currentUser->id)
->orWhere('receiver_id', '=', $currentUser->id)
->groupBy($this->raw(
'(CASE WHEN user_id = ' . $current_user->id .
'(CASE WHEN user_id = ' . (int) $currentUser->id .
' THEN receiver_id ELSE user_id END)'
));
// then getting the full message objects for each ID.
return $this->message
->joinSub($latest_message_ids, 'conversations', function ($join) {
->joinSub($latestMessageIds, 'conversations', function ($join) {
$join->on('messages.id', '=', 'conversations.last_id');
})
->orderBy('created_at', 'DESC')
->get();
}
/**
* @param mixed $value
* @return QueryExpression
*/
protected function raw($value): QueryExpression
{
return $this->db->getConnection()->raw($value);

View File

@ -225,18 +225,4 @@ class User extends BaseModel
->orderBy('read')
->orderBy('id', 'DESC');
}
/**
* Return either just the user name or the name alongside with the pronoun.
* @return string
*/
public function nameWithPronoun(): string
{
if (config('enable_pronoun')) {
$pronoun = $this->personalData->pronoun;
return $pronoun ? $this->name . ' (' . $pronoun . ')' : $this->name;
} else {
return $this->name;
}
}
}

View File

@ -11,9 +11,6 @@ use Engelsystem\Http\UrlGenerator;
use Engelsystem\Http\UrlGeneratorInterface;
use Engelsystem\Http\Validation\Validator;
use Engelsystem\Models\Message;
use Engelsystem\Models\Question;
use Engelsystem\Models\User\PersonalData;
use Engelsystem\Models\User\Settings;
use Engelsystem\Models\User\User;
use Engelsystem\Test\Unit\HasDatabase;
use Illuminate\Database\Eloquent\ModelNotFoundException;
@ -44,6 +41,7 @@ class MessagesControllerTest extends ControllerTest
/**
* @testdox index: underNormalConditions -> returnsCorrectViewAndData
* @covers \Engelsystem\Controllers\MessagesController::index
*/
public function testIndexUnderNormalConditionsReturnsCorrectViewAndData()
{
@ -63,6 +61,7 @@ class MessagesControllerTest extends ControllerTest
/**
* @testdox index: otherUsersExist -> returnsUsersWithoutMeOrderedByName
* @covers \Engelsystem\Controllers\MessagesController::index
*/
public function testIndexOtherUsersExistReturnsUsersWithoutMeOrderedByName()
{
@ -80,56 +79,9 @@ class MessagesControllerTest extends ControllerTest
$this->controller->index();
}
/**
* @testdox index: pronounsDeactivated -> userListHasNoPronouns
*/
public function testIndexPronounsDeactivatedUserListHasNoPronouns()
{
$this->user_with_pronoun = User::factory(['name' => 'x'])
->has(PersonalData::factory(['pronoun' => 'X']))->create();
$this->user_without_pronoun = $this->user_b;
$this->response->expects($this->once())
->method('withView')
->willReturnCallback(function (string $view, array $data) {
$users = $data['users'];
$this->assertEquals('x', $users[$this->user_with_pronoun->id]);
$this->assertEquals('b', $users[$this->user_without_pronoun->id]);
return $this->response;
});
$this->controller->index();
}
/**
* @testdox index: pronounsActivated -> userListHasPronouns
*/
public function testIndexPronounsActivatedUserListHasPronouns()
{
config(['enable_pronoun' => true]);
$this->user_with_pronoun = User::factory(['name' => 'x'])
->has(PersonalData::factory(['pronoun' => 'X']))->create();
$this->user_without_pronoun = $this->user_b;
$this->response->expects($this->once())
->method('withView')
->willReturnCallback(function (string $view, array $data) {
$users = $data['users'];
$this->assertEquals('x (X)', $users[$this->user_with_pronoun->id]);
$this->assertEquals('b', $users[$this->user_without_pronoun->id]);
return $this->response;
});
$this->controller->index();
}
/**
* @testdox index: withNoConversation -> returnsEmptyConversationList
* @covers \Engelsystem\Controllers\MessagesController::index
*/
public function testIndexWithNoConversationReturnsEmptyConversationList()
{
@ -145,6 +97,7 @@ class MessagesControllerTest extends ControllerTest
/**
* @testdox index: withConversation -> conversationContainsCorrectData
* @covers \Engelsystem\Controllers\MessagesController::index
*/
public function testIndexWithConversationConversationContainsCorrectData()
{
@ -181,6 +134,7 @@ class MessagesControllerTest extends ControllerTest
/**
* @testdox index: withConversations -> onlyContainsConversationsWithMe
* @covers \Engelsystem\Controllers\MessagesController::index
*/
public function testIndexWithConversationsOnlyContainsConversationsWithMe()
{
@ -209,6 +163,7 @@ class MessagesControllerTest extends ControllerTest
/**
* @testdox index: withConversations -> conversationsOrderedByDate
* @covers \Engelsystem\Controllers\MessagesController::index
*/
public function testIndexWithConversationsConversationsOrderedByDate()
{
@ -235,18 +190,20 @@ class MessagesControllerTest extends ControllerTest
}
/**
* @testdox ToConversation: withNoUserIdGiven -> throwsException
* @testdox redirectToConversation: withNoUserIdGiven -> throwsException
* @covers \Engelsystem\Controllers\MessagesController::redirectToConversation
*/
public function testToConversationWithNoUserIdGivenThrowsException()
public function testRedirectToConversationWithNoUserIdGivenThrowsException()
{
$this->expectException(ValidationException::class);
$this->controller->toConversation($this->request);
$this->controller->redirectToConversation($this->request);
}
/**
* @testdox ToConversation: withUserIdGiven -> redirect
* @testdox redirectToConversation: withUserIdGiven -> redirect
* @covers \Engelsystem\Controllers\MessagesController::redirectToConversation
*/
public function testToConversationWithUserIdGivenRedirect()
public function testRedirectToConversationWithUserIdGivenRedirect()
{
$this->request = $this->request->withParsedBody([
'user_id' => '1',
@ -256,42 +213,47 @@ class MessagesControllerTest extends ControllerTest
->with('http://localhost/messages/1')
->willReturn($this->response);
$this->controller->toConversation($this->request);
$this->controller->redirectToConversation($this->request);
}
/**
* @testdox conversation: withNoUserIdGiven -> throwsException
* @testdox messagesOfConversation: withNoUserIdGiven -> throwsException
* @covers \Engelsystem\Controllers\MessagesController::messagesOfConversation
*/
public function testConversationWithNoUserIdGivenThrowsException()
public function testMessagesOfConversationWithNoUserIdGivenThrowsException()
{
$this->expectException(ModelNotFoundException::class);
$this->controller->conversation($this->request);
$this->controller->messagesOfConversation($this->request);
}
/**
* @testdox conversation: withMyUserIdGiven -> throwsException
* @testdox messagesOfConversation: withMyUserIdGiven -> throwsException
* @covers \Engelsystem\Controllers\MessagesController::messagesOfConversation
*/
public function testConversationWithMyUserIdGivenThrowsException()
public function testMessagesOfConversationWithMyUserIdGivenThrowsException()
{
$this->request->attributes->set('user_id', $this->user_a->id);
$this->expectException(HttpForbidden::class);
$this->controller->conversation($this->request);
$this->controller->messagesOfConversation($this->request);
}
/**
* @testdox conversation: withUnknownUserIdGiven -> throwsException
* @testdox messagesOfConversation: withUnknownUserIdGiven -> throwsException
* @covers \Engelsystem\Controllers\MessagesController::messagesOfConversation
*/
public function testConversationWithUnknownUserIdGivenThrowsException()
public function testMessagesOfConversationWithUnknownUserIdGivenThrowsException()
{
$this->request->attributes->set('user_id', '1234');
$this->expectException(ModelNotFoundException::class);
$this->controller->conversation($this->request);
$this->controller->messagesOfConversation($this->request);
}
/**
* @testdox conversation: underNormalConditions -> returnsCorrectViewAndData
* @testdox messagesOfConversation: underNormalConditions -> returnsCorrectViewAndData
* @covers \Engelsystem\Controllers\MessagesController::messagesOfConversation
*/
public function testConversationUnderNormalConditionsReturnsCorrectViewAndData()
public function testMessagesOfConversationUnderNormalConditionsReturnsCorrectViewAndData()
{
$this->request->attributes->set('user_id', $this->user_b->id);
@ -306,13 +268,14 @@ class MessagesControllerTest extends ControllerTest
return $this->response;
});
$this->controller->conversation($this->request);
$this->controller->messagesOfConversation($this->request);
}
/**
* @testdox conversation: withNoMessages -> returnsEmptyMessageList
* @testdox messagesOfConversation: withNoMessages -> returnsEmptyMessageList
* @covers \Engelsystem\Controllers\MessagesController::messagesOfConversation
*/
public function testConversationWithNoMessagesReturnsEmptyMessageList()
public function testMessagesOfConversationWithNoMessagesReturnsEmptyMessageList()
{
$this->request->attributes->set('user_id', $this->user_b->id);
@ -323,13 +286,14 @@ class MessagesControllerTest extends ControllerTest
return $this->response;
});
$this->controller->conversation($this->request);
$this->controller->messagesOfConversation($this->request);
}
/**
* @testdox conversation: withMessages -> messagesOnlyWithThatUserOrderedByDate
* @testdox messagesOfConversation: withMessages -> messagesOnlyWithThatUserOrderedByDate
* @covers \Engelsystem\Controllers\MessagesController::messagesOfConversation
*/
public function testConversationWithMessagesMessagesOnlyWithThatUserOrderedByDate()
public function testMessagesOfConversationWithMessagesMessagesOnlyWithThatUserOrderedByDate()
{
$this->request->attributes->set('user_id', $this->user_b->id);
@ -356,13 +320,14 @@ class MessagesControllerTest extends ControllerTest
return $this->response;
});
$this->controller->conversation($this->request);
$this->controller->messagesOfConversation($this->request);
}
/**
* @testdox conversation: withUnreadMessages -> messagesToMeWillStillBeReturnedAsUnread
* @testdox messagesOfConversation: withUnreadMessages -> messagesToMeWillStillBeReturnedAsUnread
* @covers \Engelsystem\Controllers\MessagesController::messagesOfConversation
*/
public function testConversationWithUnreadMessagesMessagesToMeWillStillBeReturnedAsUnread()
public function testMessagesOfConversationWithUnreadMessagesMessagesToMeWillStillBeReturnedAsUnread()
{
$this->request->attributes->set('user_id', $this->user_b->id);
$this->createMessage($this->user_b, $this->user_a, 'b>a', $this->now);
@ -373,13 +338,14 @@ class MessagesControllerTest extends ControllerTest
$this->assertFalse($data['messages'][0]->read);
return $this->response;
});
$this->controller->conversation($this->request);
$this->controller->messagesOfConversation($this->request);
}
/**
* @testdox conversation: withUnreadMessages -> messagesToMeWillBeMarkedAsRead
* @testdox messagesOfConversation: withUnreadMessages -> messagesToMeWillBeMarkedAsRead
* @covers \Engelsystem\Controllers\MessagesController::messagesOfConversation
*/
public function testConversationWithUnreadMessagesMessagesToMeWillBeMarkedAsRead()
public function testMessagesOfConversationWithUnreadMessagesMessagesToMeWillBeMarkedAsRead()
{
$this->request->attributes->set('user_id', $this->user_b->id);
$this->response->expects($this->once())
@ -389,12 +355,13 @@ class MessagesControllerTest extends ControllerTest
});
$msg = $this->createMessage($this->user_b, $this->user_a, 'b>a', $this->now);
$this->controller->conversation($this->request);
$this->controller->messagesOfConversation($this->request);
$this->assertTrue(Message::whereId($msg->id)->first()->read);
}
/**
* @testdox send: withNoTextGiven -> throwsException
* @covers \Engelsystem\Controllers\MessagesController::send
*/
public function testSendWithNoTextGivenThrowsException()
{
@ -404,6 +371,7 @@ class MessagesControllerTest extends ControllerTest
/**
* @testdox send: withNoUserIdGiven -> throwsException
* @covers \Engelsystem\Controllers\MessagesController::send
*/
public function testSendWithNoUserIdGivenThrowsException()
{
@ -416,6 +384,7 @@ class MessagesControllerTest extends ControllerTest
/**
* @testdox send: withMyUserIdGiven -> throwsException
* @covers \Engelsystem\Controllers\MessagesController::send
*/
public function testSendWithMyUserIdGivenThrowsException()
{
@ -424,11 +393,13 @@ class MessagesControllerTest extends ControllerTest
]);
$this->request->attributes->set('user_id', $this->user_a->id);
$this->expectException(HttpForbidden::class);
$this->controller->send($this->request);
}
/**
* @testdox send: withUnknownUserIdGiven -> throwsException
* @covers \Engelsystem\Controllers\MessagesController::send
*/
public function testSendWithUnknownUserIdGivenThrowsException()
{
@ -442,6 +413,7 @@ class MessagesControllerTest extends ControllerTest
/**
* @testdox send: withUserAndTextGiven -> savesMessage
* @covers \Engelsystem\Controllers\MessagesController::send
*/
public function testSendWithUserAndTextGivenSavesMessage()
{
@ -465,6 +437,7 @@ class MessagesControllerTest extends ControllerTest
/**
* @testdox delete: withNoMsgIdGiven -> throwsException
* @covers \Engelsystem\Controllers\MessagesController::delete
*/
public function testDeleteWithNoMsgIdGivenThrowsException()
{
@ -474,19 +447,20 @@ class MessagesControllerTest extends ControllerTest
/**
* @testdox delete: tryingToDeleteSomeonesMessage -> throwsException
* @covers \Engelsystem\Controllers\MessagesController::delete
*/
public function testDeleteTryingToDeleteSomeonesMessageThrowsException()
{
$this->expectException(HttpForbidden::class);
$msg = $this->createMessage($this->user_b, $this->user_a, 'a>b', $this->now);
$this->request->attributes->set('msg_id', $msg->id);
$this->expectException(HttpForbidden::class);
$this->controller->delete($this->request);
}
/**
* @testdox delete: tryingToDeleteMyMessage -> deletesItAndRedirect
* @covers \Engelsystem\Controllers\MessagesController::delete
*/
public function testDeleteTryingToDeleteMyMessageDeletesItAndRedirect()
{
@ -506,6 +480,7 @@ class MessagesControllerTest extends ControllerTest
/**
* @testdox NumberOfUnreadMessages: withNoMessages -> returns0
* @covers \Engelsystem\Controllers\MessagesController::numberOfUnreadMessages
*/
public function testNumberOfUnreadMessagesWithNoMessagesReturns0()
{
@ -514,6 +489,7 @@ class MessagesControllerTest extends ControllerTest
/**
* @testdox NumberOfUnreadMessages: withMessagesNotToMe -> messagesNotToMeAreIgnored
* @covers \Engelsystem\Controllers\MessagesController::numberOfUnreadMessages
*/
public function testNumberOfUnreadMessagesWithMessagesNotToMeMessagesNotToMeAreIgnored()
{
@ -526,6 +502,7 @@ class MessagesControllerTest extends ControllerTest
/**
* @testdox NumberOfUnreadMessages: withMessages -> returnsSumOfUnreadMessagesSentToMe
* @covers \Engelsystem\Controllers\MessagesController::numberOfUnreadMessages
*/
public function testNumberOfUnreadMessagesWithMessagesReturnsSumOfUnreadMessagesSentToMe()
{

View File

@ -4,7 +4,6 @@ namespace Engelsystem\Test\Unit\Models\User;
use Carbon\Carbon;
use DMS\PHPUnitExtensions\ArraySubset\ArraySubsetAsserts;
use Engelsystem\Config\Config;
use Engelsystem\Models\BaseModel;
use Engelsystem\Models\News;
use Engelsystem\Models\NewsComment;
@ -277,45 +276,4 @@ class UserTest extends ModelTest
$this->assertContains($question1->id, $answers);
$this->assertContains($question2->id, $answers);
}
/**
* @testdox nameWithPronoun: pronounsDeactivated -> returnNameOnly
*/
public function testNameWithPronounPronounsDeactivatedReturnNameOnly()
{
$user_with_pronoun = User::factory(['name' => 'x'])
->has(PersonalData::factory(['pronoun' => 'X']))->create();
$user_without_pronoun = User::factory(['name' => 'y'])->create();
$this->assertEquals('x', $user_with_pronoun->nameWithPronoun());
$this->assertEquals('y', $user_without_pronoun->nameWithPronoun());
}
/**
* @testdox nameWithPronoun: pronounsActivated -> returnNameAndPronoun
*/
public function testNameWithPronounPronounsActivatedReturnNameAndPronoun()
{
config(['enable_pronoun' => true]);
$user_with_pronoun = User::factory(['name' => 'x'])
->has(PersonalData::factory(['pronoun' => 'X']))->create();
$user_without_pronoun = User::factory(['name' => 'y'])->create();
$this->assertEquals('x (X)', $user_with_pronoun->nameWithPronoun());
$this->assertEquals('y', $user_without_pronoun->nameWithPronoun());
}
/**
* Prepare test
*/
protected function setUp(): void
{
parent::setUp();
// config needed for checking if pronouns are activated.
$config = new Config();
$this->app->instance('config', $config);
$this->app->instance(Config::class, $config);
}
}