Merge lp:~cjohnston/summit/seperate-tests into lp:summit

Proposed by Chris Johnston
Status: Merged
Approved by: Michael Hall
Approved revision: 491
Merged at revision: 491
Proposed branch: lp:~cjohnston/summit/seperate-tests
Merge into: lp:summit
Diff against target: 7649 lines (+4092/-3423)
21 files modified
summit/schedule/tests/__init__.py (+16/-2)
summit/schedule/tests/autoscheduler.py (+209/-0)
summit/schedule/tests/delete_meeting.py (+203/-0)
summit/schedule/tests/etherpad.py (+76/-0)
summit/schedule/tests/ical.py (+232/-0)
summit/schedule/tests/launchpad_export_node.py (+32/-0)
summit/schedule/tests/meeting_model.py (+608/-0)
summit/schedule/tests/meeting_page.py (+101/-0)
summit/schedule/tests/meeting_search.py (+335/-0)
summit/schedule/tests/participation_registration.py (+202/-0)
summit/schedule/tests/private_scheduling.py (+225/-0)
summit/schedule/tests/render_schedule.py (+196/-0)
summit/schedule/tests/request_factory.py (+80/-0)
summit/schedule/tests/reverse_url.py (+220/-0)
summit/schedule/tests/schedule.py (+537/-0)
summit/schedule/tests/schedule_cache.py (+167/-0)
summit/schedule/tests/scheduling_conflicts.py (+146/-0)
summit/schedule/tests/summit_model.py (+501/-0)
summit/schedule/tests/tests.py (+0/-3417)
summit/schedule/tests/virtual.py (+2/-2)
summit/schedule/views.py (+4/-2)
To merge this branch: bzr merge lp:~cjohnston/summit/seperate-tests
Reviewer Review Type Date Requested Status
Michael Hall (community) Approve
Review via email: mp+150816@code.launchpad.net

Commit message

Separate tests into different files

To post a comment you must log in.
lp:~cjohnston/summit/seperate-tests updated
490. By Chris Johnston

Fix conflicts

491. By Chris Johnston

oops

Revision history for this message
Michael Hall (mhall119) wrote :

