2 # -*- coding: utf-8 -*-
4 # Copyright (c) 2010-2012 Cidadania S. Coop. Galega
6 # This file is part of e-cidadania.
8 # e-cidadania is free software: you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation, either version 3 of the License, or
11 # (at your option) any later version.
13 # e-cidadania is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU General Public License for more details.
18 # You should have received a copy of the GNU General Public License
19 # along with e-cidadania. If not, see <http://www.gnu.org/licenses/>.
23 from django
.contrib
.auth
.models
import User
24 from django
.core
.urlresolvers
import reverse
26 from django
.test
import Client
27 from django
.test
import TestCase
29 from django
.utils
.encoding
import smart_str
31 from core
.spaces
.models
import Space
33 from apps
.ecidadania
.debate
.models
import Debate
34 from apps
.ecidadania
.debate
.models
import Column
35 from apps
.ecidadania
.debate
.models
import Row
36 from apps
.ecidadania
.debate
.models
import Note
37 from apps
.ecidadania
.news
.models
import Post
38 from apps
.ecidadania
.proposals
.models
import ProposalSet
40 from tests
.data_seeder
import seeder
43 class ECDTestCase(TestCase
):
44 """Class which extends Django TestCase and adds methods specific to
45 e-cidadania for testing.
49 """Performs set up for the tests.
51 self
.client
= Client(enforce_csrf_checks
=False)
52 self
.username
= 'dummy_username'
53 self
.user_password
= 'dummy_user_password'
54 self
.admin_username
= 'admin_username'
55 self
.admin_password
= 'admin_password'
56 self
.foo_user
= self
.create_user('foo_user', 'foo_user_password')
57 self
.foo_admin
= self
.create_user('foo_admin', 'foo_admin_password')
58 self
.foo_mod
= self
.create_user('foo_mod', 'foo_mod_password')
60 self
.bar_user
= self
.create_user('bar_user', 'bar_user_password')
61 self
.bar_admin
= self
.create_user('bar_admin', 'bar_admin_password')
62 self
.bar_mod
= self
.create_user('bar_mod', 'bar_mod_password')
64 space_properties
= {'name': 'foo_space', 'url': 'foo_space_url',
65 'author': self
.foo_admin
, 'public': False,
66 'mod_debate': True, 'mod_proposals': True,
67 'mod_news': True, 'mod_cal': True, 'mod_docs': True,
69 self
.foo_space
= Space(**space_properties
)
71 self
.foo_space
.admins
.add(self
.foo_admin
)
72 self
.foo_space
.mods
.add(self
.foo_mod
)
73 self
.foo_space
.users
.add(self
.foo_user
)
76 space_properties
.update({'author': self
.bar_admin
, 'name': 'bar_space',
77 'url': 'bar_space_url', 'public': True,})
78 self
.bar_space
= Space(**space_properties
)
80 self
.bar_space
.admins
.add(self
.bar_admin
)
81 self
.bar_space
.mods
.add(self
.bar_mod
)
82 self
.bar_space
.users
.add(self
.bar_user
)
85 debate_properties
= {'space': self
.foo_space
, 'author': self
.foo_admin
}
86 self
.foo_debate
= self
.seed(Debate
,properties
=debate_properties
)
88 debate_properties
.update({'space': self
.bar_space
,
89 'author': self
.bar_admin
})
90 self
.bar_debate
= self
.seed(Debate
,debate_properties
)
92 column_properties
= {'debate': self
.foo_debate
, 'criteria': 'private'}
93 self
.foo_column
= Column(**column_properties
)
94 self
.foo_column
.save()
96 column_properties
.update({'debate': self
.bar_debate
,
97 'criteria': 'public'})
98 self
.bar_column
= Column(**column_properties
)
99 self
.bar_column
.save()
101 row_properties
= column_properties
.copy()
102 self
.bar_row
= Row(**row_properties
)
105 row_properties
.update({'debate': self
.foo_debate
})
106 self
.foo_row
= Row(**row_properties
)
109 note_properties
= {'column': self
.foo_column
, 'row': self
.foo_row
,
110 'debate': self
.foo_debate
, 'author': self
.foo_admin
}
111 self
.foo_note
= Note(**note_properties
)
114 note_properties
.update({'column': self
.bar_column
,
116 'debate': self
.bar_debate
,
117 'author': self
.bar_admin
})
118 self
.bar_note
= Note(**note_properties
)
121 post_properties
= {'title': 'Foo news post', 'author': self
.foo_user
,
122 'pub_index': True, 'space': self
.foo_space
}
123 self
.foo_post
= Post(**post_properties
)
126 post_properties
.update({'title': 'Bar news post',
127 'author': self
.bar_user
, 'space': self
.bar_space
})
128 self
.bar_post
= Post(**post_properties
)
131 proposal_set_properties
= {'name': 'Foo Proposal Set',
132 'space': self
.foo_space
,
133 'author': self
.foo_admin
,
134 'debate': self
.foo_debate
}
135 self
.foo_proposalset
= ProposalSet(**proposal_set_properties
)
136 self
.foo_proposalset
.save()
138 proposal_set_properties
.update({'name': 'Bar Proposal Set',
139 'space': self
.bar_space
,
140 'author': self
.bar_admin
,
141 'debate': self
.bar_debate
})
142 self
.bar_proposalset
= ProposalSet(**proposal_set_properties
)
143 self
.bar_proposalset
.save()
145 def seed(self
, model
, properties
=None, constraints
=None, follow_fk
=None,
146 generate_fk
=None, follow_m2m
=None, factory
=None, commit
=True):
147 """Generates and returns a new instance of the `model` with
148 properties in `properties`.
150 instance
= seeder
.seed(model
=model
, constraints
=constraints
,
151 follow_fk
=follow_fk
, generate_fk
=None,
152 follow_m2m
=None, factory
=None,
153 model_properties
=properties
, commit
=commit
)
157 def seedn(self
, count
, model
, properties
, constraints
=None, follow_fk
=None,
158 generate_fk
=None, follow_m2m
=None, factory
=None, commit
=True):
159 """Generates and returns `count` number of instances of `model` with
160 properties in `properties`.
163 obj_list
= seeder
.seedn(count
=count
, model
=model
, constraints
=constraints
,
164 follow_fk
=follow_fk
, generate_fk
=generate_fk
,
165 follow_m2m
=follow_m2m
, factory
=factory
,
166 model_properties
=properties
, commit
=True)
169 def create_user(self
, username
, password
, email
=None, properties
=None,
171 """Creates, saves and returns a user with a given username, password
172 and email. If `properties` is supplied, it will be applied to the
176 user
= User
.objects
.create_user(username
=username
, password
=password
,
179 for key
in properties
:
180 setattr(user
, key
, properties
[key
])
184 # log out the current user
186 # log in the new user
187 user
= self
.login(username
=username
, password
=password
, email
=email
)
190 def create_super_user(self
, username
='admin', password
='admin_pass',
191 email
='admin@test.com', properties
=None,
193 """Creates, saves and returns a super user with a given username,
194 password and email. If `properties` is supplied, it will be applied
198 super_user
= User
.objects
.create_superuser(username
=username
,
202 for key
in properties
:
203 setattr(super_user
, key
, properties
[key
])
208 super_user
= self
.login(username
=username
, password
=password
,
212 def login(self
, username
, password
, email
=None):
213 """Logs in a user with the given username and password. If the user is
214 not present in the database, it will be created and logged in.
216 We assume `username` is unique across the database.
220 user
= User
.objects
.get(username
=username
)
224 user
= self
.create_user(username
=username
, password
=password
,
227 self
.client
.login(username
=username
, password
=password
)
232 """Logs out the currently logged in user.
237 def isLoggedIn(self
, user
=None):
238 """Checks and returns True if a user is logged in otherwise returns
242 if '_auth_user_id' not in self
.client
.session
:
245 if (user
.pk
== self
.client
.session
['_auth_user_id']):
250 def getURL(self
, name
, args
=None, kwargs
=None):
251 """Returns the url for the given `name` which may be a function name or
254 return reverse(name
, args
=args
, kwargs
=kwargs
)
256 def get(self
, url
=None, url_name
=None, data
={}, follow
=False, **extra
):
258 Performs a get to the given url and returns the response.
260 if url
is None and url_name
is None:
261 raise Exception("Please pass either url or url name")
264 url
= self
.getURL(url_name
)
266 response
= self
.client
.get(url
, data
=data
, follow
=follow
, extra
=extra
)
269 def post(self
, url
, data
={}, follow
=False, **extra
):
271 Performs a post to the supplied url and returns the response.
274 response
= self
.client
.post(path
=url
, data
=data
, follow
=follow
,
278 def printResponse(self
, response
):
279 """Prints the response to the terminal.
280 We need this method because the response is a unicode string and
281 results in exception when printed directly i.e print response.
284 print smart_str(response
)
287 def assertResponseCode(self
, response
, status_code
):
288 """Asserts that the response status is status_code.
290 if response
.status_code
!= status_code
:
295 httplib
.FORBIDDEN
, httplib
.BAD_REQUEST
, httplib
.NOT_FOUND
,
297 url_codes
= [httplib
.NOT_FOUND
]
299 if response
.status_code
in verbose_codes
:
302 if response
.context
and response
.status_code
in message_codes
:
304 print response
.context
['message']
308 if response
.status_code
in url_codes
:
309 print response
.request
['PATH_INFO']
311 self
.assertEqual(status_code
, response
.status_code
)
313 def assertResponseOK(self
, response
):
314 """Asserts that the response status is OK.
316 self
.assertResponseCode(response
, httplib
.OK
)
318 def assertResponseRedirect(self
, response
):
319 """Asserts that the response status is FOUND.
321 self
.assertResponseCode(response
, httplib
.FOUND
)
323 def assertResponseForbidden(self
, response
):
324 """Asserts that the response status is FORBIDDEN.
326 self
.assertResponseCode(response
, httplib
.FORBIDDEN
)
328 def assertResponseBadRequest(self
, response
):
329 """Asserts that the response status is BAD_REQUEST.
331 self
.assertResponseCode(response
, httplib
.BAD_REQUEST
)
333 def assertResponseNotFound(self
, response
):
334 """Asserts that the response status is NOT_FOUND.
336 self
.assertResponseCode(response
, httplib
.NOT_FOUND
)