Agenda templates
- Added manage controls for list of speakers of agenda items. - New slide for list of speakers. - Fixed typo (speach -> speech)
This commit is contained in:
parent
6acdb3c305
commit
77d027c1cc
@ -377,7 +377,7 @@ class Speaker(RESTModelMixin, models.Model):
|
|||||||
|
|
||||||
end_time = models.DateTimeField(null=True)
|
end_time = models.DateTimeField(null=True)
|
||||||
"""
|
"""
|
||||||
Saves the time, when the speaker ends his speach. None, if he is not finished yet.
|
Saves the time, when the speaker ends his speech. None, if he is not finished yet.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
weight = models.IntegerField(null=True)
|
weight = models.IntegerField(null=True)
|
||||||
@ -393,19 +393,19 @@ class Speaker(RESTModelMixin, models.Model):
|
|||||||
def __str__(self):
|
def __str__(self):
|
||||||
return str(self.user)
|
return str(self.user)
|
||||||
|
|
||||||
def begin_speach(self):
|
def begin_speech(self):
|
||||||
"""
|
"""
|
||||||
Let the user speak.
|
Let the user speak.
|
||||||
|
|
||||||
Set the weight to None and the time to now. If anyone is still
|
Set the weight to None and the time to now. If anyone is still
|
||||||
speaking, end his speach.
|
speaking, end his speech.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
actual_speaker = Speaker.objects.filter(item=self.item, end_time=None).exclude(begin_time=None).get()
|
actual_speaker = Speaker.objects.filter(item=self.item, end_time=None).exclude(begin_time=None).get()
|
||||||
except Speaker.DoesNotExist:
|
except Speaker.DoesNotExist:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
actual_speaker.end_speach()
|
actual_speaker.end_speech()
|
||||||
self.weight = None
|
self.weight = None
|
||||||
self.begin_time = datetime.now()
|
self.begin_time = datetime.now()
|
||||||
self.save()
|
self.save()
|
||||||
@ -416,9 +416,9 @@ class Speaker(RESTModelMixin, models.Model):
|
|||||||
# start_countdown()
|
# start_countdown()
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def end_speach(self):
|
def end_speech(self):
|
||||||
"""
|
"""
|
||||||
The speach is finished. Set the time to now.
|
The speech is finished. Set the time to now.
|
||||||
"""
|
"""
|
||||||
self.end_time = datetime.now()
|
self.end_time = datetime.now()
|
||||||
self.save()
|
self.save()
|
||||||
|
@ -81,7 +81,7 @@ class ItemDetailSlide(ProjectorElement):
|
|||||||
view_class=ItemViewSet,
|
view_class=ItemViewSet,
|
||||||
view_action='retrieve',
|
view_action='retrieve',
|
||||||
pk=str(item.pk))
|
pk=str(item.pk))
|
||||||
for speaker in item.speaker_set.all():
|
for speaker in item.speakers.all():
|
||||||
yield ProjectorRequirement(
|
yield ProjectorRequirement(
|
||||||
view_class=speaker.user.get_view_class(),
|
view_class=speaker.user.get_view_class(),
|
||||||
view_action='retrieve',
|
view_action='retrieve',
|
||||||
|
@ -48,7 +48,7 @@ def setup_agenda_config(sender, **kwargs):
|
|||||||
default_value=False,
|
default_value=False,
|
||||||
input_type='boolean',
|
input_type='boolean',
|
||||||
label=ugettext_lazy('Couple countdown with the list of speakers'),
|
label=ugettext_lazy('Couple countdown with the list of speakers'),
|
||||||
help_text=ugettext_lazy('[Begin speach] starts the countdown, [End speach] stops the countdown.'),
|
help_text=ugettext_lazy('[Begin speech] starts the countdown, [End speech] stops the countdown.'),
|
||||||
weight=230,
|
weight=230,
|
||||||
group=ugettext_lazy('Agenda'))
|
group=ugettext_lazy('Agenda'))
|
||||||
|
|
||||||
|
@ -181,7 +181,7 @@ angular.module('OpenSlidesApp.agenda.site', ['OpenSlidesApp.agenda'])
|
|||||||
|
|
||||||
// close/open list of speakers of current item
|
// close/open list of speakers of current item
|
||||||
$scope.closeList = function (listClosed) {
|
$scope.closeList = function (listClosed) {
|
||||||
item.speakerListClosed = listClosed;
|
item.speaker_list_closed = listClosed;
|
||||||
Agenda.save(item);
|
Agenda.save(item);
|
||||||
};
|
};
|
||||||
// add user to list of speakers
|
// add user to list of speakers
|
||||||
@ -198,7 +198,34 @@ angular.module('OpenSlidesApp.agenda.site', ['OpenSlidesApp.agenda'])
|
|||||||
$scope.removeSpeaker = function (speakerId) {
|
$scope.removeSpeaker = function (speakerId) {
|
||||||
$http.delete('/rest/agenda/item/' + item.id + '/manage_speaker/',
|
$http.delete('/rest/agenda/item/' + item.id + '/manage_speaker/',
|
||||||
{headers: {'Content-Type': 'application/json'},
|
{headers: {'Content-Type': 'application/json'},
|
||||||
data: JSON.stringify({speaker: speakerId})});
|
data: JSON.stringify({speaker: speakerId})})
|
||||||
|
.error(function(data){
|
||||||
|
$scope.alert = { type: 'danger', msg: data.detail, show: true };
|
||||||
|
});
|
||||||
|
};
|
||||||
|
// begin speech of selected/next speaker
|
||||||
|
$scope.beginSpeech = function (speakerId) {
|
||||||
|
$http.put('/rest/agenda/item/' + item.id + '/speak/', {'speaker': speakerId})
|
||||||
|
.success(function(data){
|
||||||
|
$scope.alert.show = false;
|
||||||
|
})
|
||||||
|
.error(function(data){
|
||||||
|
$scope.alert = { type: 'danger', msg: data.detail, show: true };
|
||||||
|
});
|
||||||
|
};
|
||||||
|
// end speech of current speaker
|
||||||
|
$scope.endSpeech = function () {
|
||||||
|
$http.delete('/rest/agenda/item/' + item.id + '/speak/',
|
||||||
|
{headers: {'Content-Type': 'application/json'},
|
||||||
|
data: JSON.stringify()})
|
||||||
|
.error(function(data){
|
||||||
|
$scope.alert = { type: 'danger', msg: data.detail, show: true };
|
||||||
|
});
|
||||||
|
};
|
||||||
|
// project list of speakers
|
||||||
|
$scope.projectListOfSpeakers = function () {
|
||||||
|
$http.post('/rest/core/projector/1/prune_elements/',
|
||||||
|
[{name: 'agenda/item', id: item.id, list_of_speakers: true}]);
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -301,15 +328,22 @@ angular.module('OpenSlidesApp.agenda.projector', ['OpenSlidesApp.agenda'])
|
|||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
|
||||||
.controller('SlideItemDetailCtrl', function($scope, Agenda) {
|
.controller('SlideItemDetailCtrl', [
|
||||||
|
'$scope',
|
||||||
|
'Agenda',
|
||||||
|
'User',
|
||||||
|
function($scope, Agenda, User) {
|
||||||
// Attention! Each object that is used here has to be dealt on server side.
|
// Attention! Each object that is used here has to be dealt on server side.
|
||||||
// Add it to the coresponding get_requirements method of the ProjectorElement
|
// Add it to the coresponding get_requirements method of the ProjectorElement
|
||||||
// class.
|
// class.
|
||||||
var id = $scope.element.context.id;
|
var id = $scope.element.context.id;
|
||||||
Agenda.find(id);
|
Agenda.find(id);
|
||||||
|
User.findAll();
|
||||||
Agenda.bindOne(id, $scope, 'item');
|
Agenda.bindOne(id, $scope, 'item');
|
||||||
|
// get flag for list-of-speakers-slide (true/false)
|
||||||
})
|
$scope.is_list_of_speakers = $scope.element.context.list_of_speakers;
|
||||||
|
}
|
||||||
|
])
|
||||||
|
|
||||||
.controller('SlideItemListCtrl', function($scope, $http, Agenda) {
|
.controller('SlideItemListCtrl', function($scope, $http, Agenda) {
|
||||||
// Attention! Each object that is used here has to be dealt on server side.
|
// Attention! Each object that is used here has to be dealt on server side.
|
||||||
|
@ -23,50 +23,81 @@
|
|||||||
<div class="white-space-pre-line">{{ item.text }}</div>
|
<div class="white-space-pre-line">{{ item.text }}</div>
|
||||||
|
|
||||||
<div os-perm="agenda.can_manage">
|
<div os-perm="agenda.can_manage">
|
||||||
<h3 os-perm="agenda.can_manage" translate>Duration</h3>
|
<h2 os-perm="agenda.can_manage" translate>Duration</h2>
|
||||||
{{ item.duration }}
|
{{ item.duration }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div os-perm="agenda.can_manage">
|
<div os-perm="agenda.can_manage">
|
||||||
<h3 os-perm="agenda.can_manage" translate>Comment</h3>
|
<h2 os-perm="agenda.can_manage" translate>Comment</h2>
|
||||||
<div class="white-space-pre-line">{{ item.comment }}</div>
|
<div class="white-space-pre-line">{{ item.comment }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<h3 translate>List of speakers
|
<h2 translate>List of speakers
|
||||||
<span ng-if="item.speakerListClosed" class="label label-danger" translate>closed</span>
|
|
||||||
<span os-perms="agenda.can_manage">
|
<span os-perms="agenda.can_manage">
|
||||||
<button ng-if="item.speakerListClosed" ng-click="closeList(false)"
|
<button ng-if="item.speaker_list_closed" ng-click="closeList(false)"
|
||||||
class="btn btn-sm btn-default" translate>
|
class="btn btn-sm btn-danger" translate>
|
||||||
Open list
|
Closed
|
||||||
</button>
|
</button>
|
||||||
<button ng-if="!item.speakerListClosed" ng-click="closeList(true)"
|
<button ng-if="!item.speaker_list_closed" ng-click="closeList(true)"
|
||||||
class="btn btn-sm btn-default" translate>
|
class="btn btn-sm btn-success" translate>
|
||||||
Close list
|
Opened
|
||||||
</button>
|
</button>
|
||||||
</span>
|
</span>
|
||||||
</h3>
|
<!-- project list -->
|
||||||
|
<a os-perms="core.can_manage_projector" class="btn btn-default btn-sm"
|
||||||
|
ng-class="{ 'btn-primary': item.isProjected() }"
|
||||||
|
ng-click="projectListOfSpeakers()">
|
||||||
|
<i class="fa fa-video-camera"></i> Project list
|
||||||
|
</a>
|
||||||
|
</h2>
|
||||||
|
|
||||||
<!-- TODO:
|
<!-- TODO:
|
||||||
* project list
|
* show only 'add me' OR 'remove me' button
|
||||||
* show old/current/next speakers
|
|
||||||
* start/stop speech
|
|
||||||
* button 'put/remove me on/from the list'
|
|
||||||
* check permissions
|
|
||||||
-->
|
-->
|
||||||
|
<div class="well">
|
||||||
|
<button class="btn btn-default btn-xs" type="button"
|
||||||
|
data-toggle="collapse" data-target="#old_speakers"
|
||||||
|
aria-expanded="false" aria-controls="collapseExample">
|
||||||
|
Show all old speakers
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<div class="collapse" id="old_speakers">
|
||||||
|
<h3 translate>Old speakers:</h3>
|
||||||
<ol>
|
<ol>
|
||||||
<li ng-repeat="speaker in item.speakers">
|
<li ng-repeat="speaker in item.speakers | filter: {end_time: '!!'}">
|
||||||
|
{{ speaker.user.get_full_name() }}
|
||||||
|
<small class="grey">
|
||||||
|
[{{speaker.begin_time | date:'yyyy-MM-dd HH:mm:ss'}} –
|
||||||
|
{{speaker.end_time | date:'yyyy-MM-dd HH:mm:ss'}}]
|
||||||
|
</small>
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h3 translate>Current speaker:</h3>
|
||||||
|
<strong ng-repeat="speaker in item.speakers | filter: {end_time: null, begin_time: '!!'}">
|
||||||
|
{{ speaker.user.get_full_name() }}
|
||||||
|
</strong>
|
||||||
|
|
||||||
|
<h3 translate>Next speakers:</h3>
|
||||||
|
<ol>
|
||||||
|
<li ng-repeat="speaker in item.speakers | filter: {begin_time: null}">
|
||||||
{{ speaker.user.get_full_name() }}
|
{{ speaker.user.get_full_name() }}
|
||||||
<button os-perms="agenda.can_manage" ng-click="removeSpeaker(speaker.id)"
|
<button os-perms="agenda.can_manage" ng-click="removeSpeaker(speaker.id)"
|
||||||
class="btn btn-default btn-xs">
|
class="btn btn-default btn-xs">
|
||||||
<i class="fa fa-times"></i>
|
<i class="fa fa-times"></i>
|
||||||
</button>
|
</button>
|
||||||
</li>
|
<button os-perms="agenda.can_manage" ng-click="beginSpeech(speaker.id)"
|
||||||
|
class="btn btn-default btn-xs">
|
||||||
|
<i class="fa fa-play"></i>
|
||||||
|
</button>
|
||||||
</ol>
|
</ol>
|
||||||
|
|
||||||
<div os-perms="agenda.can_manage" class="form-group col-sm-6">
|
<div class="form-group">
|
||||||
<alert ng-show="alert.show" type="{{ alert.type }}" ng-click="alert={}" close="alert={}">{{ alert.msg }}</alert>
|
<alert ng-show="alert.show" type="{{ alert.type }}" ng-click="alert={}" close="alert={}">
|
||||||
<div class="input-group">
|
{{alert.msg}}
|
||||||
|
</alert>
|
||||||
|
<div os-perms="agenda.can_manage" class="input-group">
|
||||||
<ui-select ng-model="speaker.selected" ng-change="addSpeaker(speaker.selected.id)">
|
<ui-select ng-model="speaker.selected" ng-change="addSpeaker(speaker.selected.id)">
|
||||||
<ui-select-match placeholder="{{ 'Select or search a participant...' | translate }}">
|
<ui-select-match placeholder="{{ 'Select or search a participant...' | translate }}">
|
||||||
{{ $select.selected.get_full_name() }}
|
{{ $select.selected.get_full_name() }}
|
||||||
@ -81,4 +112,25 @@
|
|||||||
</a>
|
</a>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
<p os-perm="agenda.can_be_speaker">
|
||||||
|
<button ng-click="addSpeaker()" class="btn btn-default">
|
||||||
|
<i class="fa fa-plus"></i>
|
||||||
|
<translate>Add me</translate>
|
||||||
|
</button>
|
||||||
|
<button ng-click="removeSpeaker()" class="btn btn-default">
|
||||||
|
<i class="fa fa-minus"></i>
|
||||||
|
<translate>Remove me</translate>
|
||||||
|
</button>
|
||||||
|
<p os-perms="agenda.can_manage">
|
||||||
|
<button ng-click="beginSpeech()"
|
||||||
|
class="btn btn-primary">
|
||||||
|
<i class="fa fa-play"></i>
|
||||||
|
<translate>Start next speaker</translate>
|
||||||
|
</button>
|
||||||
|
<button ng-click="endSpeech()"
|
||||||
|
class="btn btn-default">
|
||||||
|
<i class="fa fa-stop"></i>
|
||||||
|
<translate>Stop current speaker</translate>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,4 +1,27 @@
|
|||||||
<div ng-controller="SlideItemDetailCtrl" class="content">
|
<div ng-controller="SlideItemDetailCtrl" class="content">
|
||||||
<h1>{{ item.title }}</h1>
|
<h1>
|
||||||
<div class="white-space-pre-line">{{ item.text }}</div>
|
{{ item.title }}
|
||||||
|
<small ng-if="is_list_of_speakers">
|
||||||
|
<span translate>List of speakers</span>
|
||||||
|
<span ng-if="item.speaker_list_closed" class="label label-danger" translate>Closed</span>
|
||||||
|
</small>
|
||||||
|
</h1>
|
||||||
|
<!-- Item text -->
|
||||||
|
<div ng-if="!is_list_of_speakers" class="white-space-pre-line">{{ item.text }}</div>
|
||||||
|
|
||||||
|
<!-- List of speakers -->
|
||||||
|
<div ng-if="is_list_of_speakers">
|
||||||
|
<!-- TODO: show last old speakers -->
|
||||||
|
|
||||||
|
<!-- current speaker -->
|
||||||
|
<p>
|
||||||
|
<strong ng-repeat="speaker in item.speakers | filter: {end_time: null, begin_time: '!!'}">
|
||||||
|
{{ speaker.user.get_full_name() }}
|
||||||
|
</strong>
|
||||||
|
<!-- next speakers -->
|
||||||
|
<ol id="list_of_speakers">
|
||||||
|
<li ng-repeat="speaker in item.speakers | filter: {begin_time: null}">
|
||||||
|
{{ speaker.user.get_full_name() }}
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -152,9 +152,9 @@ class ItemViewSet(ModelViewSet):
|
|||||||
@detail_route(methods=['PUT', 'DELETE'])
|
@detail_route(methods=['PUT', 'DELETE'])
|
||||||
def speak(self, request, pk=None):
|
def speak(self, request, pk=None):
|
||||||
"""
|
"""
|
||||||
Special view endpoint to begin and end speach of speakers. Send PUT
|
Special view endpoint to begin and end speech of speakers. Send PUT
|
||||||
{'speaker': <speaker_id>} to begin speach. Omit data to begin speach of
|
{'speaker': <speaker_id>} to begin speech. Omit data to begin speech of
|
||||||
the next speaker. Send DELETE to end speach of current speaker.
|
the next speaker. Send DELETE to end speech of current speaker.
|
||||||
"""
|
"""
|
||||||
# Retrieve item.
|
# Retrieve item.
|
||||||
item = self.get_object()
|
item = self.get_object()
|
||||||
@ -171,21 +171,21 @@ class ItemViewSet(ModelViewSet):
|
|||||||
speaker = Speaker.objects.get(pk=int(speaker_id))
|
speaker = Speaker.objects.get(pk=int(speaker_id))
|
||||||
except (ValueError, Speaker.DoesNotExist):
|
except (ValueError, Speaker.DoesNotExist):
|
||||||
raise ValidationError({'detail': _('Speaker does not exist.')})
|
raise ValidationError({'detail': _('Speaker does not exist.')})
|
||||||
speaker.begin_speach()
|
speaker.begin_speech()
|
||||||
message = _('User is now speaking.')
|
message = _('User is now speaking.')
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# request.method == 'DELETE'
|
# request.method == 'DELETE'
|
||||||
try:
|
try:
|
||||||
# We assume that there aren't multiple entries because this
|
# We assume that there aren't multiple entries because this
|
||||||
# is forbidden by the Model's begin_speach method. We assume that
|
# is forbidden by the Model's begin_speech method. We assume that
|
||||||
# there is only one speaker instance or none.
|
# there is only one speaker instance or none.
|
||||||
current_speaker = Speaker.objects.filter(item=item, end_time=None).exclude(begin_time=None).get()
|
current_speaker = Speaker.objects.filter(item=item, end_time=None).exclude(begin_time=None).get()
|
||||||
except Speaker.DoesNotExist:
|
except Speaker.DoesNotExist:
|
||||||
raise ValidationError(
|
raise ValidationError(
|
||||||
{'detail': _('There is no one speaking at the moment according to %(item)s.') % {'item': item}})
|
{'detail': _('There is no one speaking at the moment according to %(item)s.') % {'item': item}})
|
||||||
current_speaker.end_speach()
|
current_speaker.end_speech()
|
||||||
message = _('The speach is finished now.')
|
message = _('The speech is finished now.')
|
||||||
|
|
||||||
# Initiate response.
|
# Initiate response.
|
||||||
return Response({'detail': message})
|
return Response({'detail': message})
|
||||||
|
@ -125,7 +125,7 @@ class ManageSpeaker(TestCase):
|
|||||||
|
|
||||||
class Speak(TestCase):
|
class Speak(TestCase):
|
||||||
"""
|
"""
|
||||||
Tests view to begin or end speach.
|
Tests view to begin or end speech.
|
||||||
"""
|
"""
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.client = APIClient()
|
self.client = APIClient()
|
||||||
@ -135,7 +135,7 @@ class Speak(TestCase):
|
|||||||
username='test_user_Aigh4vohb3seecha4aa4',
|
username='test_user_Aigh4vohb3seecha4aa4',
|
||||||
password='test_password_eneupeeVo5deilixoo8j')
|
password='test_password_eneupeeVo5deilixoo8j')
|
||||||
|
|
||||||
def test_begin_speach(self):
|
def test_begin_speech(self):
|
||||||
Speaker.objects.add(self.user, self.item)
|
Speaker.objects.add(self.user, self.item)
|
||||||
speaker = Speaker.objects.add(get_user_model().objects.get(username='admin'), self.item)
|
speaker = Speaker.objects.add(get_user_model().objects.get(username='admin'), self.item)
|
||||||
self.assertTrue(Speaker.objects.get(pk=speaker.pk).begin_time is None)
|
self.assertTrue(Speaker.objects.get(pk=speaker.pk).begin_time is None)
|
||||||
@ -145,7 +145,7 @@ class Speak(TestCase):
|
|||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 200)
|
||||||
self.assertFalse(Speaker.objects.get(pk=speaker.pk).begin_time is None)
|
self.assertFalse(Speaker.objects.get(pk=speaker.pk).begin_time is None)
|
||||||
|
|
||||||
def test_begin_speach_next_speaker(self):
|
def test_begin_speech_next_speaker(self):
|
||||||
speaker = Speaker.objects.add(self.user, self.item)
|
speaker = Speaker.objects.add(self.user, self.item)
|
||||||
Speaker.objects.add(get_user_model().objects.get(username='admin'), self.item)
|
Speaker.objects.add(get_user_model().objects.get(username='admin'), self.item)
|
||||||
|
|
||||||
@ -154,27 +154,27 @@ class Speak(TestCase):
|
|||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 200)
|
||||||
self.assertFalse(Speaker.objects.get(pk=speaker.pk).begin_time is None)
|
self.assertFalse(Speaker.objects.get(pk=speaker.pk).begin_time is None)
|
||||||
|
|
||||||
def test_begin_speach_invalid_speaker_id(self):
|
def test_begin_speech_invalid_speaker_id(self):
|
||||||
response = self.client.put(
|
response = self.client.put(
|
||||||
reverse('item-speak', args=[self.item.pk]),
|
reverse('item-speak', args=[self.item.pk]),
|
||||||
{'speaker': '1'})
|
{'speaker': '1'})
|
||||||
self.assertEqual(response.status_code, 400)
|
self.assertEqual(response.status_code, 400)
|
||||||
|
|
||||||
def test_begin_speach_invalid_data(self):
|
def test_begin_speech_invalid_data(self):
|
||||||
response = self.client.put(
|
response = self.client.put(
|
||||||
reverse('item-speak', args=[self.item.pk]),
|
reverse('item-speak', args=[self.item.pk]),
|
||||||
{'speaker': 'invalid'})
|
{'speaker': 'invalid'})
|
||||||
self.assertEqual(response.status_code, 400)
|
self.assertEqual(response.status_code, 400)
|
||||||
|
|
||||||
def test_end_speach(self):
|
def test_end_speech(self):
|
||||||
speaker = Speaker.objects.add(get_user_model().objects.get(username='admin'), self.item)
|
speaker = Speaker.objects.add(get_user_model().objects.get(username='admin'), self.item)
|
||||||
speaker.begin_speach()
|
speaker.begin_speech()
|
||||||
self.assertFalse(Speaker.objects.get(pk=speaker.pk).begin_time is None)
|
self.assertFalse(Speaker.objects.get(pk=speaker.pk).begin_time is None)
|
||||||
self.assertTrue(Speaker.objects.get(pk=speaker.pk).end_time is None)
|
self.assertTrue(Speaker.objects.get(pk=speaker.pk).end_time is None)
|
||||||
response = self.client.delete(reverse('item-speak', args=[self.item.pk]))
|
response = self.client.delete(reverse('item-speak', args=[self.item.pk]))
|
||||||
self.assertEqual(response.status_code, 200)
|
self.assertEqual(response.status_code, 200)
|
||||||
self.assertFalse(Speaker.objects.get(pk=speaker.pk).end_time is None)
|
self.assertFalse(Speaker.objects.get(pk=speaker.pk).end_time is None)
|
||||||
|
|
||||||
def test_end_speach_no_current_speaker(self):
|
def test_end_speech_no_current_speaker(self):
|
||||||
response = self.client.delete(reverse('item-speak', args=[self.item.pk]))
|
response = self.client.delete(reverse('item-speak', args=[self.item.pk]))
|
||||||
self.assertEqual(response.status_code, 400)
|
self.assertEqual(response.status_code, 400)
|
||||||
|
@ -46,18 +46,18 @@ class ListOfSpeakerModelTests(TestCase):
|
|||||||
speaker1_item1 = Speaker.objects.add(self.speaker1, self.item1)
|
speaker1_item1 = Speaker.objects.add(self.speaker1, self.item1)
|
||||||
self.assertIsNone(speaker1_item1.begin_time)
|
self.assertIsNone(speaker1_item1.begin_time)
|
||||||
self.assertIsNone(speaker1_item1.end_time)
|
self.assertIsNone(speaker1_item1.end_time)
|
||||||
speaker1_item1.begin_speach()
|
speaker1_item1.begin_speech()
|
||||||
self.assertIsNotNone(Speaker.objects.get(pk=speaker1_item1.pk).begin_time)
|
self.assertIsNotNone(Speaker.objects.get(pk=speaker1_item1.pk).begin_time)
|
||||||
self.assertIsNone(Speaker.objects.get(pk=speaker1_item1.pk).weight)
|
self.assertIsNone(Speaker.objects.get(pk=speaker1_item1.pk).weight)
|
||||||
speaker1_item1.end_speach()
|
speaker1_item1.end_speech()
|
||||||
self.assertIsNotNone(Speaker.objects.get(pk=speaker1_item1.pk).end_time)
|
self.assertIsNotNone(Speaker.objects.get(pk=speaker1_item1.pk).end_time)
|
||||||
|
|
||||||
def test_finish_when_other_speaker_begins(self):
|
def test_finish_when_other_speaker_begins(self):
|
||||||
speaker1_item1 = Speaker.objects.add(self.speaker1, self.item1)
|
speaker1_item1 = Speaker.objects.add(self.speaker1, self.item1)
|
||||||
speaker2_item1 = Speaker.objects.add(self.speaker2, self.item1)
|
speaker2_item1 = Speaker.objects.add(self.speaker2, self.item1)
|
||||||
speaker1_item1.begin_speach()
|
speaker1_item1.begin_speech()
|
||||||
self.assertIsNone(speaker1_item1.end_time)
|
self.assertIsNone(speaker1_item1.end_time)
|
||||||
self.assertIsNone(speaker2_item1.begin_time)
|
self.assertIsNone(speaker2_item1.begin_time)
|
||||||
speaker2_item1.begin_speach()
|
speaker2_item1.begin_speech()
|
||||||
self.assertIsNotNone(Speaker.objects.get(user=self.speaker1, item=self.item1).end_time)
|
self.assertIsNotNone(Speaker.objects.get(user=self.speaker1, item=self.item1).end_time)
|
||||||
self.assertIsNotNone(speaker2_item1.begin_time)
|
self.assertIsNotNone(speaker2_item1.begin_time)
|
||||||
|
@ -56,7 +56,7 @@ class ItemViewSetManageSpeaker(TestCase):
|
|||||||
|
|
||||||
class ItemViewSetSpeak(TestCase):
|
class ItemViewSetSpeak(TestCase):
|
||||||
"""
|
"""
|
||||||
Tests views of ItemViewSet to begin and end speach.
|
Tests views of ItemViewSet to begin and end speech.
|
||||||
"""
|
"""
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.request = MagicMock()
|
self.request = MagicMock()
|
||||||
@ -65,27 +65,27 @@ class ItemViewSetSpeak(TestCase):
|
|||||||
self.view_instance.get_object = get_object_mock = MagicMock()
|
self.view_instance.get_object = get_object_mock = MagicMock()
|
||||||
get_object_mock.return_value = self.mock_item = MagicMock()
|
get_object_mock.return_value = self.mock_item = MagicMock()
|
||||||
|
|
||||||
def test_begin_speach(self):
|
def test_begin_speech(self):
|
||||||
self.request.method = 'PUT'
|
self.request.method = 'PUT'
|
||||||
self.request.user.has_perm.return_value = True
|
self.request.user.has_perm.return_value = True
|
||||||
self.request.data = {}
|
self.request.data = {}
|
||||||
self.mock_item.get_next_speaker.return_value = mock_next_speaker = MagicMock()
|
self.mock_item.get_next_speaker.return_value = mock_next_speaker = MagicMock()
|
||||||
self.view_instance.speak(self.request)
|
self.view_instance.speak(self.request)
|
||||||
mock_next_speaker.begin_speach.assert_called_with()
|
mock_next_speaker.begin_speech.assert_called_with()
|
||||||
|
|
||||||
@patch('openslides.agenda.views.Speaker')
|
@patch('openslides.agenda.views.Speaker')
|
||||||
def test_begin_speach_specific_speaker(self, mock_speaker):
|
def test_begin_speech_specific_speaker(self, mock_speaker):
|
||||||
self.request.method = 'PUT'
|
self.request.method = 'PUT'
|
||||||
self.request.user.has_perm.return_value = True
|
self.request.user.has_perm.return_value = True
|
||||||
self.request.data = {'speaker': '1'}
|
self.request.data = {'speaker': '1'}
|
||||||
mock_speaker.objects.get.return_value = mock_next_speaker = MagicMock()
|
mock_speaker.objects.get.return_value = mock_next_speaker = MagicMock()
|
||||||
self.view_instance.speak(self.request)
|
self.view_instance.speak(self.request)
|
||||||
mock_next_speaker.begin_speach.assert_called_with()
|
mock_next_speaker.begin_speech.assert_called_with()
|
||||||
|
|
||||||
@patch('openslides.agenda.views.Speaker')
|
@patch('openslides.agenda.views.Speaker')
|
||||||
def test_end_speach(self, mock_speaker):
|
def test_end_speech(self, mock_speaker):
|
||||||
self.request.method = 'DELETE'
|
self.request.method = 'DELETE'
|
||||||
self.request.user.has_perm.return_value = True
|
self.request.user.has_perm.return_value = True
|
||||||
mock_speaker.objects.filter.return_value.exclude.return_value.get.return_value = mock_speaker = MagicMock()
|
mock_speaker.objects.filter.return_value.exclude.return_value.get.return_value = mock_speaker = MagicMock()
|
||||||
self.view_instance.speak(self.request)
|
self.view_instance.speak(self.request)
|
||||||
mock_speaker.end_speach.assert_called_with()
|
mock_speaker.end_speech.assert_called_with()
|
||||||
|
Loading…
Reference in New Issue
Block a user