Looks good

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'summit/schedule/tests/__init__.py'
--- summit/schedule/tests/__init__.py 2013-02-26 20:00:45 +0000
+++ summit/schedule/tests/__init__.py 2013-02-27 15:35:39 +0000
@@ -14,5 +14,19 @@
14# You should have received a copy of the GNU Affero General Public License14# You should have received a copy of the GNU Affero General Public License
15# along with this program. If not, see <http://www.gnu.org/licenses/>.15# along with this program. If not, see <http://www.gnu.org/licenses/>.
1616
17from tests import *17from virtual import *
18from test_virtual import *18from etherpad import *
19from meeting_page import *
20from render_schedule import *
21from scheduling_conflicts import *
22from ical import *
23from meeting_search import *
24from reverse_url import *
25from autoscheduler import *
26from participation_registration import *
27from schedule_cache import *
28from delete_meeting import *
29from meeting_model import *
30from private_scheduling import *
31from schedule import *
32from summit_model import *
1933
=== added file 'summit/schedule/tests/autoscheduler.py'
--- summit/schedule/tests/autoscheduler.py 1970-01-01 00:00:00 +0000
+++ summit/schedule/tests/autoscheduler.py 2013-02-27 15:35:39 +0000
@@ -0,0 +1,209 @@
1# The Summit Scheduler web application
2# Copyright (C) 2008 - 2013 Ubuntu Community, Canonical Ltd
3#
4# This program is free software: you can redistribute it and/or modify
5# it under the terms of the GNU Affero General Public License as
6# published by the Free Software Foundation, either version 3 of the
7# License, or (at your option) any later version.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU Affero General Public License for more details.
13#
14# You should have received a copy of the GNU Affero General Public License
15# along with this program. If not, see <http://www.gnu.org/licenses/>.
16
17
18import datetime
19from django import test as djangotest
20from django.contrib.auth.models import User
21
22from model_mommy import mommy as factory
23from summit.schedule.fields import NameField
24
25from summit.schedule.models import (
26 Summit,
27 Slot,
28 Attendee,
29 Meeting,
30 Room,
31 Agenda,
32 Participant,
33)
34
35
36# Monkey-patch our NameField into the types of fields that the factory
37# understands. This is simpler than trying to subclass the Mommy
38# class directly.
39factory.default_mapping[NameField] = str
40
41
42class AutoSchedulerTestCase(djangotest.TestCase):
43 def setUp(self):
44 now = datetime.datetime.utcnow()
45 one_hour = datetime.timedelta(0, 3600)
46 week = datetime.timedelta(days=5)
47 self.summit = factory.make_one(Summit, name='uds-test')
48 self.slot = factory.make_one(
49 Slot,
50 start_utc=now+week,
51 end_utc=now+week+one_hour,
52 type='open',
53 summit=self.summit
54 )
55
56 self.room1 = factory.make_one(Room, summit=self.summit, type='open')
57 self.meeting1 = factory.make_one(
58 Meeting,
59 summit=self.summit,
60 name='meeting1',
61 requires_dial_in=False,
62 approved='APPROVED',
63 private=False
64 )
65 self.agenda1 = factory.make_one(
66 Agenda,
67 slot=self.slot,
68 meeting=self.meeting1,
69 room=self.room1
70 )
71
72 self.room2 = factory.make_one(Room, summit=self.summit, type='open')
73 self.meeting2 = factory.make_one(
74 Meeting,
75 summit=self.summit,
76 name='meeting2',
77 requires_dial_in=False,
78 approved='APPROVED',
79 private=False
80 )
81
82 self.user = factory.make_one(
83 User,
84 username='testuser',
85 first_name='Test',
86 last_name='User'
87 )
88 self.attendee = factory.make_one(
89 Attendee,
90 summit=self.summit,
91 user=self.user,
92 start_utc=now,
93 end_utc=now+week
94 )
95
96 def tearDown(self):
97 pass
98
99 def run_autoschedule(self):
100 from django.core.management import execute_from_command_line
101 execute_from_command_line(
102 argv=['manage.py', 'autoschedule', 'uds-test', '-v', '2']
103 )
104
105 def run_reschedule(self):
106 from django.core.management import execute_from_command_line
107 execute_from_command_line(
108 argv=['manage.py', 'reschedule', 'uds-test', '-v', '2']
109 )
110
111 def test_required_conflict(self):
112 participant1 = Participant.objects.create(
113 meeting=self.meeting1,
114 attendee=self.attendee,
115 participation='REQUIRED'
116 )
117
118 participant2 = Participant.objects.create(
119 meeting=self.meeting2,
120 attendee=self.attendee,
121 participation='REQUIRED'
122 )
123
124 self.run_autoschedule()
125
126 self.assertEquals(1, self.meeting1.agenda_set.all().count())
127 self.assertEquals(0, self.meeting2.agenda_set.all().count())
128
129 def test_required_and_interested(self):
130 participant1 = Participant.objects.create(
131 meeting=self.meeting1,
132 attendee=self.attendee,
133 participation='REQUIRED'
134 )
135
136 participant2 = Participant.objects.create(
137 meeting=self.meeting2,
138 attendee=self.attendee,
139 participation='INTERESTED'
140 )
141
142 self.run_autoschedule()
143
144 self.assertEquals(1, self.meeting1.agenda_set.all().count())
145 self.assertEquals(1, self.meeting2.agenda_set.all().count())
146
147 def test_interested_and_required(self):
148 participant1 = Participant.objects.create(
149 meeting=self.meeting1,
150 attendee=self.attendee,
151 participation='REQUIRED'
152 )
153
154 participant2 = Participant.objects.create(
155 meeting=self.meeting2,
156 attendee=self.attendee,
157 participation='INTERESTED'
158 )
159
160 self.run_autoschedule()
161
162 self.assertEquals(1, self.meeting1.agenda_set.all().count())
163 self.assertEquals(1, self.meeting2.agenda_set.all().count())
164
165 participant2.participation = 'REQUIRED'
166 participant2.save()
167
168 self.run_reschedule()
169
170 self.assertEquals(0, self.meeting1.agenda_set.all().count())
171 self.assertEquals(0, self.meeting2.agenda_set.all().count())
172
173 def test_get_participants_by_level(self):
174 participant1 = Participant.objects.create(
175 meeting=self.meeting1,
176 attendee=self.attendee,
177 participation='REQUIRED'
178 )
179
180 participant2 = Participant.objects.create(
181 meeting=self.meeting2,
182 attendee=self.attendee,
183 participation='INTERESTED'
184 )
185
186 self.assertEquals(
187 1,
188 len(self.meeting1.get_participants_by_level('REQUIRED'))
189 )
190 self.assertEquals(
191 0, len(self.meeting1.get_participants_by_level('INTERESTED'))
192 )
193 self.assertEquals(
194 0,
195 len(self.meeting1.get_participants_by_level('ATTENDING'))
196 )
197
198 self.assertEquals(
199 0,
200 len(self.meeting2.get_participants_by_level('REQUIRED'))
201 )
202 self.assertEquals(
203 1,
204 len(self.meeting2.get_participants_by_level('INTERESTED'))
205 )
206 self.assertEquals(
207 0,
208 len(self.meeting2.get_participants_by_level('ATTENDING'))
209 )
0210
=== added file 'summit/schedule/tests/delete_meeting.py'
--- summit/schedule/tests/delete_meeting.py 1970-01-01 00:00:00 +0000
+++ summit/schedule/tests/delete_meeting.py 2013-02-27 15:35:39 +0000
@@ -0,0 +1,203 @@
1# The Summit Scheduler web application
2# Copyright (C) 2008 - 2013 Ubuntu Community, Canonical Ltd
3#
4# This program is free software: you can redistribute it and/or modify
5# it under the terms of the GNU Affero General Public License as
6# published by the Free Software Foundation, either version 3 of the
7# License, or (at your option) any later version.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU Affero General Public License for more details.
13#
14# You should have received a copy of the GNU Affero General Public License
15# along with this program. If not, see <http://www.gnu.org/licenses/>.
16
17
18import datetime
19from django import test as djangotest
20from django.core.urlresolvers import reverse
21from django.contrib.auth.models import User, Permission
22
23from model_mommy import mommy as factory
24from summit.schedule.fields import NameField
25
26from summit.schedule.models import (
27 Summit,
28 Slot,
29 Attendee,
30 Meeting,
31 Room,
32 Agenda,
33 Participant,
34 Lead,
35)
36
37# Monkey-patch our NameField into the types of fields that the factory
38# understands. This is simpler than trying to subclass the Mommy
39# class directly.
40factory.default_mapping[NameField] = str
41
42
43class DeleteMeetingTestCase(djangotest.TestCase):
44 """
45 This will test different options for deleting a meeting from
46 the front end UI.
47 """
48
49 def setUp(self):
50 now = datetime.datetime.utcnow()
51 one_hour = datetime.timedelta(0, 3600)
52 self.summit = factory.make_one(
53 Summit,
54 name='uds-test',
55 date_start=now,
56 date_end=now+one_hour
57 )
58 self.summit.save()
59 slot = factory.make_one(
60 Slot,
61 summit=self.summit,
62 start_utc=now,
63 end_utc=now+one_hour
64 )
65 room = factory.make_one(Room)
66
67 self.meeting = factory.make_one(
68 Meeting,
69 summit=self.summit,
70 requires_dial_in=False,
71 private=False
72 )
73
74 attendee1 = factory.make_one(Attendee)
75 factory.make_one(Participant, meeting=self.meeting, attendee=attendee1)
76
77 factory.make_one(Agenda, meeting=self.meeting, slot=slot, room=room)
78
79 self.user = factory.make_one(
80 User,
81 username='testuser',
82 is_active=True,
83 is_superuser=False
84 )
85 self.user.set_password('password')
86 self.user.save()
87
88 self.attendee = factory.make_one(
89 Attendee,
90 user=self.user,
91 summit=self.summit
92 )
93
94 def tearDown(self):
95 self.client.logout()
96 self.user.user_permissions.all().delete()
97
98 def login(self):
99 logged_in = self.client.login(username='testuser', password='password')
100 self.assertTrue(logged_in)
101
102 def test_track_lead_cant_delete_meeting(self):
103 self.lead = factory.make_one(
104 Lead,
105 lead=self.attendee,
106 summit=self.summit
107 )
108 self.login()
109 response = self.client.get(
110 reverse(
111 'summit.schedule.views.delete_meeting',
112 args=(self.summit, self.meeting.id, self.meeting.name)
113 )
114 )
115 self.assertRedirects(
116 response,
117 reverse(
118 'summit.schedule.views.summit',
119 args=(self.summit.name,)
120 ),
121 status_code=302,
122 target_status_code=200
123 )
124
125 def test_user_cant_delete_meeting(self):
126 self.login()
127 response = self.client.get(
128 reverse(
129 'summit.schedule.views.delete_meeting',
130 args=(self.summit, self.meeting.id, self.meeting.name)
131 )
132 )
133 self.assertRedirects(
134 response,
135 reverse(
136 'summit.schedule.views.summit',
137 args=(self.summit.name,)
138 ),
139 status_code=302,
140 target_status_code=200
141 )
142
143 def test_managers_cant_delete_meeting(self):
144 self.summit.managers.add(self.user)
145 self.login()
146 response = self.client.get(
147 reverse(
148 'summit.schedule.views.delete_meeting',
149 args=(self.summit, self.meeting.id, self.meeting.name)
150 )
151 )
152 self.assertRedirects(
153 response,
154 reverse(
155 'summit.schedule.views.summit',
156 args=(self.summit.name,)
157 ),
158 status_code=302,
159 target_status_code=200
160 )
161
162 def test_schedulers_can_delete_meeting(self):
163 self.summit.schedulers.add(self.user)
164 self.login()
165 response = self.client.get(
166 reverse(
167 'summit.schedule.views.delete_meeting',
168 args=(self.summit, self.meeting.id, self.meeting.name)
169 )
170 )
171 self.assertRedirects(
172 response,
173 reverse(
174 'summit.schedule.views.delete_confirmed',
175 args=(self.summit.name,)
176 ),
177 status_code=302,
178 target_status_code=200
179 )
180
181 def test_change_agenda_can_delete_meeting(self):
182 """
183 Testing if a user who is assigned can_change_agenda
184 in django admin can delete a meeting
185 """
186 change_agenda = Permission.objects.get(codename='change_agenda')
187 self.user.user_permissions.add(change_agenda)
188 self.login()
189 response = self.client.get(
190 reverse(
191 'summit.schedule.views.delete_meeting',
192 args=(self.summit, self.meeting.id, self.meeting.name)
193 )
194 )
195 self.assertRedirects(
196 response,
197 reverse(
198 'summit.schedule.views.delete_confirmed',
199 args=(self.summit.name,)
200 ),
201 status_code=302,
202 target_status_code=200
203 )
0204
=== added file 'summit/schedule/tests/etherpad.py'
--- summit/schedule/tests/etherpad.py 1970-01-01 00:00:00 +0000
+++ summit/schedule/tests/etherpad.py 2013-02-27 15:35:39 +0000
@@ -0,0 +1,76 @@
1# The Summit Scheduler web application
2# Copyright (C) 2008 - 2013 Ubuntu Community, Canonical Ltd
3#
4# This program is free software: you can redistribute it and/or modify
5# it under the terms of the GNU Affero General Public License as
6# published by the Free Software Foundation, either version 3 of the
7# License, or (at your option) any later version.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU Affero General Public License for more details.
13#
14# You should have received a copy of the GNU Affero General Public License
15# along with this program. If not, see <http://www.gnu.org/licenses/>.
16
17
18from django import test as djangotest
19
20from model_mommy import mommy as factory
21from summit.schedule.fields import NameField
22
23from summit.schedule.models import (
24 Summit,
25 Slot,
26 Meeting,
27 Room,
28 Agenda,
29)
30
31# Monkey-patch our NameField into the types of fields that the factory
32# understands. This is simpler than trying to subclass the Mommy
33# class directly.
34factory.default_mapping[NameField] = str
35
36
37class EtherpadEditUrl(djangotest.TestCase):
38
39 def setUp(self):
40 self.summit = factory.make_one(Summit, name='uds-test')
41 self.summit.save()
42
43 def tearDown(self):
44 pass
45
46 def test_etherpad_edit_url(self):
47
48 slot = factory.make_one(
49 Slot,
50 type='open',
51 summit=self.summit)
52 slot.save()
53
54 room = factory.make_one(Room, summit=self.summit)
55 meeting = factory.make_one(
56 Meeting,
57 summit=self.summit,
58 name='test-meeting',
59 private=False
60 )
61 agenda = factory.make_one(
62 Agenda,
63 slot=slot,
64 meeting=meeting,
65 room=room
66 )
67
68 response = self.client.get(
69 '/uds-test/meeting/%s/test-meeting/' % meeting.id
70 )
71 self.assertEquals(response.status_code, 200)
72 self.assertContains(
73 response,
74 'http://pad.ubuntu.com/ep/pad/view/uds-test-test-meeting/latest',
75 1
76 )
077
=== added file 'summit/schedule/tests/ical.py'
--- summit/schedule/tests/ical.py 1970-01-01 00:00:00 +0000
+++ summit/schedule/tests/ical.py 2013-02-27 15:35:39 +0000
@@ -0,0 +1,232 @@
1# The Summit Scheduler web application
2# Copyright (C) 2008 - 2013 Ubuntu Community, Canonical Ltd
3#
4# This program is free software: you can redistribute it and/or modify
5# it under the terms of the GNU Affero General Public License as
6# published by the Free Software Foundation, either version 3 of the
7# License, or (at your option) any later version.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU Affero General Public License for more details.
13#
14# You should have received a copy of the GNU Affero General Public License
15# along with this program. If not, see <http://www.gnu.org/licenses/>.
16
17
18import datetime
19from django import test as djangotest
20from django.conf import settings
21from django.contrib.auth.models import User
22from django.db import models
23
24from model_mommy import mommy as factory
25from summit.schedule.fields import NameField
26
27from summit.schedule.models import (
28 Summit,
29 Slot,
30 Attendee,
31 Meeting,
32 Room,
33 Agenda,
34 Participant,
35)
36
37site_root = getattr(settings, 'SITE_ROOT', 'http://summit.ubuntu.com')
38
39# Monkey-patch our NameField into the types of fields that the factory
40# understands. This is simpler than trying to subclass the Mommy
41# class directly.
42factory.default_mapping[NameField] = str
43
44
45class ICalTestCase(djangotest.TestCase):
46
47 def test_ical_meeting_without_name(self):
48 """ Tests that ical doesn't break for nameless meetings"""
49 now = datetime.datetime.utcnow()
50 one_hour = datetime.timedelta(0, 3600)
51 summit = factory.make_one(Summit, name='uds-test')
52 summit.save()
53 slot = factory.make_one(
54 Slot,
55 start_utc=now,
56 end_utc=now+one_hour,
57 type='open',
58 summit=summit
59 )
60 slot.save()
61
62 room = factory.make_one(Room, summit=summit)
63 meeting = factory.make_one(
64 Meeting,
65 summit=summit,
66 name='',
67 private=False
68 )
69 meeting.name = ''
70 models.Model.save(meeting)
71 agenda = factory.make_one(
72 Agenda,
73 slot=slot,
74 meeting=meeting,
75 room=room
76 )
77
78 self.assertEquals(
79 meeting.meeting_page_url,
80 '/uds-test/meeting/%s/-/' % meeting.id
81 )
82
83 response = self.client.get('/uds-test.ical')
84 self.assertEquals(response.status_code, 200)
85 self.assertContains(
86 response,
87 'URL:%s/uds-test/meeting/%s/-/\n' % (site_root, meeting.id),
88 1
89 )
90
91 def test_ical_meeting_name_with_period(self):
92 """ Tests that ical doesn't break for nameless meetings"""
93 now = datetime.datetime.utcnow()
94 one_hour = datetime.timedelta(0, 3600)
95 summit = factory.make_one(Summit, name='uds-test')
96 summit.save()
97 slot = factory.make_one(
98 Slot,
99 start_utc=now,
100 end_utc=now+one_hour,
101 type='open',
102 summit=summit
103 )
104 slot.save()
105
106 room = factory.make_one(Room, summit=summit)
107 meeting = factory.make_one(
108 Meeting,
109 summit=summit,
110 name='test.name',
111 private=False
112 )
113 agenda = factory.make_one(
114 Agenda,
115 slot=slot,
116 meeting=meeting,
117 room=room
118 )
119
120 self.assertEquals(
121 meeting.meeting_page_url,
122 '/uds-test/meeting/%s/test.name/' % meeting.id
123 )
124
125 response = self.client.get('/uds-test.ical')
126 self.assertEquals(response.status_code, 200)
127 self.assertContains(
128 response,
129 'URL:%s/uds-test/meeting/%s/test.name/' % (site_root, meeting.id),
130 1
131 )
132
133 def test_ical_meeting_multiline_description(self):
134 """ Tests that ical put spaces before multi-line descriptions"""
135 now = datetime.datetime.utcnow()
136 one_hour = datetime.timedelta(0, 3600)
137 summit = factory.make_one(Summit, name='uds-test')
138 summit.save()
139 slot = factory.make_one(
140 Slot,
141 start_utc=now,
142 end_utc=now+one_hour,
143 type='open',
144 summit=summit
145 )
146 slot.save()
147
148 room = factory.make_one(Room, summit=summit)
149 meeting = factory.make_one(
150 Meeting,
151 summit=summit,
152 name='test.name',
153 description="Test\r\nDescription",
154 private=False
155 )
156 agenda = factory.make_one(
157 Agenda,
158 slot=slot,
159 meeting=meeting,
160 room=room
161 )
162
163 self.assertEquals(
164 meeting.meeting_page_url,
165 '/uds-test/meeting/%s/test.name/' % meeting.id
166 )
167
168 response = self.client.get('/uds-test.ical')
169 self.assertEquals(response.status_code, 200)
170 self.assertContains(response, 'DESCRIPTION:Test\NDescription', 1)
171
172 def test_private_ical(self):
173 """ Tests that private icals contain private meetings """
174 now = datetime.datetime.utcnow()
175 one_hour = datetime.timedelta(0, 3600)
176 week = datetime.timedelta(days=7)
177 summit = factory.make_one(Summit, name='uds-test')
178 slot = factory.make_one(
179 Slot,
180 start_utc=now,
181 end_utc=now+one_hour,
182 type='open',
183 summit=summit
184 )
185
186 room = factory.make_one(Room, summit=summit)
187 meeting = factory.make_one(
188 Meeting,
189 summit=summit,
190 name='test.name',
191 private=True
192 )
193 agenda = factory.make_one(
194 Agenda,
195 slot=slot,
196 meeting=meeting,
197 room=room
198 )
199
200 self.assertEquals(
201 meeting.meeting_page_url,
202 '/uds-test/meeting/%s/test.name/' % meeting.id
203 )
204
205 user = factory.make_one(
206 User,
207 username='testuser',
208 first_name='Test',
209 last_name='User'
210 )
211 attendee = factory.make_one(
212 Attendee,
213 summit=summit,
214 user=user,
215 start_utc=now,
216 end_utc=now+week
217 )
218 participant = factory.make_one(
219 Participant,
220 attendee=attendee,
221 meeting=meeting
222 )
223
224 response = self.client.get(
225 '/uds-test/participant/my_schedule_%s.ical' % attendee.secret_key
226 )
227 self.assertEquals(response.status_code, 200)
228 self.assertContains(
229 response,
230 'URL:%s/uds-test/meeting/%s/test.name/' % (site_root, meeting.id),
231 1
232 )
0233
=== added file 'summit/schedule/tests/launchpad_export_node.py'
--- summit/schedule/tests/launchpad_export_node.py 1970-01-01 00:00:00 +0000
+++ summit/schedule/tests/launchpad_export_node.py 2013-02-27 15:35:39 +0000
@@ -0,0 +1,32 @@
1# The Summit Scheduler web application
2# Copyright (C) 2008 - 2013 Ubuntu Community, Canonical Ltd
3#
4# This program is free software: you can redistribute it and/or modify
5# it under the terms of the GNU Affero General Public License as
6# published by the Free Software Foundation, either version 3 of the
7# License, or (at your option) any later version.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU Affero General Public License for more details.
13#
14# You should have received a copy of the GNU Affero General Public License
15# along with this program. If not, see <http://www.gnu.org/licenses/>.
16
17
18class LaunchpadExportNode(dict):
19
20 def __init__(self, *args, **kwargs):
21 self.__children = {}
22 super(LaunchpadExportNode, self).__init__(*args, **kwargs)
23
24 def add_child(self, key, node):
25 self.__children.setdefault(key, [])
26 self.__children[key].append(node)
27
28 def findall(self, key):
29 return self.__children.get(key, [])
30
31 def find(self, key):
32 return self.findall(key)[0]
033
=== added file 'summit/schedule/tests/meeting_model.py'
--- summit/schedule/tests/meeting_model.py 1970-01-01 00:00:00 +0000
+++ summit/schedule/tests/meeting_model.py 2013-02-27 15:35:39 +0000
@@ -0,0 +1,608 @@
1# The Summit Scheduler web application
2# Copyright (C) 2008 - 2013 Ubuntu Community, Canonical Ltd
3#
4# This program is free software: you can redistribute it and/or modify
5# it under the terms of the GNU Affero General Public License as
6# published by the Free Software Foundation, either version 3 of the
7# License, or (at your option) any later version.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU Affero General Public License for more details.
13#
14# You should have received a copy of the GNU Affero General Public License
15# along with this program. If not, see <http://www.gnu.org/licenses/>.
16
17
18import datetime
19from django import test as djangotest
20from django.contrib.auth.models import User
21
22from model_mommy import mommy as factory
23from summit.schedule.fields import NameField
24
25from summit.schedule.models import (
26 Summit,
27 Slot,
28 Attendee,
29 Meeting,
30 Track,
31 Room,
32 Agenda,
33 Participant,
34)
35
36from summit.schedule.tests.launchpad_export_node import LaunchpadExportNode
37
38# Monkey-patch our NameField into the types of fields that the factory
39# understands. This is simpler than trying to subclass the Mommy
40# class directly.
41factory.default_mapping[NameField] = str
42
43
44class MeetingModelTestCase(djangotest.TestCase):
45 """Tests for the Meeting model."""
46
47 def test_meetings_can_not_be_scheduled_in_closed_slots(self):
48 now = datetime.datetime.utcnow()
49 one_hour = datetime.timedelta(0, 3600)
50 slot = factory.make_one(
51 Slot,
52 start_utc=now,
53 end_utc=now+one_hour,
54 type='closed')
55
56 agenda = factory.make_one(Agenda, slot=slot)
57 meeting = factory.make_one(
58 Meeting,
59 requires_dial_in=False,
60 private=False
61 )
62
63 # XXX check_schedule should only be checking the schedule, not
64 # checking and modifying the schedule.
65 # XXX check_schedule's parameters should be an just an agenda object,
66 # not the agenda object's attributes.
67 self.assertRaises(
68 Meeting.SchedulingError,
69 meeting.check_schedule, agenda.slot, agenda.room)
70
71 def test_participants_are_in_another_meeting(self):
72 now = datetime.datetime.utcnow()
73 one_hour = datetime.timedelta(0, 3600)
74 slot = factory.make_one(
75 Slot,
76 start_utc=now,
77 end_utc=now+one_hour)
78 room1 = factory.make_one(Room)
79 room2 = factory.make_one(Room)
80
81 meeting1 = factory.make_one(
82 Meeting,
83 summit=slot.summit,
84 requires_dial_in=False,
85 private=False
86 )
87 meeting2 = factory.make_one(
88 Meeting,
89 summit=slot.summit,
90 requires_dial_in=False,
91 private=False
92 )
93
94 attendee = factory.make_one(Attendee)
95 factory.make_one(
96 Participant,
97 meeting=meeting1,
98 attendee=attendee,
99 participation='REQUIRED'
100 )
101 factory.make_one(
102 Participant,
103 meeting=meeting2,
104 attendee=attendee,
105 participation='REQUIRED'
106 )
107
108 factory.make_one(Agenda, meeting=meeting1, slot=slot, room=room1)
109 agenda = factory.make_one(
110 Agenda,
111 meeting=meeting2,
112 slot=slot,
113 room=room2
114 )
115
116 missing = meeting2.check_schedule(agenda.slot, agenda.room)
117 self.assertEqual([attendee.name], [a.name for a in missing])
118
119 def make_open_slot(self):
120 now = datetime.datetime.utcnow()
121 one_hour = datetime.timedelta(0, 3600)
122 slot = factory.make_one(
123 Slot,
124 start_utc=now+one_hour,
125 end_utc=now+one_hour+one_hour,
126 type='open')
127 return slot
128
129 def test_check_schedule_errors_on_no_dial_in(self):
130 slot = self.make_open_slot()
131 room = factory.make_one(
132 Room,
133 has_dial_in=False,
134 summit=slot.summit,
135 name="testroom"
136 )
137 meeting = factory.make_one(
138 Meeting,
139 requires_dial_in=True,
140 summit=slot.summit,
141 name="testmeeting",
142 private=False
143 )
144 try:
145 meeting.check_schedule(slot, room)
146 except meeting.SchedulingError, e:
147 self.assertEqual("Room has no dial-in capability", e.message)
148 return
149 self.fail("SchedulingError not thrown")
150
151 def make_two_adjacent_slots(self):
152 summit = factory.make_one(Summit, timezone='utc')
153 now = datetime.datetime(2011, 9, 8, 12, 00)
154 one_hour = datetime.timedelta(0, 3600)
155 slot1 = factory.make_one(
156 Slot,
157 start_utc=now+one_hour,
158 end_utc=now+one_hour+one_hour,
159 type='open', summit=summit
160 )
161 slot2 = factory.make_one(
162 Slot,
163 start_utc=now+one_hour+one_hour,
164 end_utc=now+one_hour+one_hour+one_hour,
165 type='open', summit=summit
166 )
167 return slot1, slot2
168
169 def test_check_schedule_errors_on_same_track_in_previous_slot(self):
170 slot1, slot2 = self.make_two_adjacent_slots()
171 room = factory.make_one(
172 Room,
173 summit=slot1.summit,
174 name="testroom"
175 )
176 track = factory.make_one(
177 Track,
178 summit=slot1.summit,
179 title="testtrack",
180 allow_adjacent_sessions=False
181 )
182 track2 = factory.make_one(
183 Track,
184 summit=slot1.summit,
185 title="adjacenttrack",
186 allow_adjacent_sessions=True
187 )
188 meeting1 = factory.make_one(
189 Meeting,
190 requires_dial_in=False,
191 summit=slot1.summit,
192 name="testmeeting1",
193 type='blueprint',
194 private=False
195 )
196 meeting2 = factory.make_one(
197 Meeting,
198 requires_dial_in=False,
199 summit=slot1.summit,
200 name="testmeeting2",
201 type='blueprint',
202 private=False
203 )
204 meeting1.tracks = [track, track2]
205 meeting2.tracks = [track]
206 meeting1.agenda_set.create(room=room, slot=slot1)
207 try:
208 meeting2.check_schedule(slot2, room)
209 except meeting2.SchedulingError, e:
210 self.assertEqual("Same track in the previous slot", e.message)
211 return
212 self.fail("SchedulingError not thrown")
213
214 def test_check_schedule_errors_on_same_track_in_next_slot(self):
215 slot1, slot2 = self.make_two_adjacent_slots()
216 room = factory.make_one(Room, summit=slot1.summit, name="testroom")
217 track = factory.make_one(
218 Track,
219 summit=slot1.summit,
220 title="testtrack",
221 allow_adjacent_sessions=False
222 )
223 meeting1 = factory.make_one(
224 Meeting,
225 requires_dial_in=False,
226 summit=slot1.summit,
227 name="testmeeting1",
228 type='blueprint',
229 private=False
230 )
231 meeting2 = factory.make_one(
232 Meeting,
233 requires_dial_in=False,
234 summit=slot1.summit,
235 name="testmeeting2",
236 type='blueprint',
237 private=False
238 )
239 meeting1.tracks = [track]
240 meeting2.tracks = [track]
241 meeting1.agenda_set.create(room=room, slot=slot2)
242 try:
243 meeting2.check_schedule(slot1, room)
244 except meeting2.SchedulingError, e:
245 self.assertEqual("Same track in the next slot", e.message)
246 return
247 self.fail("SchedulingError not thrown")
248
249 def test_check_schedule_no_error_on_different_track(self):
250 slot1, slot2 = self.make_two_adjacent_slots()
251 room = factory.make_one(Room, summit=slot1.summit, name="testroom")
252 track = factory.make_one(
253 Track,
254 summit=slot1.summit,
255 title="testtrack",
256 allow_adjacent_sessions=False
257 )
258 other_track = factory.make_one(
259 Track,
260 summit=slot1.summit,
261 title="othertesttrack",
262 allow_adjacent_sessions=False
263 )
264 meeting1 = factory.make_one(
265 Meeting,
266 requires_dial_in=False,
267 summit=slot1.summit,
268 name="testmeeting1",
269 type='blueprint',
270 private=False
271 )
272 meeting2 = factory.make_one(
273 Meeting,
274 requires_dial_in=False,
275 summit=slot1.summit,
276 name="testmeeting2",
277 type='blueprint',
278 private=False
279 )
280 meeting1.tracks = [track]
281 meeting2.tracks = [other_track]
282 meeting1.agenda_set.create(room=room, slot=slot2)
283 meeting2.check_schedule(slot1, room)
284
285 def test_check_schedule_no_error_on_same_track_for_plenaries(self):
286 slot1, slot2 = self.make_two_adjacent_slots()
287 room = factory.make_one(Room, summit=slot1.summit, name="testroom")
288 track = factory.make_one(
289 Track,
290 summit=slot1.summit,
291 title="testtrack",
292 allow_adjacent_sessions=False
293 )
294 meeting1 = factory.make_one(
295 Meeting,
296 requires_dial_in=False,
297 summit=slot1.summit,
298 name="testmeeting1",
299 type='blueprint',
300 private=False
301 )
302 meeting2 = factory.make_one(
303 Meeting,
304 requires_dial_in=False,
305 summit=slot1.summit,
306 name="testmeeting2",
307 type='plenary',
308 private=False
309 )
310 meeting1.tracks = [track]
311 meeting2.tracks = [track]
312 meeting1.agenda_set.create(room=room, slot=slot2)
313 meeting2.check_schedule(slot1, room)
314
315 def test_check_schedule_no_error_same_track_ajdacent_sessions_allowed(
316 self
317 ):
318 slot1, slot2 = self.make_two_adjacent_slots()
319 room = factory.make_one(Room, summit=slot1.summit, name="testroom")
320 track = factory.make_one(
321 Track,
322 summit=slot1.summit,
323 title="adjacenttrack",
324 allow_adjacent_sessions=True
325 )
326 meeting1 = factory.make_one(
327 Meeting,
328 requires_dial_in=False,
329 summit=slot1.summit,
330 name="testmeeting1",
331 type='blueprint',
332 private=False
333 )
334 meeting2 = factory.make_one(
335 Meeting,
336 requires_dial_in=False,
337 summit=slot1.summit,
338 name="testmeeting2",
339 type='blueprint',
340 private=False
341 )
342 meeting1.tracks = [track]
343 meeting2.tracks = [track]
344 meeting1.agenda_set.create(room=room, slot=slot2)
345 meeting2.check_schedule(slot1, room)
346
347 def test_try_schedule_into_refuses_room_without_dial_in(self):
348 slot = self.make_open_slot()
349 room = factory.make_one(
350 Room,
351 has_dial_in=False,
352 summit=slot.summit,
353 name="testroom"
354 )
355 meeting = factory.make_one(
356 Meeting,
357 requires_dial_in=True,
358 summit=slot.summit,
359 name="testmeeting",
360 private=False
361 )
362
363 self.assertEqual(False, meeting.try_schedule_into([room]))
364 self.assertEqual(0, meeting.agenda_set.all().count())
365
366 def test_try_schedule_into_allows_room_with_dial_in(self):
367 slot = self.make_open_slot()
368 room = factory.make_one(
369 Room,
370 has_dial_in=True,
371 summit=slot.summit,
372 name="testroom"
373 )
374 meeting = factory.make_one(
375 Meeting,
376 requires_dial_in=True,
377 summit=slot.summit,
378 name="testmeeting",
379 private=False
380 )
381
382 self.assertEqual(True, meeting.try_schedule_into([room]))
383 self.assertEqual(1, meeting.agenda_set.all().count())
384
385 def test_link_to_pad_with_pad_url_set(self):
386 url = 'http://pad.com/url'
387 meeting = factory.make_one(Meeting, pad_url=url, private=False)
388 self.assertEqual(url, meeting.link_to_pad)
389
390 def get_pad_host(self):
391 summit_name = 'testsummit'
392 summit = factory.make_one(Summit, name=summit_name)
393 return getattr(summit, 'etherpad', 'http://pad.ubuntu.com/')
394
395 def test_link_to_pad_with_pad_url_unset(self):
396 summit_name = 'testsummit'
397 summit = factory.make_one(Summit, name=summit_name)
398 name = 'testmeeting'
399 meeting = factory.make_one(
400 Meeting,
401 pad_url=None,
402 name=name,
403 summit=summit,
404 private=False
405 )
406 pad_host = self.get_pad_host()
407 url = pad_host + summit_name + '-' + name
408 self.assertEqual(url, meeting.link_to_pad)
409
410 def test_link_to_pad_with_plus_in_meeting_name(self):
411 summit_name = 'testsummit'
412 summit = factory.make_one(Summit, name=summit_name)
413 name = 'test+meeting'
414 meeting = factory.make_one(
415 Meeting,
416 pad_url=None,
417 name=name,
418 summit=summit,
419 private=False
420 )
421 pad_host = self.get_pad_host()
422 url = pad_host + summit_name + '-' + name.replace("+", "-")
423 self.assertEqual(url, meeting.link_to_pad)
424
425 def test_edit_link_to_pad_with_pad_url_set(self):
426 url = 'http://pad.com/url'
427 meeting = factory.make_one(Meeting, pad_url=url, private=False)
428 self.assertEqual(url, meeting.edit_link_to_pad)
429
430 def test_edit_link_to_pad_with_pad_url_unset(self):
431 summit_name = 'testsummit'
432 summit = factory.make_one(Summit, name=summit_name)
433 name = 'testmeeting'
434 meeting = factory.make_one(
435 Meeting,
436 pad_url=None,
437 name=name,
438 summit=summit,
439 private=False
440 )
441 pad_host = self.get_pad_host()
442 url = pad_host + "ep/pad/view/" + summit_name + '-' + name + "/latest"
443 self.assertEqual(url, meeting.edit_link_to_pad)
444
445 def test_edit_link_to_pad_with_plus_in_meeting_name(self):
446 summit_name = 'testsummit'
447 summit = factory.make_one(Summit, name=summit_name)
448 name = 'test+meeting'
449 meeting = factory.make_one(
450 Meeting,
451 pad_url=None,
452 name=name,
453 summit=summit,
454 private=False
455 )
456 pad_host = self.get_pad_host()
457 url = (
458 pad_host
459 + "ep/pad/view/"
460 + summit_name
461 + '-'
462 + name.replace("+", "-")
463 + "/latest"
464 )
465 self.assertEqual(url, meeting.edit_link_to_pad)
466
467 def test_update_from_launchpad_sets_status(self):
468 summit = factory.make_one(Summit, timezone='utc', name='test-summit')
469 meeting = factory.make_one(
470 Meeting,
471 pad_url=None,
472 name='test-meeting',
473 summit=summit,
474 private=False
475 )
476 status = "Discussion"
477 name = meeting.name
478 elem = LaunchpadExportNode(status=status, name=name)
479 meeting.update_from_launchpad(elem)
480 self.assertEqual(status, meeting.status)
481
482 def test_update_from_launchpad_sets_priority(self):
483 summit = factory.make_one(Summit, timezone='utc', name='test-summit')
484 meeting = factory.make_one(
485 Meeting,
486 pad_url=None,
487 name='test-meeting',
488 summit=summit,
489 private=False
490 )
491 priority = 70
492 name = meeting.name
493 elem = LaunchpadExportNode(priority=priority, name=name)
494 meeting.update_from_launchpad(elem)
495 self.assertEqual(priority, meeting.priority)
496
497 def test_update_from_launchpad_sets_wiki_url(self):
498 summit = factory.make_one(Summit, timezone='utc', name='test-summit')
499 meeting = factory.make_one(
500 Meeting,
501 pad_url=None,
502 name='test-meeting',
503 summit=summit,
504 private=False
505 )
506 wiki_url = "http://example.com/somespec"
507 name = meeting.name
508 elem = LaunchpadExportNode(specurl=wiki_url, name=name)
509 meeting.update_from_launchpad(elem)
510 self.assertEqual(wiki_url, meeting.wiki_url)
511
512 def get_person_node(self, username, required=False):
513 elem = LaunchpadExportNode()
514 required_map = {True: "True", False: "False"}
515 elem.add_child(
516 "person",
517 LaunchpadExportNode(
518 name=username,
519 required=required_map[required]
520 )
521 )
522 return elem
523
524 def make_one_future_slot(self, summit=None):
525 if summit is None:
526 summit = factory.make_one(Summit)
527 now = datetime.datetime.utcnow()
528 one_hour = datetime.timedelta(hours=1)
529 return factory.make_one(
530 Slot,
531 summit=summit,
532 start=now+one_hour,
533 end=now+one_hour+one_hour,
534 type='open'
535 )
536
537 def make_summit_and_attendee(self):
538 username = "username"
539 user = factory.make_one(User, username=username)
540 summit = factory.make_one(Summit)
541 slot = self.make_one_future_slot(summit=summit)
542 attendee = summit.attendee_set.create(
543 user=user,
544 start_utc=slot.start_utc,
545 end_utc=slot.end_utc
546 )
547 return summit, attendee
548
549 def test_update_from_launchpad_adds_participant(self):
550 summit, attendee = self.make_summit_and_attendee()
551 meeting = factory.make_one(
552 Meeting,
553 pad_url=None,
554 name='test-meeting',
555 summit=summit,
556 private=False
557 )
558 name = meeting.name
559 elem = self.get_person_node(
560 attendee.user.username,
561 required=False,
562 )
563 meeting.update_from_launchpad(elem)
564 participant = meeting.participant_set.get()
565 self.assertEqual(attendee, participant.attendee)
566 self.assertEqual('ATTENDING', participant.participation)
567
568 def test_update_from_launchpad_sets_participant_essential(self):
569 summit, attendee = self.make_summit_and_attendee()
570 meeting = factory.make_one(
571 Meeting,
572 pad_url=None,
573 name='test-meeting',
574 summit=summit,
575 private=False
576 )
577 name = meeting.name
578 elem = self.get_person_node(
579 attendee.user.username,
580 required=True,
581 )
582 meeting.update_from_launchpad(elem)
583 participant = meeting.participant_set.get()
584 self.assertEqual('INTERESTED', participant.participation)
585
586 def test_update_from_launchpad_sets_from_launchpad(self):
587 summit, attendee = self.make_summit_and_attendee()
588 meeting = summit.meeting_set.create()
589 elem = self.get_person_node(attendee.user.username)
590 meeting.update_from_launchpad(elem)
591 participant = meeting.participant_set.get()
592 self.assertEqual(True, participant.from_launchpad)
593
594 def test_update_from_launchpad_removes_from_launchpad_unsubscribed(self):
595 summit, attendee = self.make_summit_and_attendee()
596 meeting = summit.meeting_set.create()
597 elem = self.get_person_node(attendee.user.username)
598 otheruser = factory.make_one(User, username="otheruser")
599 otherattendee = summit.attendee_set.create(user=otheruser)
600 meeting.participant_set.create(
601 attendee=otherattendee,
602 from_launchpad=True
603 )
604 meeting.update_from_launchpad(elem)
605 usernames = [
606 p.attendee.user.username for p in meeting.participant_set.all()
607 ]
608 self.assertEqual(["username"], usernames)
0609
=== added file 'summit/schedule/tests/meeting_page.py'
--- summit/schedule/tests/meeting_page.py 1970-01-01 00:00:00 +0000
+++ summit/schedule/tests/meeting_page.py 2013-02-27 15:35:39 +0000
@@ -0,0 +1,101 @@
1# The Summit Scheduler web application
2# Copyright (C) 2008 - 2013 Ubuntu Community, Canonical Ltd
3#
4# This program is free software: you can redistribute it and/or modify
5# it under the terms of the GNU Affero General Public License as
6# published by the Free Software Foundation, either version 3 of the
7# License, or (at your option) any later version.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU Affero General Public License for more details.
13#
14# You should have received a copy of the GNU Affero General Public License
15# along with this program. If not, see <http://www.gnu.org/licenses/>.
16
17
18import datetime
19from django import test as djangotest
20from django.core.urlresolvers import reverse
21from django.conf import settings
22
23from model_mommy import mommy as factory
24from summit.schedule.fields import NameField
25
26from summit.schedule.models import (
27 Summit,
28 Slot,
29 Meeting,
30 Room,
31 Agenda,
32)
33
34site_root = getattr(settings, 'SITE_ROOT', 'http://summit.ubuntu.com')
35
36# Monkey-patch our NameField into the types of fields that the factory
37# understands. This is simpler than trying to subclass the Mommy
38# class directly.
39factory.default_mapping[NameField] = str
40
41
42class MeetingPageTestCase(djangotest.TestCase):
43
44 def test_meeting_page_url(self):
45 """ Tests the creation and reverse lookup of meeting page urls"""
46 now = datetime.datetime.utcnow()
47 one_hour = datetime.timedelta(0, 3600)
48 summit = factory.make_one(Summit, name='uds-test')
49 summit.save()
50 slot = factory.make_one(
51 Slot,
52 start_utc=now,
53 end_utc=now+one_hour,
54 type='open',
55 summit=summit
56 )
57 slot.save()
58
59 room = factory.make_one(Room, summit=summit)
60 meeting = factory.make_one(
61 Meeting,
62 summit=summit,
63 name='test-meeting',
64 private=False
65 )
66 agenda = factory.make_one(
67 Agenda,
68 slot=slot,
69 meeting=meeting,
70 room=room
71 )
72
73 # check meeting page url generation
74 self.assertEquals(
75 meeting.meeting_page_url,
76 '/uds-test/meeting/%s/test-meeting/' % meeting.id
77 )
78
79 # check meeting page url reverse lookup
80 rev_args = ['uds-test', meeting.id, 'test-meeting']
81 reverse_url = reverse('summit.schedule.views.meeting', args=rev_args)
82 self.assertEquals(
83 reverse_url,
84 '/uds-test/meeting/%s/test-meeting/' % meeting.id
85 )
86
87 # check meeting details page
88 response = self.client.get(reverse_url)
89 self.assertEquals(response.status_code, 200)
90
91 # check meeting in ical
92 response = self.client.get('/uds-test.ical')
93 self.assertEquals(response.status_code, 200)
94 self.assertContains(
95 response,
96 'URL:%s/uds-test/meeting/%s/test-meeting/' % (
97 site_root,
98 meeting.id
99 ),
100 1
101 )
0102
=== added file 'summit/schedule/tests/meeting_search.py'
--- summit/schedule/tests/meeting_search.py 1970-01-01 00:00:00 +0000
+++ summit/schedule/tests/meeting_search.py 2013-02-27 15:35:39 +0000
@@ -0,0 +1,335 @@
1# The Summit Scheduler web application
2# Copyright (C) 2008 - 2013 Ubuntu Community, Canonical Ltd
3#
4# This program is free software: you can redistribute it and/or modify
5# it under the terms of the GNU Affero General Public License as
6# published by the Free Software Foundation, either version 3 of the
7# License, or (at your option) any later version.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU Affero General Public License for more details.
13#
14# You should have received a copy of the GNU Affero General Public License
15# along with this program. If not, see <http://www.gnu.org/licenses/>.
16
17
18import datetime
19from django import test as djangotest
20from django.core.urlresolvers import reverse
21from django.contrib.auth.models import User
22
23from model_mommy import mommy as factory
24from summit.schedule.fields import NameField
25
26from summit.schedule.models import (
27 Summit,
28 Slot,
29 Meeting,
30 Room,
31 Attendee,
32 Participant,
33)
34
35# Monkey-patch our NameField into the types of fields that the factory
36# understands. This is simpler than trying to subclass the Mommy
37# class directly.
38factory.default_mapping[NameField] = str
39
40
41class MeetingSearchTestCase(djangotest.TestCase):
42 """
43 This will test different options for deleting a meeting from
44 the front end UI.
45 """
46
47 form_html = '<form id="site_search_form"'
48
49 def setUp(self):
50 now = datetime.datetime.utcnow()
51 one_hour = datetime.timedelta(0, 3600)
52 self.summit = factory.make_one(
53 Summit,
54 name='uds-test',
55 date_start=now,
56 date_end=now+one_hour
57 )
58 self.slot = factory.make_one(
59 Slot,
60 summit=self.summit,
61 start_utc=now,
62 end_utc=now+one_hour
63 )
64 self.room = factory.make_one(Room)
65
66 def tearDown(self):
67 self.client.logout()
68
69 def test_searchform_exists_on_summit_view(self):
70 ''' Search form should appear on the summit view page '''
71 response = self.client.get(
72 reverse(
73 'summit.schedule.views.summit',
74 args=[self.summit.name]
75 )
76 )
77 self.assertContains(response, self.form_html, 1)
78
79 def test_searchform_exists_on_daily_view(self):
80 ''' Search form should appear on the list view page '''
81 response = self.client.get(
82 reverse(
83 'summit.schedule.views.daily_schedule',
84 args=[self.summit.name, '2012-10-10']
85 )
86 )
87 self.assertContains(response, self.form_html, 1)
88
89 def test_searchform_exists_on_today_view(self):
90 ''' Search form should appear on the today view page '''
91 response = self.client.get(
92 reverse(
93 'summit.schedule.views.today_view',
94 args=[self.summit.name]
95 )
96 )
97 self.assertContains(response, self.form_html, 1)
98
99 def test_searchform_exists_on_meeting_view(self):
100 ''' Search form should appear on the meeting view page '''
101 meeting = factory.make_one(
102 Meeting,
103 summit=self.summit,
104 requires_dial_in=False,
105 private=False
106 )
107
108 response = self.client.get(
109 reverse(
110 'summit.schedule.views.meeting',
111 args=[self.summit.name, meeting.id, meeting.name]
112 )
113 )
114 self.assertContains(response, self.form_html, 1)
115
116 def test_searchform_not_exists_on_index(self):
117 '''
118 Search form should NOT appear on the index page because
119 there isn't a summit selected
120 '''
121 response = self.client.get(reverse('summit.common.views.index'))
122 self.assertContains(response, self.form_html, 0)
123
124 def test_meeting_in_search_results(self):
125 '''
126 Meeting should appear in search results page if the query
127 matches the name or title
128 '''
129 meeting = factory.make_one(
130 Meeting,
131 summit=self.summit,
132 name='test-name',
133 title='Test Title',
134 requires_dial_in=False,
135 private=False
136 )
137
138 # Attempt to match 'name' against 'test-name' in Meeting.name
139 response = self.client.get(
140 reverse(
141 'summit.schedule.views.search',
142 args=[self.summit.name]
143 ),
144 {'q': 'name'}
145 )
146 self.assertContains(response, self.form_html, 1)
147 self.assertContains(
148 response,
149 '<a href="%s">Test Title</a>' % meeting.get_meeting_page_url(),
150 1
151 )
152
153 # Attempt to match 'title' against 'Test Title' in Meeting.title
154 response = self.client.get(
155 reverse(
156 'summit.schedule.views.search',
157 args=[self.summit.name]
158 ),
159 {'q': 'title'}
160 )
161 self.assertContains(response, self.form_html, 1)
162 self.assertContains(
163 response,
164 '<a href="%s">Test Title</a>' % meeting.get_meeting_page_url(),
165 1
166 )
167
168 def test_meeting_not_in_search_results(self):
169 '''
170 Meetings for one summit should NOT appear when searching
171 a different summit
172 '''
173 now = datetime.datetime.utcnow()
174 one_hour = datetime.timedelta(0, 3600)
175
176 # Create a second summit
177 other_summit = factory.make_one(
178 Summit,
179 name='uds-other',
180 date_start=now,
181 date_end=now+one_hour
182 )
183
184 meeting = factory.make_one(
185 Meeting,
186 summit=other_summit,
187 name='test-name',
188 title='Test Title',
189 requires_dial_in=False,
190 private=False
191 )
192
193 # Attempt to match 'test' against 'test-name' or 'Test Title'
194 # should return 0 results because the the meeting is in
195 # other_summit, not self.summit
196 response = self.client.get(
197 reverse(
198 'summit.schedule.views.search',
199 args=[self.summit.name]
200 ),
201 {'q': 'test'}
202 )
203 self.assertContains(response, self.form_html, 1)
204 self.assertContains(
205 response,
206 '<a href="%s">Test Title</a>' % meeting.get_meeting_page_url(),
207 0
208 )
209
210 # Same test, but searching the correct other_summit should return
211 # 1 result
212 response = self.client.get(
213 reverse(
214 'summit.schedule.views.search',
215 args=[other_summit.name]
216 ),
217 {'q': 'test'}
218 )
219 self.assertContains(response, self.form_html, 1)
220 self.assertContains(
221 response,
222 '<a href="%s">Test Title</a>' % meeting.get_meeting_page_url(),
223 1
224 )
225
226 def test_private_meeting_not_shown(self):
227 '''
228 Private meetings should not be in the results if the attendee
229 is not attending it
230 '''
231 now = datetime.datetime.now()
232 week = datetime.timedelta(days=7)
233 meeting = factory.make_one(
234 Meeting,
235 summit=self.summit,
236 name='test-name',
237 title='Test Title',
238 requires_dial_in=False,
239 private=True
240 )
241 user = factory.make_one(
242 User,
243 username='testuser',
244 first_name='Test',
245 last_name='User',
246 is_active=True
247 )
248 user.set_password('password')
249 user.save()
250 attendee = factory.make_one(
251 Attendee,
252 summit=self.summit,
253 user=user,
254 start_utc=now,
255 end_utc=now+week
256 )
257 participant = factory.make_one(
258 Participant,
259 meeting=meeting,
260 attendee=attendee,
261 participation='ATTENDING',
262 from_launchpad=False
263 )
264
265 # Attempt to match 'name' against 'test-name' in Meeting.name
266 response = self.client.get(
267 reverse(
268 'summit.schedule.views.search',
269 args=[self.summit.name]
270 ),
271 {'q': 'test'}
272 )
273 self.assertContains(response, self.form_html, 1)
274 self.assertContains(
275 response,
276 '<a href="%s">Test Title</a>' % meeting.get_meeting_page_url(),
277 0
278 )
279
280 def test_private_meeting_with_attendee_shown(self):
281 '''
282 Private meetings should be in the results if the attendee
283 is attending it
284 '''
285 now = datetime.datetime.now()
286 week = datetime.timedelta(days=7)
287 meeting = factory.make_one(
288 Meeting,
289 summit=self.summit,
290 name='test-name',
291 title='Test Title',
292 requires_dial_in=False,
293 private=True
294 )
295 user = factory.make_one(
296 User,
297 username='testuser',
298 first_name='Test',
299 last_name='User',
300 is_active=True
301 )
302 user.set_password('password')
303 user.save()
304 attendee = factory.make_one(
305 Attendee,
306 summit=self.summit,
307 user=user,
308 start_utc=now,
309 end_utc=now+week
310 )
311 participant = factory.make_one(
312 Participant,
313 meeting=meeting,
314 attendee=attendee,
315 participation='ATTENDING',
316 from_launchpad=False
317 )
318
319 logged_in = self.client.login(username='testuser', password='password')
320 self.assertTrue(logged_in)
321
322 # Attempt to match 'name' against 'test-name' in Meeting.name
323 response = self.client.get(
324 reverse(
325 'summit.schedule.views.search',
326 args=[self.summit.name]
327 ),
328 {'q': 'test'}
329 )
330 self.assertContains(response, self.form_html, 1)
331 self.assertContains(
332 response,
333 '<a href="%s">Test Title</a>' % meeting.get_meeting_page_url(),
334 1
335 )
0336
=== added file 'summit/schedule/tests/participation_registration.py'
--- summit/schedule/tests/participation_registration.py 1970-01-01 00:00:00 +0000
+++ summit/schedule/tests/participation_registration.py 2013-02-27 15:35:39 +0000
@@ -0,0 +1,202 @@
1# The Summit Scheduler web application
2# Copyright (C) 2008 - 2013 Ubuntu Community, Canonical Ltd
3#
4# This program is free software: you can redistribute it and/or modify
5# it under the terms of the GNU Affero General Public License as
6# published by the Free Software Foundation, either version 3 of the
7# License, or (at your option) any later version.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU Affero General Public License for more details.
13#
14# You should have received a copy of the GNU Affero General Public License
15# along with this program. If not, see <http://www.gnu.org/licenses/>.
16
17
18import datetime
19from django import test as djangotest
20from django.contrib.auth.models import User
21from django.core.urlresolvers import reverse
22
23from model_mommy import mommy as factory
24from summit.schedule.fields import NameField
25
26from summit.schedule.models import (
27 Summit,
28 Slot,
29 Attendee,
30 Meeting,
31 Room,
32 Participant,
33)
34
35# Monkey-patch our NameField into the types of fields that the factory
36# understands. This is simpler than trying to subclass the Mommy
37# class directly.
38factory.default_mapping[NameField] = str
39
40
41class ParticipationRegistrationTestCase(djangotest.TestCase):
42
43 def setUp(self):
44 now = datetime.datetime.utcnow()
45 one_hour = datetime.timedelta(0, 3600)
46 week = datetime.timedelta(days=5)
47 self.summit = factory.make_one(Summit, name='uds-test')
48 self.slot = factory.make_one(
49 Slot,
50 start_utc=now+one_hour,
51 end_utc=now+(2*one_hour),
52 type='open',
53 summit=self.summit
54 )
55
56 self.room = factory.make_one(Room, summit=self.summit, type='open')
57 self.meeting = factory.make_one(
58 Meeting,
59 summit=self.summit,
60 name='meeting1',
61 private=False,
62 requires_dial_in=False,
63 spec_url=''
64 )
65
66 self.user = factory.make_one(
67 User,
68 username='testuser',
69 first_name='Test',
70 last_name='User',
71 is_active=True
72 )
73 self.user.set_password('password')
74 self.user.save()
75
76 self.attendee = factory.make_one(
77 Attendee,
78 summit=self.summit,
79 user=self.user,
80 start_utc=now,
81 end_utc=now+week
82 )
83
84 def tearDown(self):
85 pass
86
87 def login(self):
88 logged_in = self.client.login(username='testuser', password='password')
89 self.assertTrue(logged_in)
90
91 def test_attend_link(self):
92 self.assertEquals(
93 0,
94 Participant.objects.filter(
95 attendee=self.attendee
96 ).count()
97 )
98 self.login()
99 response = self.client.get(
100 reverse(
101 'summit.schedule.views.meeting',
102 args=('uds-test', self.meeting.id, 'meeting1')
103 )
104 )
105 self.assertContains(response, 'Attend this meeting', 1)
106 self.assertContains(response, 'Subscribe to this meeting', 0)
107 self.assertContains(response, 'Skip this meeting', 0)
108
109 def test_subscribe_link(self):
110 self.assertEquals(
111 0,
112 Participant.objects.filter(
113 attendee=self.attendee
114 ).count()
115 )
116 self.login()
117 self.meeting.spec_url = 'http://examplespec.com/test'
118 self.meeting.save()
119 response = self.client.get(
120 reverse(
121 'summit.schedule.views.meeting',
122 args=('uds-test', self.meeting.id, 'meeting1')
123 )
124 )
125 self.assertContains(response, 'Subscribe to blueprint', 1)
126 self.assertContains(
127 response,
128 'http://examplespec.com/test/+subscribe',
129 1
130 )
131 self.assertContains(response, 'Attend this meeting', 1)
132 self.assertContains(response, 'Skip this meeting', 0)
133
134 def test_skip_link(self):
135 self.meeting.participant_set.create(
136 attendee=self.attendee,
137 participation='ATTENDING',
138 from_launchpad=False
139 )
140 self.assertEquals(
141 1,
142 Participant.objects.filter(
143 attendee=self.attendee
144 ).count()
145 )
146 self.login()
147 response = self.client.get(
148 reverse(
149 'summit.schedule.views.meeting',
150 args=('uds-test', self.meeting.id, 'meeting1')
151 )
152 )
153 self.assertContains(response, 'Skip this meeting', 1)
154 self.assertContains(response, 'Subscribe to this meeting', 0)
155 self.assertContains(response, 'Attend this meeting', 0)
156
157 def test_add_participation(self):
158 self.assertEquals(
159 0,
160 Participant.objects.filter(
161 attendee=self.attendee
162 ).count()
163 )
164 self.login()
165 response = self.client.get(
166 reverse(
167 'summit.schedule.views.register',
168 args=('uds-test', self.meeting.id, 'meeting1')
169 )
170 )
171 self.assertEquals(
172 1,
173 Participant.objects.filter(
174 attendee=self.attendee
175 ).count()
176 )
177
178 def test_delete_participation(self):
179 self.meeting.participant_set.create(
180 attendee=self.attendee,
181 participation='ATTENDING',
182 from_launchpad=False
183 )
184 self.assertEquals(
185 1,
186 Participant.objects.filter(
187 attendee=self.attendee
188 ).count()
189 )
190 self.login()
191 response = self.client.get(
192 reverse(
193 'summit.schedule.views.unregister',
194 args=('uds-test', self.meeting.id, 'meeting1')
195 )
196 )
197 self.assertEquals(
198 0,
199 Participant.objects.filter(
200 attendee=self.attendee
201 ).count()
202 )
0203
=== added file 'summit/schedule/tests/private_scheduling.py'
--- summit/schedule/tests/private_scheduling.py 1970-01-01 00:00:00 +0000
+++ summit/schedule/tests/private_scheduling.py 2013-02-27 15:35:39 +0000
@@ -0,0 +1,225 @@
1# The Summit Scheduler web application
2# Copyright (C) 2008 - 2013 Ubuntu Community, Canonical Ltd
3#
4# This program is free software: you can redistribute it and/or modify
5# it under the terms of the GNU Affero General Public License as
6# published by the Free Software Foundation, either version 3 of the
7# License, or (at your option) any later version.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU Affero General Public License for more details.
13#
14# You should have received a copy of the GNU Affero General Public License
15# along with this program. If not, see <http://www.gnu.org/licenses/>.
16
17
18import datetime
19from django import test as djangotest
20from django.contrib.auth.models import User
21
22from model_mommy import mommy as factory
23from summit.schedule.fields import NameField
24
25from summit.schedule.models import (
26 Summit,
27 Slot,
28 Attendee,
29 Meeting,
30 Room,
31 Agenda,
32)
33
34# Monkey-patch our NameField into the types of fields that the factory
35# understands. This is simpler than trying to subclass the Mommy
36# class directly.
37factory.default_mapping[NameField] = str
38
39
40class PrivateSchedulingTestCase(djangotest.TestCase):
41
42 def setUp(self):
43 now = datetime.datetime.utcnow()
44 one_hour = datetime.timedelta(0, 3600)
45 week = datetime.timedelta(days=5)
46 self.summit = factory.make_one(Summit, name='uds-test')
47 self.slot = factory.make_one(
48 Slot,
49 start_utc=now+one_hour,
50 end_utc=now+(2*one_hour),
51 type='open',
52 summit=self.summit
53 )
54
55 self.open_room = factory.make_one(
56 Room,
57 summit=self.summit,
58 type='open'
59 )
60 self.public_meeting = factory.make_one(
61 Meeting,
62 summit=self.summit,
63 name='meeting1',
64 private=False,
65 requires_dial_in=False,
66 approved='APPROVED'
67 )
68
69 self.private_room = factory.make_one(
70 Room,
71 summit=self.summit,
72 type='private'
73 )
74 self.private_meeting = factory.make_one(
75 Meeting,
76 summit=self.summit,
77 name='meeting2',
78 private=True,
79 requires_dial_in=False,
80 approved='APPROVED'
81 )
82
83 self.user = factory.make_one(
84 User,
85 username='testuser',
86 first_name='Test',
87 last_name='User'
88 )
89 self.attendee = factory.make_one(
90 Attendee,
91 summit=self.summit,
92 user=self.user,
93 start_utc=now,
94 end_utc=now+week
95 )
96
97 def tearDown(self):
98 pass
99
100 def assertRaises(self, exception_type, function, args):
101 try:
102 function(*args)
103 raise AssertionError(
104 'Callable failed to raise exception %s' % exception_type
105 )
106 except exception_type, e:
107 return True
108
109 def run_autoschedule(self):
110 from django.core.management import execute_from_command_line
111 execute_from_command_line(
112 argv=['manage.py', 'autoschedule', 'uds-test', '-v', '2']
113 )
114
115 def test_private_meeting_schedule(self):
116 '''
117 General run of the autoschedule, no gurantee of what ends up where
118 '''
119 self.run_autoschedule()
120
121 # Private meetings should not ever be autoscheduled
122 self.assertEquals(
123 0,
124 Agenda.objects.filter(
125 slot__summit=self.summit,
126 meeting__private=True,
127 room__type='open'
128 ).count()
129 )
130 self.assertEquals(
131 0,
132 Agenda.objects.filter(
133 slot__summit=self.summit,
134 meeting__private=False,
135 room__type='private'
136 ).count()
137 )
138 # Private rooms should not ever be autoscheduled
139 self.assertEquals(
140 0,
141 Agenda.objects.filter(
142 slot__summit=self.summit,
143 meeting__private=True,
144 room__type='private'
145 ).count()
146 )
147
148 # Public meetings in open rooms should be autoscheduled
149 self.assertEquals(
150 1,
151 Agenda.objects.filter(
152 slot__summit=self.summit,
153 meeting__private=False,
154 room__type='open'
155 ).count()
156 )
157
158 def test_no_available_public_room(self):
159 '''
160 Make sure public meetings will not be autoscheduled into private rooms
161 '''
162 self.open_room.type = 'private'
163 self.open_room.save()
164
165 self.run_autoschedule()
166
167 # Without an open room, public meetings should not be autoscheduled
168 self.assertEquals(0, self.public_meeting.agenda_set.count())
169
170 # Private meetings should not ever be autoscheduled
171 self.assertEquals(0, self.private_meeting.agenda_set.count())
172
173 # Private rooms should not ever be autoscheduled
174 self.assertEquals(
175 0,
176 Agenda.objects.filter(
177 room__type='private'
178 ).count()
179 )
180
181 def test_no_available_private_room(self):
182 '''
183 Make sure private meetings will not be autoscheduled into open rooms
184 '''
185 self.private_room.type = 'open'
186 self.private_room.save()
187
188 self.run_autoschedule()
189
190 # Private meetings should not ever be autoscheduled
191 self.assertEquals(0, self.private_meeting.agenda_set.count())
192
193 # Public meeting should be autoscheduled into one of the two open rooms
194 self.assertEquals(1, self.public_meeting.agenda_set.count())
195 self.assertEquals(1, Agenda.objects.filter(room__type='open').count())
196
197 def test_required_participant_in_private_meeting(self):
198 '''
199 Make sure meetings aren't scheduled when
200 someone is in a private meeting.
201 '''
202 # Make the same person required for both meetings
203 self.public_meeting.participant_set.create(
204 attendee=self.attendee,
205 participation='REQUIRED'
206 )
207 self.private_meeting.participant_set.create(
208 attendee=self.attendee,
209 participation='REQUIRED'
210 )
211 # Schedule the private meeting in the one available slot
212 self.private_room.agenda_set.create(
213 slot=self.slot,
214 meeting=self.private_meeting
215 )
216
217 self.run_autoschedule()
218
219 # Check that the private meeting is still scheduled
220 self.assertEquals(
221 1,
222 self.private_meeting.agenda_set.count()
223 )
224 # Check that the public meeting is not scheduled
225 self.assertEquals(0, self.public_meeting.agenda_set.count())
0226
=== added file 'summit/schedule/tests/render_schedule.py'
--- summit/schedule/tests/render_schedule.py 1970-01-01 00:00:00 +0000
+++ summit/schedule/tests/render_schedule.py 2013-02-27 15:35:39 +0000
@@ -0,0 +1,196 @@
1# The Summit Scheduler web application
2# Copyright (C) 2008 - 2013 Ubuntu Community, Canonical Ltd
3#
4# This program is free software: you can redistribute it and/or modify
5# it under the terms of the GNU Affero General Public License as
6# published by the Free Software Foundation, either version 3 of the
7# License, or (at your option) any later version.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU Affero General Public License for more details.
13#
14# You should have received a copy of the GNU Affero General Public License
15# along with this program. If not, see <http://www.gnu.org/licenses/>.
16
17
18import datetime
19from django import test as djangotest
20from django.core.urlresolvers import reverse
21from django.contrib.auth.models import User
22from django.core.cache import cache
23
24from model_mommy import mommy as factory
25from summit.schedule.fields import NameField
26
27from summit.schedule.models import (
28 Summit,
29 Slot,
30 Attendee,
31 Meeting,
32 Track,
33 Room,
34 Agenda,
35)
36
37# Monkey-patch our NameField into the types of fields that the factory
38# understands. This is simpler than trying to subclass the Mommy
39# class directly.
40factory.default_mapping[NameField] = str
41
42
43class RenderScheduleTestCase(djangotest.TestCase):
44
45 def setUp(self):
46 now = datetime.datetime.utcnow()
47 one_hour = datetime.timedelta(0, 3600)
48 week = datetime.timedelta(days=5)
49 self.summit = factory.make_one(Summit, name='uds-test', timezone='UTC')
50 self.slot = factory.make_one(
51 Slot,
52 start_utc=now+one_hour,
53 end_utc=now+(2*one_hour),
54 type='open',
55 summit=self.summit
56 )
57
58 self.track1 = factory.make_one(
59 Track,
60 slug='test_slug',
61 summit=self.summit
62 )
63 self.room1 = factory.make_one(
64 Room,
65 summit=self.summit,
66 name='room1'
67 )
68 self.meeting1 = factory.make_one(
69 Meeting,
70 summit=self.summit,
71 name='meeting1',
72 private=False,
73 requires_dial_in=False
74 )
75 self.agenda1 = factory.make_one(
76 Agenda,
77 slot=self.slot,
78 meeting=self.meeting1,
79 room=self.room1
80 )
81
82 self.user = factory.make_one(
83 User,
84 username='testuser',
85 first_name='Test',
86 last_name='User'
87 )
88 self.attendee = factory.make_one(
89 Attendee,
90 summit=self.summit,
91 user=self.user,
92 start_utc=now,
93 end_utc=now+week
94 )
95
96 def tearDown(self):
97 # Cached requests cause render.py to return old data.
98 # We will clear the cache
99 if hasattr(cache, 'clear'):
100 cache.clear()
101 # Older django didn't have .clear, but locmem cache did have ._cull
102 elif hasattr(cache, '_cull'):
103 cache._cull()
104
105 def request_schedule(self):
106 schedule_args = [self.summit.name, self.agenda1.slot.start_utc.date()]
107 schedule_url = reverse(
108 'summit.schedule.views.by_date',
109 args=schedule_args
110 )
111 response = self.client.get(schedule_url)
112 return response
113
114 def test_percent_in_meeting_name(self):
115 self.meeting1.name = 'test%meeting'
116 self.meeting1.save()
117
118 response = self.request_schedule()
119
120 self.assertContains(response, 'test%meeting', 1)
121
122 def test_percent_in_meeting_title(self):
123 self.meeting1.title = 'test % meeting'
124 self.meeting1.save()
125
126 response = self.request_schedule()
127
128 self.assertContains(response, 'test % meeting', 1)
129
130 def test_percent_in_room_title(self):
131 self.meeting1.type = 'talk'
132 self.meeting1.save()
133 self.room1.title = 'test % room'
134 self.room1.save()
135
136 response = self.request_schedule()
137
138 # Room title is displayed at top and bottom of the schedule,
139 # and also on the meeting div for self.meeting1 which is scheduled
140 # for that room
141 self.assertContains(response, 'test % room', 4)
142
143 def test_percent_in_meeting_track_title(self):
144 self.track1.title = 'test % track'
145 self.track1.save()
146 self.meeting1.tracks.add(self.track1)
147
148 response = self.request_schedule()
149
150 self.assertContains(response, 'test % track', 1)
151
152 def test_percent_in_meeting_track_slug(self):
153 self.track1.slug = 'test%track'
154 self.track1.save()
155 self.meeting1.tracks.add(self.track1)
156
157 response = self.request_schedule()
158
159 self.assertContains(response, 'test%track', 1)
160
161 def test_specify_rooms_in_schedule(self):
162 room2 = factory.make_one(
163 Room,
164 summit=self.summit,
165 name='room2',
166 title='Room 2'
167 )
168 self.room1.title = 'Room 1'
169 self.room1.save()
170 self.agenda1.delete()
171
172 schedule_args = [self.summit.name, self.agenda1.slot.start_utc.date()]
173 schedule_url = reverse(
174 'summit.schedule.views.by_date',
175 args=schedule_args
176 )
177
178 response = self.client.get(schedule_url)
179 self.assertContains(response, self.room1.title, 2)
180 self.assertContains(response, room2.title, 2)
181
182 response = self.client.get(schedule_url + '?rooms=room1')
183 self.assertContains(response, self.room1.title, 2)
184 self.assertContains(response, room2.title, 0)
185
186 response = self.client.get(schedule_url + '?rooms=room2')
187 self.assertContains(response, self.room1.title, 0)
188 self.assertContains(response, room2.title, 2)
189
190 response = self.client.get(schedule_url + '?rooms=room1,room2')
191 self.assertContains(response, self.room1.title, 2)
192 self.assertContains(response, room2.title, 2)
193
194 response = self.client.get(schedule_url + '?rooms=unknown1,unknown2')
195 self.assertContains(response, self.room1.title, 0)
196 self.assertContains(response, room2.title, 0)
0197
=== added file 'summit/schedule/tests/request_factory.py'
--- summit/schedule/tests/request_factory.py 1970-01-01 00:00:00 +0000
+++ summit/schedule/tests/request_factory.py 2013-02-27 15:35:39 +0000
@@ -0,0 +1,80 @@
1# The Summit Scheduler web application
2# Copyright (C) 2008 - 2013 Ubuntu Community, Canonical Ltd
3#
4# This program is free software: you can redistribute it and/or modify
5# it under the terms of the GNU Affero General Public License as
6# published by the Free Software Foundation, either version 3 of the
7# License, or (at your option) any later version.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU Affero General Public License for more details.
13#
14# You should have received a copy of the GNU Affero General Public License
15# along with this program. If not, see <http://www.gnu.org/licenses/>.
16
17
18from django import test as djangotest
19from django.core.handlers.base import BaseHandler
20from django.core.handlers.wsgi import WSGIRequest
21from django.conf import settings
22
23from model_mommy import mommy as factory
24from summit.schedule.fields import NameField
25
26# Monkey-patch our NameField into the types of fields that the factory
27# understands. This is simpler than trying to subclass the Mommy
28# class directly.
29factory.default_mapping[NameField] = str
30
31site_root = getattr(settings, 'SITE_ROOT', 'http://summit.ubuntu.com')
32theme_media = getattr(settings, 'THEME_MEDIA', 'ubuntu_website.MEDIA_ROOT')
33
34
35class RequestFactory(djangotest.Client):
36 """
37 Class that lets you create mock Request objects for use in testing.
38
39 Usage:
40
41 rf = RequestFactory()
42 get_request = rf.get('/hello/')
43 post_request = rf.post('/submit/', {'foo': 'bar'})
44
45 This class re-uses the django.test.client.Client interface, docs here:
46 http://www.djangoproject.com/documentation/testing/#the-test-client
47
48 Once you have a request object you can pass it to any view function,
49 just as if that view had been hooked up using a URLconf.
50
51 """
52 def request(self, **request):
53 """
54 Similar to parent class, but returns the request object as soon as it
55 has created it.
56 """
57 environ = {
58 'HTTP_COOKIE': self.cookies,
59 'PATH_INFO': '/',
60 'QUERY_STRING': '',
61 'REQUEST_METHOD': 'GET',
62 'SCRIPT_NAME': '',
63 'SERVER_NAME': 'testserver',
64 'SERVER_PORT': 80,
65 'SERVER_PROTOCOL': 'HTTP/1.1',
66 'wsgi.input': '',
67 }
68 environ.update(self.defaults)
69 environ.update(request)
70 request = WSGIRequest(environ)
71 handler = BaseHandler()
72 handler.load_middleware()
73 for middleware_method in handler._request_middleware:
74 if middleware_method(request):
75 raise Exception(
76 "Couldn't create request mock object - "
77 "request middleware %s returned a response"
78 % middleware_method
79 )
80 return request
081
=== added file 'summit/schedule/tests/reverse_url.py'
--- summit/schedule/tests/reverse_url.py 1970-01-01 00:00:00 +0000
+++ summit/schedule/tests/reverse_url.py 2013-02-27 15:35:39 +0000
@@ -0,0 +1,220 @@
1# The Summit Scheduler web application
2# Copyright (C) 2008 - 2013 Ubuntu Community, Canonical Ltd
3#
4# This program is free software: you can redistribute it and/or modify
5# it under the terms of the GNU Affero General Public License as
6# published by the Free Software Foundation, either version 3 of the
7# License, or (at your option) any later version.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU Affero General Public License for more details.
13#
14# You should have received a copy of the GNU Affero General Public License
15# along with this program. If not, see <http://www.gnu.org/licenses/>.
16
17
18import datetime
19from django import test as djangotest
20from django.core.urlresolvers import reverse
21from django.contrib.auth.models import User
22
23from model_mommy import mommy as factory
24from summit.schedule.fields import NameField
25
26from summit.schedule.models import (
27 Summit,
28 Slot,
29 Meeting,
30 Track,
31 Room,
32)
33
34# Monkey-patch our NameField into the types of fields that the factory
35# understands. This is simpler than trying to subclass the Mommy
36# class directly.
37factory.default_mapping[NameField] = str
38
39
40class ReverseUrlLookupTestCase(djangotest.TestCase):
41
42 def setUp(self):
43 now = datetime.datetime.utcnow()
44 one_hour = datetime.timedelta(0, 3600)
45 self.summit = factory.make_one(Summit, name='uds-test')
46 self.summit.save()
47 self.slot = factory.make_one(
48 Slot,
49 start_utc=now,
50 end_utc=now+one_hour,
51 type='open',
52 summit=self.summit
53 )
54 self.slot.save()
55
56 def tearDown(self):
57 pass
58
59 def test_meeting_name_with_period(self):
60 '''
61 Testing a meeting with a . in the name
62 '''
63 meeting = factory.make_one(
64 Meeting,
65 summit=self.summit,
66 name='test.meeting',
67 private=False
68 )
69
70 rev_args = ['uds-test', meeting.id, 'test.meeting']
71 reverse_url = reverse('summit.schedule.views.meeting', args=rev_args)
72 self.assertEquals(
73 reverse_url,
74 '/uds-test/meeting/%s/test.meeting/' % meeting.id
75 )
76
77 def test_room_name_with_period(self):
78 '''
79 Test the URL for a room name with a . in the name for both the website
80 and the ical
81 '''
82 room = factory.make_one(Room, summit=self.summit, name='test.room')
83
84 rev_args = ['uds-test', 'test.room']
85 reverse_url = reverse('summit.schedule.views.by_room', args=rev_args)
86 self.assertEquals(reverse_url, '/uds-test/test.room/')
87
88 reverse_url = reverse('summit.schedule.views.room_ical', args=rev_args)
89 self.assertEquals(reverse_url, '/uds-test/room/test.room.ical')
90
91 def test_track_name_with_period(self):
92 '''
93 Test the URL for a track name with a . in the name for both the website
94 and the ical
95 '''
96 track = factory.make_one(Track, summit=self.summit, slug='test.track')
97
98 rev_args = ['uds-test', 'test.track']
99 reverse_url = reverse('summit.schedule.views.by_track', args=rev_args)
100 self.assertEquals(reverse_url, '/uds-test/track/test.track/')
101
102 reverse_url = reverse(
103 'summit.schedule.views.track_ical',
104 args=rev_args
105 )
106 self.assertEquals(reverse_url, '/uds-test/track/test.track.ical')
107
108 def test_participant_name_with_period(self):
109 '''
110 Test the URL for a user with a . in their name for the website and
111 the iCal
112 '''
113 user = factory.make_one(User, username='test.user')
114
115 rev_args = ['uds-test', 'test.user']
116 reverse_url = reverse('summit.schedule.views.user_ical', args=rev_args)
117 self.assertEquals(reverse_url, '/uds-test/participant/test.user.ical')
118
119 def test_meeting_name_with_percent(self):
120 '''
121 Test the URL for a meeting with a % in the name
122 '''
123 meeting = factory.make_one(
124 Meeting,
125 summit=self.summit,
126 name='test.meeting',
127 private=False
128 )
129
130 rev_args = ['uds-test', meeting.id, 'test%meeting']
131 reverse_url = reverse('summit.schedule.views.meeting', args=rev_args)
132 self.assertEquals(
133 reverse_url,
134 '/uds-test/meeting/%s/test%%meeting/' % meeting.id
135 )
136
137 def test_meeting_name_with_plus_sign(self):
138 meeting = factory.make_one(
139 Meeting,
140 summit=self.summit,
141 name='test.meeting',
142 private=False
143 )
144 rev_args = ['uds-test', meeting.id, 'test+meeting']
145 reverse_url = reverse('summit.schedule.views.meeting', args=rev_args)
146 self.assertEquals(
147 reverse_url,
148 '/uds-test/meeting/%s/test+meeting/' % meeting.id
149 )
150
151 def test_room_name_with_percent(self):
152 '''
153 Test the URL for a room with a % in the name for both the website
154 and the iCal
155 '''
156 room = factory.make_one(Room, summit=self.summit, name='test.room')
157
158 rev_args = ['uds-test', 'test%room']
159 reverse_url = reverse('summit.schedule.views.by_room', args=rev_args)
160 self.assertEquals(reverse_url, '/uds-test/test%room/')
161
162 reverse_url = reverse('summit.schedule.views.room_ical', args=rev_args)
163 self.assertEquals(reverse_url, '/uds-test/room/test%room.ical')
164
165 def test_room_name_with_plus_sign(self):
166 room = factory.make_one(Room, summit=self.summit, name='test.room')
167
168 rev_args = ['uds-test', 'test+room']
169 reverse_url = reverse('summit.schedule.views.by_room', args=rev_args)
170 self.assertEquals(reverse_url, '/uds-test/test+room/')
171
172 reverse_url = reverse('summit.schedule.views.room_ical', args=rev_args)
173 self.assertEquals(reverse_url, '/uds-test/room/test+room.ical')
174
175 def test_track_name_with_percent(self):
176 '''
177 Test the URL for a track with a % in the name for both the website
178 and the iCal
179 '''
180 track = factory.make_one(Track, summit=self.summit, slug='test.track')
181
182 rev_args = ['uds-test', 'test%track']
183 reverse_url = reverse('summit.schedule.views.by_track', args=rev_args)
184 self.assertEquals(reverse_url, '/uds-test/track/test%track/')
185
186 reverse_url = reverse(
187 'summit.schedule.views.track_ical',
188 args=rev_args
189 )
190 self.assertEquals(reverse_url, '/uds-test/track/test%track.ical')
191
192 def test_track_name_with_plus_sign(self):
193 track = factory.make_one(Track, summit=self.summit, slug='test.track')
194
195 rev_args = ['uds-test', 'test+track']
196 reverse_url = reverse('summit.schedule.views.by_track', args=rev_args)
197 self.assertEquals(reverse_url, '/uds-test/track/test+track/')
198
199 reverse_url = reverse(
200 'summit.schedule.views.track_ical',
201 args=rev_args
202 )
203 self.assertEquals(reverse_url, '/uds-test/track/test+track.ical')
204
205 def test_participant_name_with_percent(self):
206 '''
207 Test the iCal URL for a participant with a % in the name.
208 '''
209 user = factory.make_one(User, username='test.user')
210
211 rev_args = ['uds-test', 'test%user']
212 reverse_url = reverse('summit.schedule.views.user_ical', args=rev_args)
213 self.assertEquals(reverse_url, '/uds-test/participant/test%user.ical')
214
215 def test_participant_name_with_plus_sign(self):
216 user = factory.make_one(User, username='test.user')
217
218 rev_args = ['uds-test', 'test+user']
219 reverse_url = reverse('summit.schedule.views.user_ical', args=rev_args)
220 self.assertEquals(reverse_url, '/uds-test/participant/test+user.ical')
0221
=== added file 'summit/schedule/tests/schedule.py'
--- summit/schedule/tests/schedule.py 1970-01-01 00:00:00 +0000
+++ summit/schedule/tests/schedule.py 2013-02-27 15:35:39 +0000
@@ -0,0 +1,537 @@
1# The Summit Scheduler web application
2# Copyright (C) 2008 - 2013 Ubuntu Community, Canonical Ltd
3#
4# This program is free software: you can redistribute it and/or modify
5# it under the terms of the GNU Affero General Public License as
6# published by the Free Software Foundation, either version 3 of the
7# License, or (at your option) any later version.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU Affero General Public License for more details.
13#
14# You should have received a copy of the GNU Affero General Public License
15# along with this program. If not, see <http://www.gnu.org/licenses/>.
16
17
18import datetime
19import pytz
20from django import test as djangotest
21from django.contrib.auth.models import User
22from django.contrib.contenttypes.models import ContentType
23
24from model_mommy import mommy as factory
25from summit.schedule.fields import NameField
26
27from summit.schedule.models import (
28 Summit,
29 Slot,
30 Attendee,
31 Meeting,
32 Track,
33 Room,
34)
35
36from summit.schedule.render import Schedule
37
38from summit.schedule.tests.request_factory import RequestFactory
39
40# Monkey-patch our NameField into the types of fields that the factory
41# understands. This is simpler than trying to subclass the Mommy
42# class directly.
43factory.default_mapping[NameField] = str
44
45
46class ScheduleTestCase(djangotest.TestCase):
47
48 def get_request(self):
49 return RequestFactory().request()
50
51 def get_schedule_from_request(self, date=None):
52 request = self.get_request()
53 summit = factory.make_one(Summit)
54 return Schedule.from_request(request, summit, date=date)
55
56 def test_default_read_only(self):
57 schedule = self.get_schedule_from_request()
58 self.assertEqual(False, schedule.edit)
59
60 def get_user_with_schedule_permission(self):
61 user = factory.make_one(
62 User,
63 is_active=True,
64 is_staff=False,
65 is_superuser=False
66 )
67 user.user_permissions.create(
68 codename='change_agenda',
69 content_type=factory.make_one(ContentType, app_label='schedule')
70 )
71 return user
72
73 def get_get_request(self, **kwargs):
74 return RequestFactory().get('/someurl/', data=kwargs)
75
76 def get_edit_request(self, **kwargs):
77 kwargs['edit'] = True
78 return self.get_get_request(**kwargs)
79
80 def test_editable(self):
81 user = self.get_user_with_schedule_permission()
82 request = self.get_edit_request()
83 request.user = user
84 summit = factory.make_one(Summit, state='schedule')
85 attendee = factory.make_one(Attendee, summit=summit, user=user)
86 schedule = Schedule.from_request(request, summit, attendee)
87 self.assertEqual(True, schedule.edit)
88
89 def test_read_only_for_public_summit(self):
90 user = self.get_user_with_schedule_permission()
91 request = self.get_edit_request()
92 request.user = user
93 summit = factory.make_one(Summit, state='public')
94 attendee = factory.make_one(Attendee, summit=summit, user=user)
95 schedule = Schedule.from_request(request, summit, attendee)
96 self.assertEqual(False, schedule.edit)
97
98 def test_read_only_for_non_edit_request(self):
99 user = self.get_user_with_schedule_permission()
100 request = self.get_request()
101 request.user = user
102 summit = factory.make_one(Summit, state='schedule')
103 attendee = factory.make_one(Attendee, summit=summit, user=user)
104 schedule = Schedule.from_request(request, summit, attendee)
105 self.assertEqual(False, schedule.edit)
106
107 def test_read_only_for_unauthenticated_user(self):
108 request = self.get_edit_request()
109 summit = factory.make_one(Summit, state='schedule')
110 schedule = Schedule.from_request(request, summit)
111 self.assertEqual(False, schedule.edit)
112
113 def test_read_only_for_user_without_permission(self):
114 user = factory.make_one(User, is_active=True, is_superuser=False)
115 request = self.get_edit_request()
116 request.user = user
117 summit = factory.make_one(Summit, state='schedule')
118 schedule = Schedule.from_request(request, summit)
119 self.assertEqual(False, schedule.edit)
120
121 def test_default_not_personal(self):
122 schedule = self.get_schedule_from_request()
123 self.assertEqual(False, schedule.personal)
124
125 def test_personal_if_specified_in_get(self):
126 request = self.get_get_request(personal=True)
127 summit = factory.make_one(Summit)
128 schedule = Schedule.from_request(request, summit)
129 self.assertEqual(True, schedule.personal)
130
131 def test_date_set_from_date(self):
132 date = datetime.date.today()
133 schedule = self.get_schedule_from_request(date=date)
134 self.assertEqual(date, schedule.date)
135 self.assertEqual([date], schedule.dates)
136
137 def test_date_parsed_from_string(self):
138 date = datetime.date.today()
139 date_str = date.strftime("%Y-%m-%d")
140 schedule = self.get_schedule_from_request(date=date_str)
141 self.assertEqual(date, schedule.date)
142 self.assertEqual([date], schedule.dates)
143
144 def test_dates_set_from_summit_if_not_passed(self):
145 schedule = self.get_schedule_from_request()
146 self.assertEqual(None, schedule.date)
147 self.assertEqual(schedule.summit.dates(), schedule.dates)
148
149 def test_room_set_from_room(self):
150 request = self.get_request()
151 summit = factory.make_one(Summit)
152 room = factory.make_one(Room, summit=summit)
153 schedule = Schedule.from_request(request, summit, room=room)
154 self.assertEqual(room, schedule.room)
155 self.assertEqual([room], schedule.rooms)
156
157 def test_room_set_from_rooms(self):
158 request = self.get_request()
159 summit = factory.make_one(Summit)
160 rooms = factory.make_many(Room, 2, summit=summit)
161 schedule = Schedule.from_request(request, summit, room=rooms)
162 self.assertEqual(None, schedule.room)
163 self.assertEqual(rooms, schedule.rooms)
164
165 def test_room_set_from_summit_if_not_passed(self):
166 request = self.get_request()
167 summit = factory.make_one(Summit)
168 room1 = factory.make_one(
169 Room,
170 summit=summit,
171 type='open',
172 name="room1"
173 )
174 room2 = factory.make_one(
175 Room,
176 summit=summit,
177 type='open',
178 name="room2"
179 )
180 factory.make_one(Room, summit=summit, type='closed')
181 factory.make_one(Room, summit=summit, type='private')
182 schedule = Schedule.from_request(request, summit)
183 self.assertEqual(None, schedule.room)
184 self.assertEqual(
185 ["room1", "room2"],
186 sorted([r.name for r in schedule.rooms])
187 )
188
189 def test_rooms_include_private_if_user_is_staff(self):
190 user = factory.make_one(
191 User,
192 is_active=True,
193 is_staff=True,
194 is_superuser=False
195 )
196 request = self.get_request()
197 request.user = user
198 summit = factory.make_one(Summit)
199 room1 = factory.make_one(
200 Room,
201 summit=summit,
202 type='open',
203 name="room1"
204 )
205 room2 = factory.make_one(
206 Room,
207 summit=summit,
208 type='open',
209 name="room2"
210 )
211 factory.make_one(Room, summit=summit, type='closed')
212 factory.make_one(
213 Room,
214 summit=summit,
215 type='private',
216 name="privateroom"
217 )
218 schedule = Schedule.from_request(request, summit)
219 self.assertEqual(None, schedule.room)
220 self.assertEqual(
221 ["privateroom", "room1", "room2"],
222 sorted([r.name for r in schedule.rooms])
223 )
224
225 def test_rooms_include_private_if_show_private(self):
226 request = self.get_request()
227 summit = factory.make_one(Summit)
228 room1 = factory.make_one(
229 Room,
230 summit=summit,
231 type='open',
232 name="room1"
233 )
234 room2 = factory.make_one(
235 Room,
236 summit=summit,
237 type='open',
238 name="room2"
239 )
240 factory.make_one(Room, summit=summit, type='closed')
241 factory.make_one(
242 Room,
243 summit=summit,
244 type='private',
245 name="privateroom"
246 )
247 schedule = Schedule.from_request(request, summit, show_private=True)
248 self.assertEqual(None, schedule.room)
249 self.assertEqual(
250 ["privateroom", "room1", "room2"],
251 sorted([r.name for r in schedule.rooms])
252 )
253
254 def test_track_is_none_by_default(self):
255 schedule = self.get_schedule_from_request()
256 self.assertEqual(None, schedule.track)
257
258 def test_track_set_from_track(self):
259 request = self.get_request()
260 summit = factory.make_one(Summit)
261 track = factory.make_one(Track, summit=summit)
262 schedule = Schedule.from_request(request, summit, track=track)
263 self.assertEqual(track, schedule.track)
264
265 def test_nextonly_false_by_default(self):
266 schedule = self.get_schedule_from_request()
267 self.assertEqual(False, schedule.nextonly)
268
269 def test_nextonly_set_from_get_parameters(self):
270 request = self.get_get_request(next=True)
271 summit = factory.make_one(Summit)
272 schedule = Schedule.from_request(request, summit)
273 self.assertEqual(True, schedule.nextonly)
274
275 def test_fakenow_none_by_default(self):
276 schedule = self.get_schedule_from_request()
277 self.assertEqual(None, schedule.fakenow)
278
279 def test_fakenow_set_from_get_parameters(self):
280 summit = factory.make_one(Summit)
281 date = datetime.datetime(2011, 7, 8, 19, 12)
282 date = pytz.timezone(summit.timezone).localize(date)
283 request = self.get_get_request(fakenow=date.strftime("%Y-%m-%d_%H:%M"))
284 schedule = Schedule.from_request(request, summit)
285 self.assertEqual(date, schedule.fakenow)
286
287 def test_fakenow_set_to_none_if_invalid(self):
288 summit = factory.make_one(Summit)
289 request = self.get_get_request(fakenow="AAAAA")
290 schedule = Schedule.from_request(request, summit)
291 self.assertEqual(None, schedule.fakenow)
292
293 def get_schedule(
294 self,
295 edit=False,
296 room=None,
297 summit=None,
298 dates=None,
299 rooms=None
300 ):
301 request = self.get_request()
302 if summit is None:
303 summit = factory.make_one(Summit)
304 schedule = Schedule(
305 request,
306 summit,
307 edit=edit,
308 room=room,
309 dates=dates,
310 rooms=rooms
311 )
312 return schedule
313
314 def test_calculate_unscheduled_does_nothing_when_read_only(self):
315 schedule = self.get_schedule(edit=False)
316 schedule.calculate_unscheduled()
317 self.assertEqual([], schedule.unscheduled)
318
319 def test_calculate_unscheduled_includes_unscheduled(self):
320 schedule = self.get_schedule(edit=True)
321 meeting = factory.make_one(
322 Meeting,
323 summit=schedule.summit,
324 private=False,
325 approved='APPROVED'
326 )
327 schedule.calculate_unscheduled()
328 self.assertEqual([meeting], schedule.unscheduled)
329
330 def test_calculate_unscheduled_ignores_scheduled_meetings(self):
331 schedule = self.get_schedule(edit=True)
332 meeting = factory.make_one(
333 Meeting,
334 summit=schedule.summit,
335 private=False
336 )
337 room = factory.make_one(Room, summit=schedule.summit)
338 slot = factory.make_one(Slot, summit=schedule.summit)
339 meeting.agenda_set.create(room=room, slot=slot)
340 schedule.calculate_unscheduled()
341 self.assertEqual([], schedule.unscheduled)
342
343 def test_calculate_unscheduled_ignores_meetings_in_tracks_not_in_this_room(
344 self
345 ):
346 summit = factory.make_one(Summit)
347 room = factory.make_one(Room, summit=summit, type='open')
348 schedule = self.get_schedule(edit=True, room=room, summit=summit)
349 meeting = factory.make_one(
350 Meeting,
351 summit=schedule.summit,
352 type='blueprint',
353 private=False
354 )
355 track = factory.make_one(Track, summit=summit)
356 other_track = factory.make_one(Track, summit=summit)
357 room.tracks = [track]
358 meeting.tracks = [other_track]
359 schedule.calculate_unscheduled()
360 self.assertEqual([], schedule.unscheduled)
361
362 def test_calculate_unscheduled_includes_meetings_without_a_track(self):
363 summit = factory.make_one(Summit)
364 room = factory.make_one(Room, summit=summit, type='open')
365 schedule = self.get_schedule(edit=True, room=room, summit=summit)
366 meeting = factory.make_one(
367 Meeting,
368 summit=schedule.summit,
369 type='blueprint',
370 private=False,
371 approved='APPROVED'
372 )
373 track = factory.make_one(Track, summit=summit)
374 room.tracks = [track]
375 schedule.calculate_unscheduled()
376 self.assertEqual([meeting], schedule.unscheduled)
377
378 def test_calculate_unscheduled_includes_all_meetings_in_room_without_a_track(self):
379 summit = factory.make_one(Summit)
380 room = factory.make_one(Room, summit=summit, type='open')
381 schedule = self.get_schedule(edit=True, room=room, summit=summit)
382 meeting = factory.make_one(
383 Meeting,
384 summit=schedule.summit,
385 type='blueprint',
386 private=False,
387 approved='APPROVED'
388 )
389 track = factory.make_one(Track, summit=summit)
390 meeting.tracks = [track]
391 schedule.calculate_unscheduled()
392 self.assertEqual([meeting], schedule.unscheduled)
393
394 def test_calculate_unscheduled_includes_meetings_of_the_right_track(self):
395 summit = factory.make_one(Summit)
396 room = factory.make_one(Room, summit=summit, type='open')
397 schedule = self.get_schedule(edit=True, room=room, summit=summit)
398 meeting = factory.make_one(
399 Meeting,
400 summit=schedule.summit,
401 type='blueprint',
402 private=False,
403 approved='APPROVED'
404 )
405 track = factory.make_one(Track, summit=summit)
406 meeting.tracks = [track]
407 room.tracks = [track]
408 schedule.calculate_unscheduled()
409 self.assertEqual([meeting], schedule.unscheduled)
410
411 def test_calculate_unscheduled_includes_meetings_with_one_right_track(self):
412 summit = factory.make_one(Summit)
413 room = factory.make_one(Room, summit=summit, type='open')
414 schedule = self.get_schedule(edit=True, room=room, summit=summit)
415 meeting = factory.make_one(
416 Meeting,
417 summit=schedule.summit,
418 type='blueprint',
419 private=False,
420 approved='APPROVED'
421 )
422 track = factory.make_one(Track, summit=summit)
423 other_track = factory.make_one(Track, summit=summit)
424 meeting.tracks = [track, other_track]
425 room.tracks = [track]
426 schedule.calculate_unscheduled()
427 self.assertEqual([meeting], schedule.unscheduled)
428
429 def test_calculate_unscheduled_ignores_plenaries_in_the_room_view(self):
430 summit = factory.make_one(Summit)
431 room = factory.make_one(Room, summit=summit, type='open')
432 schedule = self.get_schedule(edit=True, room=room, summit=summit)
433 meeting = factory.make_one(
434 Meeting,
435 summit=schedule.summit,
436 type='plenary',
437 private=False
438 )
439 schedule.calculate_unscheduled()
440 self.assertEqual([], schedule.unscheduled)
441
442 def test_calculate_unscheduled_ignores_talks_in_the_room_view(self):
443 summit = factory.make_one(Summit)
444 room = factory.make_one(Room, summit=summit, type='open')
445 schedule = self.get_schedule(edit=True, room=room, summit=summit)
446 meeting = factory.make_one(
447 Meeting,
448 summit=schedule.summit,
449 type='talk',
450 private=False
451 )
452 schedule.calculate_unscheduled()
453 self.assertEqual([], schedule.unscheduled)
454
455 def test_calculate_unscheduled_ignores_specials_in_the_room_view(self):
456 summit = factory.make_one(Summit)
457 room = factory.make_one(Room, summit=summit, type='open')
458 schedule = self.get_schedule(edit=True, room=room, summit=summit)
459 meeting = factory.make_one(
460 Meeting,
461 summit=schedule.summit,
462 type='special',
463 private=False
464 )
465 schedule.calculate_unscheduled()
466 self.assertEqual([], schedule.unscheduled)
467
468 def test_calculate_unscheduled_shows_plenaries_in_the_plenary_room_view(
469 self
470 ):
471 summit = factory.make_one(Summit)
472 room = factory.make_one(Room, summit=summit, type='plenary')
473 schedule = self.get_schedule(edit=True, room=room, summit=summit)
474 meeting = factory.make_one(
475 Meeting,
476 summit=schedule.summit,
477 type='plenary',
478 private=False,
479 approved='APPROVED'
480 )
481 schedule.calculate_unscheduled()
482 self.assertEqual([meeting], schedule.unscheduled)
483
484 def test_calculate_unscheduled_ignores_non_plenaries_in_the_plenary_room_view(self):
485 summit = factory.make_one(Summit)
486 room = factory.make_one(Room, summit=summit, type='plenary')
487 schedule = self.get_schedule(edit=True, room=room, summit=summit)
488 meeting = factory.make_one(
489 Meeting,
490 summit=schedule.summit,
491 type='blueprint',
492 private=False
493 )
494 schedule.calculate_unscheduled()
495 self.assertEqual([], schedule.unscheduled)
496
497 def test_calculate_passes_with_multiple_plenary_rooms_if_editing(self):
498 now = datetime.datetime.utcnow()
499 one_hour = datetime.timedelta(hours=1)
500 summit = factory.make_one(
501 Summit,
502 date_start=now.date(),
503 date_end=now.date(),
504 timezone='UTC'
505 )
506 slot = factory.make_one(
507 Slot,
508 summit=summit,
509 type='plenary',
510 start_utc=now-(2*one_hour),
511 end_utc=now-(1*one_hour)
512 )
513 room1 = factory.make_one(
514 Room,
515 summit=summit,
516 type='plenary',
517 start_utc=now-(2*one_hour),
518 end_utc=now-(1*one_hour)
519 )
520 room2 = factory.make_one(
521 Room,
522 summit=summit,
523 type='plenary',
524 start_utc=now-(2*one_hour),
525 end_utc=now-(1*one_hour)
526 )
527 schedule = self.get_schedule(
528 edit=True,
529 rooms=[room1, room2],
530 summit=summit,
531 dates=[now.date()]
532 )
533 schedule.calculate()
534 # To avoid test being fragile and arbitrarily dependent on the
535 # room order, we check the returned schedule.meetings bit-by-bit.
536 self.assertEqual([slot], schedule.meetings.keys())
537 self.assertEqual(1, len(set(schedule.meetings[slot])))
0538
=== added file 'summit/schedule/tests/schedule_cache.py'
--- summit/schedule/tests/schedule_cache.py 1970-01-01 00:00:00 +0000
+++ summit/schedule/tests/schedule_cache.py 2013-02-27 15:35:39 +0000
@@ -0,0 +1,167 @@
1# The Summit Scheduler web application
2# Copyright (C) 2008 - 2013 Ubuntu Community, Canonical Ltd
3#
4# This program is free software: you can redistribute it and/or modify
5# it under the terms of the GNU Affero General Public License as
6# published by the Free Software Foundation, either version 3 of the
7# License, or (at your option) any later version.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU Affero General Public License for more details.
13#
14# You should have received a copy of the GNU Affero General Public License
15# along with this program. If not, see <http://www.gnu.org/licenses/>.
16
17
18import datetime
19from django import test as djangotest
20from django.core.urlresolvers import reverse
21from django.contrib.auth.models import User
22from django.core.cache import cache
23
24from model_mommy import mommy as factory
25from summit.schedule.fields import NameField
26
27from summit.schedule.models import (
28 Summit,
29 Slot,
30 Attendee,
31 Meeting,
32 Track,
33 Room,
34 Agenda,
35)
36
37# Monkey-patch our NameField into the types of fields that the factory
38# understands. This is simpler than trying to subclass the Mommy
39# class directly.
40factory.default_mapping[NameField] = str
41
42
43class ScheduleCacheTestCase(djangotest.TestCase):
44
45 def setUp(self):
46 now = datetime.datetime.utcnow()
47 one_hour = datetime.timedelta(0, 3600)
48 week = datetime.timedelta(days=5)
49 self.summit = factory.make_one(Summit, name='uds-test', timezone='UTC')
50 self.slot = factory.make_one(
51 Slot,
52 start_utc=now+one_hour,
53 end_utc=now+(2*one_hour),
54 type='open',
55 summit=self.summit
56 )
57
58 self.track = factory.make_one(
59 Track,
60 slug='test.track',
61 summit=self.summit
62 )
63 self.room = factory.make_one(
64 Room,
65 name='test.room',
66 title='Test Room',
67 summit=self.summit
68 )
69 self.room.tracks = [self.track]
70 self.meeting = factory.make_one(
71 Meeting,
72 summit=self.summit,
73 title='Test Meeting',
74 name='meeting',
75 private=False,
76 requires_dial_in=False
77 )
78 self.meeting.tracks = [self.track]
79 self.agenda = factory.make_one(
80 Agenda,
81 slot=self.slot,
82 meeting=self.meeting,
83 room=self.room
84 )
85
86 self.user = factory.make_one(
87 User,
88 username='testuser',
89 first_name='Test',
90 last_name='User'
91 )
92 self.attendee = factory.make_one(
93 Attendee,
94 summit=self.summit,
95 user=self.user,
96 start_utc=now,
97 end_utc=now+week
98 )
99
100 def tearDown(self):
101 # Cached requests cause render.py to return old data.
102 # Let's clear the cache
103 if hasattr(cache, 'clear'):
104 cache.clear()
105 # Older django didn't have .clear, but locmem cache did have ._cull
106 elif hasattr(cache, '_cull'):
107 cache._cull()
108
109 def request_schedule_by_date(self):
110 schedule_args = [self.summit.name, self.agenda.slot.start_utc.date()]
111 schedule_url = reverse(
112 'summit.schedule.views.by_date',
113 args=schedule_args
114 )
115 response = self.client.get(schedule_url)
116 return response
117
118 def request_schedule_by_track(self):
119 schedule_args = [self.summit.name, self.track.slug]
120 schedule_url = reverse(
121 'summit.schedule.views.by_track',
122 args=schedule_args
123 )
124 response = self.client.get(schedule_url)
125 return response
126
127 def test_cache_cleared_on_meeting_change(self):
128 self.assertEqual(None, cache.get('meeting-html-%s' % self.meeting.id))
129 response = self.request_schedule_by_date()
130 self.assertTrue(
131 'Test Meeting' in cache.get(
132 'meeting-html-%s' % self.meeting.id,
133 ''
134 )
135 )
136
137 self.meeting.save()
138
139 self.assertEqual(None, cache.get('meeting-html-%s' % self.meeting.id))
140 response = self.request_schedule_by_date()
141 self.assertTrue(
142 'Test Meeting' in cache.get(
143 'meeting-html-%s' % self.meeting.id,
144 ''
145 )
146 )
147
148 def test_cache_cleared_on_agenda_change(self):
149 self.assertEqual(None, cache.get('meeting-html-%s' % self.meeting.id))
150 response = self.request_schedule_by_date()
151 self.assertTrue(
152 'Test Meeting' in cache.get(
153 'meeting-html-%s' % self.meeting.id,
154 ''
155 )
156 )
157
158 self.agenda.save()
159
160 self.assertEqual(None, cache.get('meeting-html-%s' % self.meeting.id))
161 response = self.request_schedule_by_date()
162 self.assertTrue(
163 'Test Meeting' in cache.get(
164 'meeting-html-%s' % self.meeting.id,
165 ''
166 )
167 )
0168
=== added file 'summit/schedule/tests/scheduling_conflicts.py'
--- summit/schedule/tests/scheduling_conflicts.py 1970-01-01 00:00:00 +0000
+++ summit/schedule/tests/scheduling_conflicts.py 2013-02-27 15:35:39 +0000
@@ -0,0 +1,146 @@
1# The Summit Scheduler web application
2# Copyright (C) 2008 - 2013 Ubuntu Community, Canonical Ltd
3#
4# This program is free software: you can redistribute it and/or modify
5# it under the terms of the GNU Affero General Public License as
6# published by the Free Software Foundation, either version 3 of the
7# License, or (at your option) any later version.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU Affero General Public License for more details.
13#
14# You should have received a copy of the GNU Affero General Public License
15# along with this program. If not, see <http://www.gnu.org/licenses/>.
16
17
18import datetime
19from django import test as djangotest
20from django.contrib.auth.models import User
21
22from model_mommy import mommy as factory
23from summit.schedule.fields import NameField
24
25from summit.schedule.models import (
26 Summit,
27 Slot,
28 Attendee,
29 Meeting,
30 Room,
31 Agenda,
32 Participant,
33)
34
35
36# Monkey-patch our NameField into the types of fields that the factory
37# understands. This is simpler than trying to subclass the Mommy
38# class directly.
39factory.default_mapping[NameField] = str
40
41
42class SchedulingConflictsTestCase(djangotest.TestCase):
43
44 def setUp(self):
45 now = datetime.datetime.utcnow()
46 one_hour = datetime.timedelta(0, 3600)
47 week = datetime.timedelta(days=5)
48 self.summit = factory.make_one(Summit, name='uds-test')
49 self.slot = factory.make_one(
50 Slot,
51 start_utc=now,
52 end_utc=now+one_hour,
53 type='open',
54 summit=self.summit)
55
56 self.room1 = factory.make_one(Room, summit=self.summit)
57 self.meeting1 = factory.make_one(
58 Meeting,
59 summit=self.summit,
60 name='meeting1',
61 requires_dial_in=False
62 )
63 self.agenda1 = factory.make_one(
64 Agenda,
65 slot=self.slot,
66 meeting=self.meeting1,
67 room=self.room1
68 )
69
70 self.room2 = factory.make_one(Room, summit=self.summit)
71 self.meeting2 = factory.make_one(
72 Meeting,
73 summit=self.summit,
74 name='meeting2',
75 requires_dial_in=False
76 )
77
78 self.user = factory.make_one(
79 User,
80 username='testuser',
81 first_name='Test',
82 last_name='User'
83 )
84 self.attendee = factory.make_one(
85 Attendee,
86 summit=self.summit,
87 user=self.user,
88 start_utc=now,
89 end_utc=now+week
90 )
91
92 def tearDown(self):
93 pass
94
95 def assertRaises(self, exception_type, function, args):
96 try:
97 function(*args)
98 raise AssertionError(
99 'Callable failed to raise exception %s' % exception_type
100 )
101 except exception_type, e:
102 return True
103
104 def test_meeting_check_schedule_no_conflict(self):
105 '''Checks the Meeting model's check_schedule'''
106 missing = self.meeting1.check_schedule(self.slot, self.room1)
107 self.assertEquals(len(missing), 0)
108
109 missing = self.meeting2.check_schedule(self.slot, self.room2)
110 self.assertEquals(len(missing), 0)
111
112 def test_meeting_check_room_conflict(self):
113 '''Checks that two meetings will not be scheduled in the same room
114 at the same time
115 '''
116 missing = self.meeting1.check_schedule(self.slot, self.room1)
117 self.assertEquals(len(missing), 0)
118
119 self.assertRaises(
120 Meeting.SchedulingError,
121 Meeting.check_schedule,
122 (self.meeting2,
123 self.slot,
124 self.room1)
125 )
126
127 def test_meeting_check_schedule_participant_conflict(self):
128 '''
129 Checks that a two meetings requiring the same attendee will mark that
130 user as missing.
131 '''
132 participant1 = Participant.objects.create(
133 meeting=self.meeting1,
134 attendee=self.attendee,
135 participation='REQUIRED'
136 )
137 missing = self.meeting1.check_schedule(self.slot, self.room1)
138 self.assertEquals(len(missing), 0)
139
140 participant1 = Participant.objects.create(
141 meeting=self.meeting2,
142 attendee=self.attendee,
143 participation='REQUIRED'
144 )
145 missing = self.meeting2.check_schedule(self.slot, self.room2)
146 self.assertEquals(len(missing), 1)
0147
=== added file 'summit/schedule/tests/summit_model.py'
--- summit/schedule/tests/summit_model.py 1970-01-01 00:00:00 +0000
+++ summit/schedule/tests/summit_model.py 2013-02-27 15:35:39 +0000
@@ -0,0 +1,501 @@
1# The Summit Scheduler web application
2# Copyright (C) 2008 - 2013 Ubuntu Community, Canonical Ltd
3#
4# This program is free software: you can redistribute it and/or modify
5# it under the terms of the GNU Affero General Public License as
6# published by the Free Software Foundation, either version 3 of the
7# License, or (at your option) any later version.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU Affero General Public License for more details.
13#
14# You should have received a copy of the GNU Affero General Public License
15# along with this program. If not, see <http://www.gnu.org/licenses/>.
16
17
18import datetime
19from django import test as djangotest
20
21from model_mommy import mommy as factory
22from summit.schedule.fields import NameField
23
24from summit.schedule.models import (
25 Summit,
26 Slot,
27 Attendee,
28 Meeting,
29 Room,
30 Agenda,
31 SummitSprint,
32)
33
34from summit.common import launchpad
35
36from summit.schedule.tests.launchpad_export_node import LaunchpadExportNode
37
38# Monkey-patch our NameField into the types of fields that the factory
39# understands. This is simpler than trying to subclass the Mommy
40# class directly.
41factory.default_mapping[NameField] = str
42
43
44class SummitModelTestCase(djangotest.TestCase):
45
46 def get_basic_launchpad_response(self):
47 elem = LaunchpadExportNode()
48 elem.add_child("attendees", LaunchpadExportNode())
49 elem.add_child("unscheduled", LaunchpadExportNode())
50 return elem
51
52 def make_one_future_slot(self, summit=None):
53 if summit is None:
54 summit = factory.make_one(Summit)
55 now = datetime.datetime.utcnow()
56 one_hour = datetime.timedelta(hours=1)
57 return factory.make_one(
58 Slot,
59 summit=summit,
60 start=now+one_hour,
61 end=now+one_hour+one_hour,
62 type='open'
63 )
64
65 def test_update_meeting_skips_no_name(self):
66 summit = factory.make_one(Summit)
67 elem = LaunchpadExportNode()
68 meeting = summit.update_meeting_from_launchpad(elem)
69 self.assertEqual(None, meeting)
70 self.assertEqual(0, Meeting.objects.all().count())
71
72 def test_update_meeting_trims_name(self):
73 summit = factory.make_one(Summit)
74 elem = LaunchpadExportNode(name="very " * 20 + "longname", id="42")
75 meeting = summit.update_meeting_from_launchpad(elem)
76 # Names are truncated at 100 chars.
77 expected_name = "very " * 20
78 self.assertEqual(expected_name, meeting.name)
79 self.assertEqual(
80 1,
81 summit.meeting_set.filter(
82 name__exact=expected_name
83 ).count()
84 )
85
86 def test_update_meeting_accepts_existing_meeting(self):
87 summit = factory.make_one(Summit)
88 name = "meeting-name"
89 title = "other-title"
90 elem = LaunchpadExportNode(name=name, id="42")
91 summit.meeting_set.create(name=name, title=title)
92 meeting = summit.update_meeting_from_launchpad(elem)
93 self.assertEqual(name, meeting.name)
94 self.assertEqual(
95 1,
96 summit.meeting_set.filter(
97 name__exact=name,
98 title__exact=title
99 ).count()
100 )
101
102 def test_update_from_launchpad_response_empty(self):
103 summit = factory.make_one(Summit)
104 elem = self.get_basic_launchpad_response()
105 meetings = summit.update_from_launchpad_response(elem)
106 self.assertEqual(set(), meetings)
107 self.assertEqual(0, Meeting.objects.all().count())
108 self.assertEqual(0, Attendee.objects.all().count())
109
110 def test_update_from_launchpad_response_handles_no_name(self):
111 summit = factory.make_one(Summit)
112 elem = self.get_basic_launchpad_response()
113 meeting_node = LaunchpadExportNode(name=None, id="42")
114 elem.find("unscheduled").add_child("meeting", meeting_node)
115 meetings = summit.update_from_launchpad_response(elem)
116 self.assertEqual(set(), meetings)
117
118 def test_launchpad_sprint_import_urls_uses_default(self):
119 summit = factory.make_one(Summit, name='test-sprint')
120 self.assertEqual(
121 ['https://launchpad.net/sprints/test-sprint/+temp-meeting-export'],
122 summit.launchpad_sprint_import_urls()
123 )
124
125 def test_launchpad_sprint_import_url_uses_one_summit_sprint(self):
126 import_url = 'http://example.com/test'
127 summit = factory.make_one(Summit)
128 factory.make_one(SummitSprint, summit=summit, import_url=import_url)
129 self.assertEqual([import_url], summit.launchpad_sprint_import_urls())
130
131 def test_launchpad_sprint_import_url_uses_two_summit_sprint(self):
132 import_url1 = 'http://example.com/test1'
133 import_url2 = 'http://example.com/test2'
134 summit = factory.make_one(Summit)
135 factory.make_one(SummitSprint, summit=summit, import_url=import_url1)
136 factory.make_one(SummitSprint, summit=summit, import_url=import_url2)
137 self.assertEqual(
138 sorted(
139 [import_url1, import_url2]
140 ),
141 sorted(
142 summit.launchpad_sprint_import_urls()
143 )
144 )
145
146 def test_update_from_launchpad_gets_info_for_all_import_urls(self):
147 import_url1 = 'http://example.com/test1'
148 import_url2 = 'http://example.com/test2'
149 summit = factory.make_one(Summit)
150 factory.make_one(SummitSprint, summit=summit, import_url=import_url1)
151 factory.make_one(SummitSprint, summit=summit, import_url=import_url2)
152 called_urls = []
153
154 def get_sprint_info(url):
155 called_urls.append(url)
156 return self.get_basic_launchpad_response()
157
158 summit._get_sprint_info_from_launchpad = get_sprint_info
159 summit.update_from_launchpad()
160 self.assertEqual(
161 sorted(
162 [import_url1, import_url2]
163 ),
164 sorted(called_urls)
165 )
166
167 def test_update_from_launchpad_does_the_update(self):
168 summit = factory.make_one(Summit)
169
170 def get_sprint_info(url):
171 elem = self.get_basic_launchpad_response()
172 meeting_node = LaunchpadExportNode(name="foo", id="42")
173 elem.find("unscheduled").add_child("meeting", meeting_node)
174 return elem
175
176 summit._get_sprint_info_from_launchpad = get_sprint_info
177 summit.update_from_launchpad()
178 self.assertEqual(1, summit.meeting_set.all().count())
179
180 def test_update_from_launchpad_does_renames(self):
181 summit = factory.make_one(Summit)
182 meeting = summit.meeting_set.create(
183 name="name",
184 launchpad_blueprint_id="42"
185 )
186
187 def get_sprint_info(url):
188 elem = self.get_basic_launchpad_response()
189 meeting_node = LaunchpadExportNode(name="other", id="42")
190 elem.find("unscheduled").add_child("meeting", meeting_node)
191 return elem
192
193 summit._get_sprint_info_from_launchpad = get_sprint_info
194 summit.update_from_launchpad()
195 # Since both had blueprint id 42, it should just update
196 # the existing meeting
197 self.assertEqual(
198 0,
199 summit.meeting_set.filter(
200 name__exact="name"
201 ).count()
202 )
203 self.assertEqual(
204 1,
205 summit.meeting_set.filter(
206 name__exact="other"
207 ).count()
208 )
209
210 def test_update_from_launchpad_deletes_missing_unscheduled_meetings(self):
211 summit = factory.make_one(Summit)
212 meeting = summit.meeting_set.create(
213 spec_url='test_url',
214 name="name",
215 launchpad_blueprint_id="42"
216 )
217
218 def get_sprint_info(url):
219 elem = self.get_basic_launchpad_response()
220 meeting_node = LaunchpadExportNode(name="other")
221 elem.find("unscheduled").add_child("meeting", meeting_node)
222 return elem
223
224 summit._get_sprint_info_from_launchpad = get_sprint_info
225 summit.update_from_launchpad()
226 self.assertEqual(
227 1,
228 summit.meeting_set.filter(
229 name__exact="name"
230 ).count()
231 )
232 self.assertEqual(
233 0,
234 summit.meeting_set.filter(
235 name__exact="name"
236 ).exclude(
237 approved='REMOVED'
238 ).count()
239 )
240
241 def test_update_from_launchpad_deletes_missing_scheduled_meetings(self):
242 summit = factory.make_one(Summit)
243 meeting = summit.meeting_set.create(
244 spec_url='test_url',
245 name="name",
246 launchpad_blueprint_id="42"
247 )
248 room = factory.make_one(Room, summit=summit)
249 slot = factory.make_one(Slot)
250 agenda = meeting.agenda_set.create(room=room, slot=slot, auto=True)
251
252 def get_sprint_info(url):
253 elem = self.get_basic_launchpad_response()
254 meeting_node = LaunchpadExportNode(name="other")
255 elem.find("unscheduled").add_child("meeting", meeting_node)
256 return elem
257 summit._get_sprint_info_from_launchpad = get_sprint_info
258 summit.update_from_launchpad()
259 self.assertEqual(
260 1,
261 summit.meeting_set.filter(
262 name__exact="name"
263 ).count()
264 )
265 self.assertEqual(
266 0,
267 summit.meeting_set.filter(
268 name__exact="name"
269 ).exclude(
270 approved='REMOVED'
271 ).count()
272 )
273
274 def test_update_from_launchpad_doesnt_delete_meetings_with_spec_url(self):
275 summit = factory.make_one(Summit)
276 meeting = summit.meeting_set.create(
277 spec_url='http://example.com/foo',
278 name="name",
279 launchpad_blueprint_id="42"
280 )
281
282 def get_sprint_info(url):
283 elem = self.get_basic_launchpad_response()
284 meeting_node = LaunchpadExportNode(name="other", id="43")
285 elem.find("unscheduled").add_child("meeting", meeting_node)
286 return elem
287 summit._get_sprint_info_from_launchpad = get_sprint_info
288 summit.update_from_launchpad()
289 self.assertEqual(
290 1,
291 summit.meeting_set.filter(
292 name__exact="name"
293 ).count()
294 )
295
296 def test_update_from_launchpad_wont_delete_meetings_without_spec_url(self):
297 summit = factory.make_one(Summit)
298 meeting = summit.meeting_set.create(
299 spec_url='',
300 name="name",
301 launchpad_blueprint_id="42"
302 )
303
304 def get_sprint_info(url):
305 elem = self.get_basic_launchpad_response()
306 meeting_node = LaunchpadExportNode(name="other", id="43")
307 elem.find("unscheduled").add_child("meeting", meeting_node)
308 return elem
309
310 summit._get_sprint_info_from_launchpad = get_sprint_info
311 summit.update_from_launchpad()
312 self.assertEqual(
313 1,
314 summit.meeting_set.filter(
315 name__exact="name"
316 ).count()
317 )
318
319 def test_update_from_launchpad_updates_last_update(self):
320 old_now = datetime.datetime.utcnow() - datetime.timedelta(days=1)
321 summit = factory.make_one(Summit, last_update=old_now)
322
323 def get_sprint_info(url):
324 return self.get_basic_launchpad_response()
325
326 summit._get_sprint_info_from_launchpad = get_sprint_info
327 summit.update_from_launchpad()
328 self.assertTrue(old_now < summit.last_update)
329
330 def test_reschedule_does_nothing_on_empty_schedule(self):
331 summit = factory.make_one(Summit)
332 summit.reschedule()
333
334 def test_reschedule_removes_missing_participants(self):
335 summit = factory.make_one(Summit)
336 meeting1 = factory.make_one(
337 Meeting,
338 summit=summit,
339 requires_dial_in=False,
340 private=False
341 )
342 meeting2 = factory.make_one(
343 Meeting,
344 summit=summit,
345 requires_dial_in=False,
346 private=False
347 )
348 room1 = factory.make_one(Room, summit=summit)
349 room2 = factory.make_one(Room, summit=summit)
350 slot = self.make_one_future_slot(summit=summit)
351 attendee = factory.make_one(
352 Attendee,
353 summit=summit,
354 start_utc=slot.start_utc,
355 end_utc=slot.end_utc
356 )
357 meeting1.participant_set.create(
358 attendee=attendee,
359 participation='REQUIRED'
360 )
361 meeting2.participant_set.create(
362 attendee=attendee,
363 participation='REQUIRED'
364 )
365 factory.make_one(
366 Agenda,
367 meeting=meeting1,
368 room=room1,
369 slot=slot,
370 auto=True
371 )
372 factory.make_one(
373 Agenda,
374 meeting=meeting2,
375 room=room2,
376 slot=slot,
377 auto=True
378 )
379 summit.reschedule()
380 self.assertEqual(1, slot.agenda_set.all().count())
381
382 def test_reschedule_removes_unavailable_participants(self):
383 summit = factory.make_one(Summit)
384 meeting = factory.make_one(
385 Meeting,
386 summit=summit,
387 requires_dial_in=False,
388 private=False
389 )
390 room = factory.make_one(Room, summit=summit)
391 slot = self.make_one_future_slot(summit=summit)
392 attendee = factory.make_one(
393 Attendee,
394 summit=summit,
395 start_utc=slot.end_utc,
396 end_utc=slot.end_utc+datetime.timedelta(hours=1)
397 )
398 meeting.participant_set.create(
399 attendee=attendee,
400 participation='REQUIRED'
401 )
402 factory.make_one(
403 Agenda,
404 meeting=meeting,
405 room=room,
406 slot=slot,
407 auto=True
408 )
409 summit.reschedule()
410 self.assertEqual(0, slot.agenda_set.all().count())
411
412 def test_reschedule_removes_insufficient_slots(self):
413 summit = factory.make_one(Summit)
414 meeting = factory.make_one(
415 Meeting,
416 summit=summit,
417 slots=2,
418 requires_dial_in=False,
419 private=False
420 )
421 room = factory.make_one(Room, summit=summit)
422 slot = self.make_one_future_slot(summit=summit)
423 factory.make_one(
424 Agenda,
425 meeting=meeting,
426 room=room,
427 slot=slot,
428 auto=True
429 )
430 summit.reschedule()
431 self.assertEqual(0, slot.agenda_set.all().count())
432
433 def test_reschedule_leaves_old_slots(self):
434 summit = factory.make_one(Summit)
435 meeting = factory.make_one(
436 Meeting,
437 summit=summit,
438 slots=2,
439 requires_dial_in=False,
440 private=False
441 )
442 room = factory.make_one(Room, summit=summit)
443 now = datetime.datetime.utcnow()
444 one_hour = datetime.timedelta(hours=1)
445 slot = factory.make_one(
446 Slot,
447 summit=summit,
448 start=now-one_hour,
449 end=now,
450 type='open'
451 )
452 factory.make_one(
453 Agenda,
454 meeting=meeting,
455 room=room,
456 slot=slot,
457 auto=True
458 )
459 summit.reschedule()
460 self.assertEqual(1, slot.agenda_set.all().count())
461
462 def test_reschedule_leaves_manually_scheduled(self):
463 summit = factory.make_one(Summit)
464 meeting = factory.make_one(
465 Meeting,
466 summit=summit,
467 slots=2,
468 requires_dial_in=False,
469 private=False
470 )
471 room = factory.make_one(Room, summit=summit)
472 slot = self.make_one_future_slot(summit=summit)
473 factory.make_one(
474 Agenda,
475 meeting=meeting,
476 room=room,
477 slot=slot,
478 auto=False
479 )
480 summit.reschedule()
481 self.assertEqual(1, slot.agenda_set.all().count())
482
483 def test_update_from_launchpad_adds_attendees(self):
484 def mock_set_openid(user, force=False):
485 self.assertEquals(user.username, 'testuser')
486 mock_set_openid.called = True
487 return True
488 mock_set_openid.called = False
489 launchpad.set_user_openid = mock_set_openid
490
491 summit = factory.make_one(Summit)
492 attendee_node = LaunchpadExportNode(name='testuser')
493 summit.update_attendee_from_launchpad(attendee_node)
494
495 self.assertEqual(
496 1,
497 summit.attendee_set.filter(
498 user__username__exact="testuser"
499 ).count()
500 )
501 self.assertTrue(mock_set_openid.called)
0502
=== removed file 'summit/schedule/tests/tests.py'
--- summit/schedule/tests/tests.py 2013-02-27 03:18:38 +0000
+++ summit/schedule/tests/tests.py 1970-01-01 00:00:00 +0000
@@ -1,3417 +0,0 @@
1# The Summit Scheduler web application
2# Copyright (C) 2008 - 2013 Ubuntu Community, Canonical Ltd
3#
4# This program is free software: you can redistribute it and/or modify
5# it under the terms of the GNU Affero General Public License as
6# published by the Free Software Foundation, either version 3 of the
7# License, or (at your option) any later version.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU Affero General Public License for more details.
13#
14# You should have received a copy of the GNU Affero General Public License
15# along with this program. If not, see <http://www.gnu.org/licenses/>.
16
17
18import datetime
19import pytz
20import unittest
21from django.core.management.base import CommandError
22from django import test as djangotest
23from django.core.handlers.base import BaseHandler
24from django.core.handlers.wsgi import WSGIRequest
25from django.core.urlresolvers import reverse
26from django.conf import settings
27from django.contrib.auth.models import User, Permission
28from django.contrib.contenttypes.models import ContentType
29from django.db import models
30from django.core.cache import cache
31
32from summit.schedule.management.commands import reschedule
33
34from model_mommy import mommy as factory
35from summit.schedule.fields import NameField
36
37from summit.schedule.models import (
38 Summit,
39 Slot,
40 Attendee,
41 Meeting,
42 Track,
43 Room,
44 Agenda,
45 Participant,
46 SummitSprint,
47 Lead,
48)
49
50from summit.schedule.render import Schedule
51from summit.common import launchpad
52
53# Monkey-patch our NameField into the types of fields that the factory
54# understands. This is simpler than trying to subclass the Mommy
55# class directly.
56factory.default_mapping[NameField] = str
57
58site_root = getattr(settings, 'SITE_ROOT', 'http://summit.ubuntu.com')
59theme_media = getattr(settings, 'THEME_MEDIA', 'ubuntu_website.MEDIA_ROOT')
60
61
62class RequestFactory(djangotest.Client):
63 """
64 Class that lets you create mock Request objects for use in testing.
65
66 Usage:
67
68 rf = RequestFactory()
69 get_request = rf.get('/hello/')
70 post_request = rf.post('/submit/', {'foo': 'bar'})
71
72 This class re-uses the django.test.client.Client interface, docs here:
73 http://www.djangoproject.com/documentation/testing/#the-test-client
74
75 Once you have a request object you can pass it to any view function,
76 just as if that view had been hooked up using a URLconf.
77
78 """
79 def request(self, **request):
80 """
81 Similar to parent class, but returns the request object as soon as it
82 has created it.
83 """
84 environ = {
85 'HTTP_COOKIE': self.cookies,
86 'PATH_INFO': '/',
87 'QUERY_STRING': '',
88 'REQUEST_METHOD': 'GET',
89 'SCRIPT_NAME': '',
90 'SERVER_NAME': 'testserver',
91 'SERVER_PORT': 80,
92 'SERVER_PROTOCOL': 'HTTP/1.1',
93 'wsgi.input': '',
94 }
95 environ.update(self.defaults)
96 environ.update(request)
97 request = WSGIRequest(environ)
98 handler = BaseHandler()
99 handler.load_middleware()
100 for middleware_method in handler._request_middleware:
101 if middleware_method(request):
102 raise Exception(
103 "Couldn't create request mock object - "
104 "request middleware %s returned a response"
105 % middleware_method
106 )
107 return request
108
109
110class RescheduleCommandTestCase(unittest.TestCase):
111 """Tests for the 'reschedule' management command."""
112
113 def test_passing_nonexistant_summit_raises_error(self):
114 cmd = reschedule.Command()
115 self.assertRaises(CommandError, cmd.handle, summit='uds-xxx')
116
117
118class MeetingModelTestCase(djangotest.TestCase):
119 """Tests for the Meeting model."""
120
121 def test_meetings_can_not_be_scheduled_in_closed_slots(self):
122 now = datetime.datetime.utcnow()
123 one_hour = datetime.timedelta(0, 3600)
124 slot = factory.make_one(
125 Slot,
126 start_utc=now,
127 end_utc=now+one_hour,
128 type='closed')
129
130 agenda = factory.make_one(Agenda, slot=slot)
131 meeting = factory.make_one(
132 Meeting,
133 requires_dial_in=False,
134 private=False
135 )
136
137 # XXX check_schedule should only be checking the schedule, not
138 # checking and modifying the schedule.
139 # XXX check_schedule's parameters should be an just an agenda object,
140 # not the agenda object's attributes.
141 self.assertRaises(
142 Meeting.SchedulingError,
143 meeting.check_schedule, agenda.slot, agenda.room)
144
145 def test_participants_are_in_another_meeting(self):
146 now = datetime.datetime.utcnow()
147 one_hour = datetime.timedelta(0, 3600)
148 slot = factory.make_one(
149 Slot,
150 start_utc=now,
151 end_utc=now+one_hour)
152 room1 = factory.make_one(Room)
153 room2 = factory.make_one(Room)
154
155 meeting1 = factory.make_one(
156 Meeting,
157 summit=slot.summit,
158 requires_dial_in=False,
159 private=False
160 )
161 meeting2 = factory.make_one(
162 Meeting,
163 summit=slot.summit,
164 requires_dial_in=False,
165 private=False
166 )
167
168 attendee = factory.make_one(Attendee)
169 factory.make_one(
170 Participant,
171 meeting=meeting1,
172 attendee=attendee,
173 participation='REQUIRED'
174 )
175 factory.make_one(
176 Participant,
177 meeting=meeting2,
178 attendee=attendee,
179 participation='REQUIRED'
180 )
181
182 factory.make_one(Agenda, meeting=meeting1, slot=slot, room=room1)
183 agenda = factory.make_one(
184 Agenda,
185 meeting=meeting2,
186 slot=slot,
187 room=room2
188 )
189
190 missing = meeting2.check_schedule(agenda.slot, agenda.room)
191 self.assertEqual([attendee.name], [a.name for a in missing])
192
193 def make_open_slot(self):
194 now = datetime.datetime.utcnow()
195 one_hour = datetime.timedelta(0, 3600)
196 slot = factory.make_one(
197 Slot,
198 start_utc=now+one_hour,
199 end_utc=now+one_hour+one_hour,
200 type='open')
201 return slot
202
203 def test_check_schedule_errors_on_no_dial_in(self):
204 slot = self.make_open_slot()
205 room = factory.make_one(
206 Room,
207 has_dial_in=False,
208 summit=slot.summit,
209 name="testroom"
210 )
211 meeting = factory.make_one(
212 Meeting,
213 requires_dial_in=True,
214 summit=slot.summit,
215 name="testmeeting",
216 private=False
217 )
218 try:
219 meeting.check_schedule(slot, room)
220 except meeting.SchedulingError, e:
221 self.assertEqual("Room has no dial-in capability", e.message)
222 return
223 self.fail("SchedulingError not thrown")
224
225 def make_two_adjacent_slots(self):
226 summit = factory.make_one(Summit, timezone='utc')
227 now = datetime.datetime(2011, 9, 8, 12, 00)
228 one_hour = datetime.timedelta(0, 3600)
229 slot1 = factory.make_one(
230 Slot,
231 start_utc=now+one_hour,
232 end_utc=now+one_hour+one_hour,
233 type='open', summit=summit
234 )
235 slot2 = factory.make_one(
236 Slot,
237 start_utc=now+one_hour+one_hour,
238 end_utc=now+one_hour+one_hour+one_hour,
239 type='open', summit=summit
240 )
241 return slot1, slot2
242
243 def test_check_schedule_errors_on_same_track_in_previous_slot(self):
244 slot1, slot2 = self.make_two_adjacent_slots()
245 room = factory.make_one(
246 Room,
247 summit=slot1.summit,
248 name="testroom"
249 )
250 track = factory.make_one(
251 Track,
252 summit=slot1.summit,
253 title="testtrack",
254 allow_adjacent_sessions=False
255 )
256 track2 = factory.make_one(
257 Track,
258 summit=slot1.summit,
259 title="adjacenttrack",
260 allow_adjacent_sessions=True
261 )
262 meeting1 = factory.make_one(
263 Meeting,
264 requires_dial_in=False,
265 summit=slot1.summit,
266 name="testmeeting1",
267 type='blueprint',
268 private=False
269 )
270 meeting2 = factory.make_one(
271 Meeting,
272 requires_dial_in=False,
273 summit=slot1.summit,
274 name="testmeeting2",
275 type='blueprint',
276 private=False
277 )
278 meeting1.tracks = [track, track2]
279 meeting2.tracks = [track]
280 meeting1.agenda_set.create(room=room, slot=slot1)
281 try:
282 meeting2.check_schedule(slot2, room)
283 except meeting2.SchedulingError, e:
284 self.assertEqual("Same track in the previous slot", e.message)
285 return
286 self.fail("SchedulingError not thrown")
287
288 def test_check_schedule_errors_on_same_track_in_next_slot(self):
289 slot1, slot2 = self.make_two_adjacent_slots()
290 room = factory.make_one(Room, summit=slot1.summit, name="testroom")
291 track = factory.make_one(
292 Track,
293 summit=slot1.summit,
294 title="testtrack",
295 allow_adjacent_sessions=False
296 )
297 meeting1 = factory.make_one(
298 Meeting,
299 requires_dial_in=False,
300 summit=slot1.summit,
301 name="testmeeting1",
302 type='blueprint',
303 private=False
304 )
305 meeting2 = factory.make_one(
306 Meeting,
307 requires_dial_in=False,
308 summit=slot1.summit,
309 name="testmeeting2",
310 type='blueprint',
311 private=False
312 )
313 meeting1.tracks = [track]
314 meeting2.tracks = [track]
315 meeting1.agenda_set.create(room=room, slot=slot2)
316 try:
317 meeting2.check_schedule(slot1, room)
318 except meeting2.SchedulingError, e:
319 self.assertEqual("Same track in the next slot", e.message)
320 return
321 self.fail("SchedulingError not thrown")
322
323 def test_check_schedule_no_error_on_different_track(self):
324 slot1, slot2 = self.make_two_adjacent_slots()
325 room = factory.make_one(Room, summit=slot1.summit, name="testroom")
326 track = factory.make_one(
327 Track,
328 summit=slot1.summit,
329 title="testtrack",
330 allow_adjacent_sessions=False
331 )
332 other_track = factory.make_one(
333 Track,
334 summit=slot1.summit,
335 title="othertesttrack",
336 allow_adjacent_sessions=False
337 )
338 meeting1 = factory.make_one(
339 Meeting,
340 requires_dial_in=False,
341 summit=slot1.summit,
342 name="testmeeting1",
343 type='blueprint',
344 private=False
345 )
346 meeting2 = factory.make_one(
347 Meeting,
348 requires_dial_in=False,
349 summit=slot1.summit,
350 name="testmeeting2",
351 type='blueprint',
352 private=False
353 )
354 meeting1.tracks = [track]
355 meeting2.tracks = [other_track]
356 meeting1.agenda_set.create(room=room, slot=slot2)
357 meeting2.check_schedule(slot1, room)
358
359 def test_check_schedule_no_error_on_same_track_for_plenaries(self):
360 slot1, slot2 = self.make_two_adjacent_slots()
361 room = factory.make_one(Room, summit=slot1.summit, name="testroom")
362 track = factory.make_one(
363 Track,
364 summit=slot1.summit,
365 title="testtrack",
366 allow_adjacent_sessions=False
367 )
368 meeting1 = factory.make_one(
369 Meeting,
370 requires_dial_in=False,
371 summit=slot1.summit,
372 name="testmeeting1",
373 type='blueprint',
374 private=False
375 )
376 meeting2 = factory.make_one(
377 Meeting,
378 requires_dial_in=False,
379 summit=slot1.summit,
380 name="testmeeting2",
381 type='plenary',
382 private=False
383 )
384 meeting1.tracks = [track]
385 meeting2.tracks = [track]
386 meeting1.agenda_set.create(room=room, slot=slot2)
387 meeting2.check_schedule(slot1, room)
388
389 def test_check_schedule_no_error_on_same_track_for_ajdacent_sessions_allowed(self):
390 slot1, slot2 = self.make_two_adjacent_slots()
391 room = factory.make_one(Room, summit=slot1.summit, name="testroom")
392 track = factory.make_one(
393 Track,
394 summit=slot1.summit,
395 title="adjacenttrack",
396 allow_adjacent_sessions=True
397 )
398 meeting1 = factory.make_one(
399 Meeting,
400 requires_dial_in=False,
401 summit=slot1.summit,
402 name="testmeeting1",
403 type='blueprint',
404 private=False
405 )
406 meeting2 = factory.make_one(
407 Meeting,
408 requires_dial_in=False,
409 summit=slot1.summit,
410 name="testmeeting2",
411 type='blueprint',
412 private=False
413 )
414 meeting1.tracks = [track]
415 meeting2.tracks = [track]
416 meeting1.agenda_set.create(room=room, slot=slot2)
417 meeting2.check_schedule(slot1, room)
418
419 def test_try_schedule_into_refuses_room_without_dial_in(self):
420 slot = self.make_open_slot()
421 room = factory.make_one(
422 Room,
423 has_dial_in=False,
424 summit=slot.summit,
425 name="testroom"
426 )
427 meeting = factory.make_one(
428 Meeting,
429 requires_dial_in=True,
430 summit=slot.summit,
431 name="testmeeting",
432 private=False
433 )
434
435 self.assertEqual(False, meeting.try_schedule_into([room]))
436 self.assertEqual(0, meeting.agenda_set.all().count())
437
438 def test_try_schedule_into_allows_room_with_dial_in(self):
439 slot = self.make_open_slot()
440 room = factory.make_one(
441 Room,
442 has_dial_in=True,
443 summit=slot.summit,
444 name="testroom"
445 )
446 meeting = factory.make_one(
447 Meeting,
448 requires_dial_in=True,
449 summit=slot.summit,
450 name="testmeeting",
451 private=False
452 )
453
454 self.assertEqual(True, meeting.try_schedule_into([room]))
455 self.assertEqual(1, meeting.agenda_set.all().count())
456
457 def test_link_to_pad_with_pad_url_set(self):
458 url = 'http://pad.com/url'
459 meeting = factory.make_one(Meeting, pad_url=url, private=False)
460 self.assertEqual(url, meeting.link_to_pad)
461
462 def get_pad_host(self):
463 summit_name = 'testsummit'
464 summit = factory.make_one(Summit, name=summit_name)
465 return getattr(summit, 'etherpad', 'http://pad.ubuntu.com/')
466
467 def test_link_to_pad_with_pad_url_unset(self):
468 summit_name = 'testsummit'
469 summit = factory.make_one(Summit, name=summit_name)
470 name = 'testmeeting'
471 meeting = factory.make_one(
472 Meeting,
473 pad_url=None,
474 name=name,
475 summit=summit,
476 private=False
477 )
478 pad_host = self.get_pad_host()
479 url = pad_host + summit_name + '-' + name
480 self.assertEqual(url, meeting.link_to_pad)
481
482 def test_link_to_pad_with_plus_in_meeting_name(self):
483 summit_name = 'testsummit'
484 summit = factory.make_one(Summit, name=summit_name)
485 name = 'test+meeting'
486 meeting = factory.make_one(
487 Meeting,
488 pad_url=None,
489 name=name,
490 summit=summit,
491 private=False
492 )
493 pad_host = self.get_pad_host()
494 url = pad_host + summit_name + '-' + name.replace("+", "-")
495 self.assertEqual(url, meeting.link_to_pad)
496
497 def test_edit_link_to_pad_with_pad_url_set(self):
498 url = 'http://pad.com/url'
499 meeting = factory.make_one(Meeting, pad_url=url, private=False)
500 self.assertEqual(url, meeting.edit_link_to_pad)
501
502 def test_edit_link_to_pad_with_pad_url_unset(self):
503 summit_name = 'testsummit'
504 summit = factory.make_one(Summit, name=summit_name)
505 name = 'testmeeting'
506 meeting = factory.make_one(
507 Meeting,
508 pad_url=None,
509 name=name,
510 summit=summit,
511 private=False
512 )
513 pad_host = self.get_pad_host()
514 url = pad_host + "ep/pad/view/" + summit_name + '-' + name + "/latest"
515 self.assertEqual(url, meeting.edit_link_to_pad)
516
517 def test_edit_link_to_pad_with_plus_in_meeting_name(self):
518 summit_name = 'testsummit'
519 summit = factory.make_one(Summit, name=summit_name)
520 name = 'test+meeting'
521 meeting = factory.make_one(
522 Meeting,
523 pad_url=None,
524 name=name,
525 summit=summit,
526 private=False
527 )
528 pad_host = self.get_pad_host()
529 url = (
530 pad_host
531 + "ep/pad/view/"
532 + summit_name
533 + '-'
534 + name.replace("+", "-")
535 + "/latest"
536 )
537 self.assertEqual(url, meeting.edit_link_to_pad)
538
539 def test_update_from_launchpad_sets_status(self):
540 summit = factory.make_one(Summit, timezone='utc', name='test-summit')
541 meeting = factory.make_one(
542 Meeting,
543 pad_url=None,
544 name='test-meeting',
545 summit=summit,
546 private=False
547 )
548 status = "Discussion"
549 name = meeting.name
550 elem = LaunchpadExportNode(status=status, name=name)
551 meeting.update_from_launchpad(elem)
552 self.assertEqual(status, meeting.status)
553
554 def test_update_from_launchpad_sets_priority(self):
555 summit = factory.make_one(Summit, timezone='utc', name='test-summit')
556 meeting = factory.make_one(
557 Meeting,
558 pad_url=None,
559 name='test-meeting',
560 summit=summit,
561 private=False
562 )
563 priority = 70
564 name = meeting.name
565 elem = LaunchpadExportNode(priority=priority, name=name)
566 meeting.update_from_launchpad(elem)
567 self.assertEqual(priority, meeting.priority)
568
569 def test_update_from_launchpad_sets_wiki_url(self):
570 summit = factory.make_one(Summit, timezone='utc', name='test-summit')
571 meeting = factory.make_one(
572 Meeting,
573 pad_url=None,
574 name='test-meeting',
575 summit=summit,
576 private=False
577 )
578 wiki_url = "http://example.com/somespec"
579 name = meeting.name
580 elem = LaunchpadExportNode(specurl=wiki_url, name=name)
581 meeting.update_from_launchpad(elem)
582 self.assertEqual(wiki_url, meeting.wiki_url)
583
584 def get_person_node(self, username, required=False):
585 elem = LaunchpadExportNode()
586 required_map = {True: "True", False: "False"}
587 elem.add_child(
588 "person",
589 LaunchpadExportNode(
590 name=username,
591 required=required_map[required]
592 )
593 )
594 return elem
595
596 def make_one_future_slot(self, summit=None):
597 if summit is None:
598 summit = factory.make_one(Summit)
599 now = datetime.datetime.utcnow()
600 one_hour = datetime.timedelta(hours=1)
601 return factory.make_one(
602 Slot,
603 summit=summit,
604 start=now+one_hour,
605 end=now+one_hour+one_hour,
606 type='open'
607 )
608
609 def make_summit_and_attendee(self):
610 username = "username"
611 user = factory.make_one(User, username=username)
612 summit = factory.make_one(Summit)
613 slot = self.make_one_future_slot(summit=summit)
614 attendee = summit.attendee_set.create(
615 user=user,
616 start_utc=slot.start_utc,
617 end_utc=slot.end_utc
618 )
619 return summit, attendee
620
621 def test_update_from_launchpad_adds_participant(self):
622 summit, attendee = self.make_summit_and_attendee()
623 meeting = factory.make_one(
624 Meeting,
625 pad_url=None,
626 name='test-meeting',
627 summit=summit,
628 private=False
629 )
630 name = meeting.name
631 elem = self.get_person_node(
632 attendee.user.username,
633 required=False,
634 )
635 meeting.update_from_launchpad(elem)
636 participant = meeting.participant_set.get()
637 self.assertEqual(attendee, participant.attendee)
638 self.assertEqual('ATTENDING', participant.participation)
639
640 def test_update_from_launchpad_sets_participant_essential(self):
641 summit, attendee = self.make_summit_and_attendee()
642 meeting = factory.make_one(
643 Meeting,
644 pad_url=None,
645 name='test-meeting',
646 summit=summit,
647 private=False
648 )
649 name = meeting.name
650 elem = self.get_person_node(
651 attendee.user.username,
652 required=True,
653 )
654 meeting.update_from_launchpad(elem)
655 participant = meeting.participant_set.get()
656 self.assertEqual('INTERESTED', participant.participation)
657
658 def test_update_from_launchpad_sets_from_launchpad(self):
659 summit, attendee = self.make_summit_and_attendee()
660 meeting = summit.meeting_set.create()
661 elem = self.get_person_node(attendee.user.username)
662 meeting.update_from_launchpad(elem)
663 participant = meeting.participant_set.get()
664 self.assertEqual(True, participant.from_launchpad)
665
666 def test_update_from_launchpad_removes_from_launchpad_unsubscribed(self):
667 summit, attendee = self.make_summit_and_attendee()
668 meeting = summit.meeting_set.create()
669 elem = self.get_person_node(attendee.user.username)
670 otheruser = factory.make_one(User, username="otheruser")
671 otherattendee = summit.attendee_set.create(user=otheruser)
672 meeting.participant_set.create(
673 attendee=otherattendee,
674 from_launchpad=True
675 )
676 meeting.update_from_launchpad(elem)
677 usernames = [
678 p.attendee.user.username for p in meeting.participant_set.all()
679 ]
680 self.assertEqual(["username"], usernames)
681
682
683class ICalTestCase(djangotest.TestCase):
684
685 def test_ical_meeting_without_name(self):
686 """ Tests that ical doesn't break for nameless meetings"""
687 now = datetime.datetime.utcnow()
688 one_hour = datetime.timedelta(0, 3600)
689 summit = factory.make_one(Summit, name='uds-test')
690 summit.save()
691 slot = factory.make_one(
692 Slot,
693 start_utc=now,
694 end_utc=now+one_hour,
695 type='open',
696 summit=summit
697 )
698 slot.save()
699
700 room = factory.make_one(Room, summit=summit)
701 meeting = factory.make_one(
702 Meeting,
703 summit=summit,
704 name='',
705 private=False
706 )
707 meeting.name = ''
708 models.Model.save(meeting)
709 agenda = factory.make_one(
710 Agenda,
711 slot=slot,
712 meeting=meeting,
713 room=room
714 )
715
716 self.assertEquals(
717 meeting.meeting_page_url,
718 '/uds-test/meeting/%s/-/' % meeting.id
719 )
720
721 response = self.client.get('/uds-test.ical')
722 self.assertEquals(response.status_code, 200)
723 self.assertContains(
724 response,
725 'URL:%s/uds-test/meeting/%s/-/\n' % (site_root, meeting.id),
726 1
727 )
728
729 def test_ical_meeting_name_with_period(self):
730 """ Tests that ical doesn't break for nameless meetings"""
731 now = datetime.datetime.utcnow()
732 one_hour = datetime.timedelta(0, 3600)
733 summit = factory.make_one(Summit, name='uds-test')
734 summit.save()
735 slot = factory.make_one(
736 Slot,
737 start_utc=now,
738 end_utc=now+one_hour,
739 type='open',
740 summit=summit
741 )
742 slot.save()
743
744 room = factory.make_one(Room, summit=summit)
745 meeting = factory.make_one(
746 Meeting,
747 summit=summit,
748 name='test.name',
749 private=False
750 )
751 agenda = factory.make_one(
752 Agenda,
753 slot=slot,
754 meeting=meeting,
755 room=room
756 )
757
758 self.assertEquals(
759 meeting.meeting_page_url,
760 '/uds-test/meeting/%s/test.name/' % meeting.id
761 )
762
763 response = self.client.get('/uds-test.ical')
764 self.assertEquals(response.status_code, 200)
765 self.assertContains(
766 response,
767 'URL:%s/uds-test/meeting/%s/test.name/' % (site_root, meeting.id),
768 1
769 )
770
771 def test_ical_meeting_multiline_description(self):
772 """ Tests that ical put spaces before multi-line descriptions"""
773 now = datetime.datetime.utcnow()
774 one_hour = datetime.timedelta(0, 3600)
775 summit = factory.make_one(Summit, name='uds-test')
776 summit.save()
777 slot = factory.make_one(
778 Slot,
779 start_utc=now,
780 end_utc=now+one_hour,
781 type='open',
782 summit=summit
783 )
784 slot.save()
785
786 room = factory.make_one(Room, summit=summit)
787 meeting = factory.make_one(
788 Meeting,
789 summit=summit,
790 name='test.name',
791 description="Test\r\nDescription",
792 private=False
793 )
794 agenda = factory.make_one(
795 Agenda,
796 slot=slot,
797 meeting=meeting,
798 room=room
799 )
800
801 self.assertEquals(
802 meeting.meeting_page_url,
803 '/uds-test/meeting/%s/test.name/' % meeting.id
804 )
805
806 response = self.client.get('/uds-test.ical')
807 self.assertEquals(response.status_code, 200)
808 self.assertContains(response, 'DESCRIPTION:Test\NDescription', 1)
809
810 def test_private_ical(self):
811 """ Tests that private icals contain private meetings """
812 now = datetime.datetime.utcnow()
813 one_hour = datetime.timedelta(0, 3600)
814 week = datetime.timedelta(days=7)
815 summit = factory.make_one(Summit, name='uds-test')
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches