root / snf-astakos-app / astakos / im / tests / projects.py @ 50f74340
History | View | Annotate | Download (10.2 kB)
1 | bd1f667b | Giorgos Korfiatis | # Copyright 2011, 2012, 2013 GRNET S.A. All rights reserved.
|
---|---|---|---|
2 | 1ac3349d | Kostas Papadimitriou | #
|
3 | 1ac3349d | Kostas Papadimitriou | # Redistribution and use in source and binary forms, with or
|
4 | 1ac3349d | Kostas Papadimitriou | # without modification, are permitted provided that the following
|
5 | 1ac3349d | Kostas Papadimitriou | # conditions are met:
|
6 | 1ac3349d | Kostas Papadimitriou | #
|
7 | 1ac3349d | Kostas Papadimitriou | # 1. Redistributions of source code must retain the above
|
8 | 1ac3349d | Kostas Papadimitriou | # copyright notice, this list of conditions and the following
|
9 | 1ac3349d | Kostas Papadimitriou | # disclaimer.
|
10 | 1ac3349d | Kostas Papadimitriou | #
|
11 | 1ac3349d | Kostas Papadimitriou | # 2. Redistributions in binary form must reproduce the above
|
12 | 1ac3349d | Kostas Papadimitriou | # copyright notice, this list of conditions and the following
|
13 | 1ac3349d | Kostas Papadimitriou | # disclaimer in the documentation and/or other materials
|
14 | 1ac3349d | Kostas Papadimitriou | # provided with the distribution.
|
15 | 1ac3349d | Kostas Papadimitriou | #
|
16 | 1ac3349d | Kostas Papadimitriou | # THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
|
17 | 1ac3349d | Kostas Papadimitriou | # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
18 | 1ac3349d | Kostas Papadimitriou | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
19 | 1ac3349d | Kostas Papadimitriou | # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
|
20 | 1ac3349d | Kostas Papadimitriou | # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
21 | 1ac3349d | Kostas Papadimitriou | # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
22 | 1ac3349d | Kostas Papadimitriou | # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
23 | 1ac3349d | Kostas Papadimitriou | # USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
24 | 1ac3349d | Kostas Papadimitriou | # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
25 | 1ac3349d | Kostas Papadimitriou | # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
26 | 1ac3349d | Kostas Papadimitriou | # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
27 | 1ac3349d | Kostas Papadimitriou | # POSSIBILITY OF SUCH DAMAGE.
|
28 | 1ac3349d | Kostas Papadimitriou | #
|
29 | 1ac3349d | Kostas Papadimitriou | # The views and conclusions contained in the software and
|
30 | 1ac3349d | Kostas Papadimitriou | # documentation are those of the authors and should not be
|
31 | 1ac3349d | Kostas Papadimitriou | # interpreted as representing official policies, either expressed
|
32 | 1ac3349d | Kostas Papadimitriou | # or implied, of GRNET S.A.
|
33 | 1ac3349d | Kostas Papadimitriou | |
34 | 1ac3349d | Kostas Papadimitriou | from astakos.im.tests.common import * |
35 | 1ac3349d | Kostas Papadimitriou | |
36 | 1ac3349d | Kostas Papadimitriou | |
37 | 1ac3349d | Kostas Papadimitriou | class TestProjects(TestCase): |
38 | 1ac3349d | Kostas Papadimitriou | """
|
39 | 1ac3349d | Kostas Papadimitriou | Test projects.
|
40 | 1ac3349d | Kostas Papadimitriou | """
|
41 | 1ac3349d | Kostas Papadimitriou | def setUp(self): |
42 | 1ac3349d | Kostas Papadimitriou | # astakos resources
|
43 | 1ac3349d | Kostas Papadimitriou | self.resource = Resource.objects.create(name="astakos.pending_app", |
44 | 1ac3349d | Kostas Papadimitriou | uplimit=0,
|
45 | 1ac3349d | Kostas Papadimitriou | allow_in_projects=False,
|
46 | bd1f667b | Giorgos Korfiatis | service_type="astakos")
|
47 | 1ac3349d | Kostas Papadimitriou | |
48 | 1ac3349d | Kostas Papadimitriou | # custom service resources
|
49 | 1ac3349d | Kostas Papadimitriou | self.resource = Resource.objects.create(name="service1.resource", |
50 | 1ac3349d | Kostas Papadimitriou | uplimit=100,
|
51 | bd1f667b | Giorgos Korfiatis | service_type="service1")
|
52 | 1ac3349d | Kostas Papadimitriou | self.admin = get_local_user("projects-admin@synnefo.org") |
53 | 1ac3349d | Kostas Papadimitriou | self.admin.uuid = 'uuid1' |
54 | 1ac3349d | Kostas Papadimitriou | self.admin.save()
|
55 | 1ac3349d | Kostas Papadimitriou | |
56 | 1ac3349d | Kostas Papadimitriou | self.user = get_local_user("user@synnefo.org") |
57 | 1ac3349d | Kostas Papadimitriou | self.member = get_local_user("member@synnefo.org") |
58 | 1ac3349d | Kostas Papadimitriou | self.member2 = get_local_user("member2@synnefo.org") |
59 | 1ac3349d | Kostas Papadimitriou | |
60 | 1ac3349d | Kostas Papadimitriou | self.admin_client = get_user_client("projects-admin@synnefo.org") |
61 | 1ac3349d | Kostas Papadimitriou | self.user_client = get_user_client("user@synnefo.org") |
62 | 1ac3349d | Kostas Papadimitriou | self.member_client = get_user_client("member@synnefo.org") |
63 | 1ac3349d | Kostas Papadimitriou | self.member2_client = get_user_client("member2@synnefo.org") |
64 | 1ac3349d | Kostas Papadimitriou | |
65 | 1ac3349d | Kostas Papadimitriou | quotas.qh_sync_users(AstakosUser.objects.all()) |
66 | 1ac3349d | Kostas Papadimitriou | |
67 | baa9073a | Kostas Papadimitriou | def tearDown(self): |
68 | baa9073a | Kostas Papadimitriou | Service.objects.all().delete() |
69 | baa9073a | Kostas Papadimitriou | ProjectApplication.objects.all().delete() |
70 | fce2ebcb | Kostas Papadimitriou | Project.objects.all().delete() |
71 | fce2ebcb | Kostas Papadimitriou | AstakosUser.objects.all().delete() |
72 | baa9073a | Kostas Papadimitriou | |
73 | 1ac3349d | Kostas Papadimitriou | @im_settings(PROJECT_ADMINS=['uuid1']) |
74 | 1ac3349d | Kostas Papadimitriou | def test_application_limit(self): |
75 | 1ac3349d | Kostas Papadimitriou | # user cannot create a project
|
76 | 1ac3349d | Kostas Papadimitriou | r = self.user_client.get(reverse('project_add'), follow=True) |
77 | 1ac3349d | Kostas Papadimitriou | self.assertRedirects(r, reverse('project_list')) |
78 | 1ac3349d | Kostas Papadimitriou | self.assertContains(r, "You are not allowed to create a new project") |
79 | 1ac3349d | Kostas Papadimitriou | |
80 | 1ac3349d | Kostas Papadimitriou | # but admin can
|
81 | 1ac3349d | Kostas Papadimitriou | r = self.admin_client.get(reverse('project_add'), follow=True) |
82 | 1ac3349d | Kostas Papadimitriou | self.assertRedirects(r, reverse('project_add')) |
83 | 1ac3349d | Kostas Papadimitriou | |
84 | 1ac3349d | Kostas Papadimitriou | @im_settings(PROJECT_ADMINS=['uuid1']) |
85 | 1ac3349d | Kostas Papadimitriou | def test_allow_in_project(self): |
86 | 1ac3349d | Kostas Papadimitriou | dfrom = datetime.now() |
87 | 1ac3349d | Kostas Papadimitriou | dto = datetime.now() + timedelta(days=30)
|
88 | 1ac3349d | Kostas Papadimitriou | |
89 | 1ac3349d | Kostas Papadimitriou | # astakos.pending_uplimit allow_in_project flag is False
|
90 | 1ac3349d | Kostas Papadimitriou | # we shouldn't be able to create a project application using this
|
91 | 1ac3349d | Kostas Papadimitriou | # resource.
|
92 | 1ac3349d | Kostas Papadimitriou | application_data = { |
93 | 1ac3349d | Kostas Papadimitriou | 'name': 'project.synnefo.org', |
94 | 1ac3349d | Kostas Papadimitriou | 'homepage': 'https://www.synnefo.org', |
95 | 1ac3349d | Kostas Papadimitriou | 'start_date': dfrom.strftime("%Y-%m-%d"), |
96 | 1ac3349d | Kostas Papadimitriou | 'end_date': dto.strftime("%Y-%m-%d"), |
97 | 1ac3349d | Kostas Papadimitriou | 'member_join_policy': 2, |
98 | 1ac3349d | Kostas Papadimitriou | 'member_leave_policy': 1, |
99 | 1ac3349d | Kostas Papadimitriou | 'service1.resource_uplimit': 100, |
100 | 1ac3349d | Kostas Papadimitriou | 'is_selected_service1.resource': "1", |
101 | 1ac3349d | Kostas Papadimitriou | 'astakos.pending_app_uplimit': 100, |
102 | 1ac3349d | Kostas Papadimitriou | 'is_selected_accounts': "1", |
103 | 1ac3349d | Kostas Papadimitriou | 'user': self.user.pk |
104 | 1ac3349d | Kostas Papadimitriou | } |
105 | 1ac3349d | Kostas Papadimitriou | form = forms.ProjectApplicationForm(data=application_data) |
106 | 1ac3349d | Kostas Papadimitriou | # form is invalid
|
107 | 1ac3349d | Kostas Papadimitriou | self.assertEqual(form.is_valid(), False) |
108 | 1ac3349d | Kostas Papadimitriou | |
109 | 1ac3349d | Kostas Papadimitriou | del application_data['astakos.pending_app_uplimit'] |
110 | 1ac3349d | Kostas Papadimitriou | del application_data['is_selected_accounts'] |
111 | 1ac3349d | Kostas Papadimitriou | form = forms.ProjectApplicationForm(data=application_data) |
112 | 1ac3349d | Kostas Papadimitriou | self.assertEqual(form.is_valid(), True) |
113 | 1ac3349d | Kostas Papadimitriou | |
114 | 1ac3349d | Kostas Papadimitriou | @im_settings(PROJECT_ADMINS=['uuid1']) |
115 | 1ac3349d | Kostas Papadimitriou | def test_applications(self): |
116 | 1ac3349d | Kostas Papadimitriou | # let user have 2 pending applications
|
117 | 1ac3349d | Kostas Papadimitriou | quotas.add_base_quota(self.user, 'astakos.pending_app', 2) |
118 | 1ac3349d | Kostas Papadimitriou | |
119 | 1ac3349d | Kostas Papadimitriou | r = self.user_client.get(reverse('project_add'), follow=True) |
120 | 1ac3349d | Kostas Papadimitriou | self.assertRedirects(r, reverse('project_add')) |
121 | 1ac3349d | Kostas Papadimitriou | |
122 | 1ac3349d | Kostas Papadimitriou | # user fills the project application form
|
123 | 1ac3349d | Kostas Papadimitriou | post_url = reverse('project_add') + '?verify=1' |
124 | 1ac3349d | Kostas Papadimitriou | dfrom = datetime.now() |
125 | 1ac3349d | Kostas Papadimitriou | dto = datetime.now() + timedelta(days=30)
|
126 | 1ac3349d | Kostas Papadimitriou | application_data = { |
127 | 1ac3349d | Kostas Papadimitriou | 'name': 'project.synnefo.org', |
128 | 1ac3349d | Kostas Papadimitriou | 'homepage': 'https://www.synnefo.org', |
129 | 1ac3349d | Kostas Papadimitriou | 'start_date': dfrom.strftime("%Y-%m-%d"), |
130 | 1ac3349d | Kostas Papadimitriou | 'end_date': dto.strftime("%Y-%m-%d"), |
131 | 1ac3349d | Kostas Papadimitriou | 'member_join_policy': 2, |
132 | 1ac3349d | Kostas Papadimitriou | 'member_leave_policy': 1, |
133 | 1ac3349d | Kostas Papadimitriou | 'service1.resource_uplimit': 100, |
134 | 1ac3349d | Kostas Papadimitriou | 'is_selected_service1.resource': "1", |
135 | 1ac3349d | Kostas Papadimitriou | 'user': self.user.pk |
136 | 1ac3349d | Kostas Papadimitriou | } |
137 | 1ac3349d | Kostas Papadimitriou | r = self.user_client.post(post_url, data=application_data, follow=True) |
138 | 1ac3349d | Kostas Papadimitriou | self.assertEqual(r.status_code, 200) |
139 | 1ac3349d | Kostas Papadimitriou | self.assertEqual(r.context['form'].is_valid(), True) |
140 | 1ac3349d | Kostas Papadimitriou | |
141 | 1ac3349d | Kostas Papadimitriou | # confirm request
|
142 | 1ac3349d | Kostas Papadimitriou | post_url = reverse('project_add') + '?verify=0&edit=0' |
143 | 1ac3349d | Kostas Papadimitriou | r = self.user_client.post(post_url, data=application_data, follow=True) |
144 | 1ac3349d | Kostas Papadimitriou | self.assertContains(r, "The project application has been received") |
145 | 1ac3349d | Kostas Papadimitriou | self.assertRedirects(r, reverse('project_list')) |
146 | 1ac3349d | Kostas Papadimitriou | self.assertEqual(ProjectApplication.objects.count(), 1) |
147 | 50f74340 | Giorgos Korfiatis | app1 = ProjectApplication.objects.filter().order_by('pk')[0] |
148 | 50f74340 | Giorgos Korfiatis | app1_id = app1.pk |
149 | 50f74340 | Giorgos Korfiatis | project1_id = app1.chain_id |
150 | 1ac3349d | Kostas Papadimitriou | |
151 | 1ac3349d | Kostas Papadimitriou | # create another one
|
152 | 1ac3349d | Kostas Papadimitriou | application_data['name'] = 'project2.synnefo.org' |
153 | 1ac3349d | Kostas Papadimitriou | r = self.user_client.post(post_url, data=application_data, follow=True) |
154 | 50f74340 | Giorgos Korfiatis | app2 = ProjectApplication.objects.filter().order_by('pk')[1] |
155 | 50f74340 | Giorgos Korfiatis | project2_id = app2.chain_id |
156 | 1ac3349d | Kostas Papadimitriou | |
157 | 1ac3349d | Kostas Papadimitriou | # no more applications (LIMIT is 2)
|
158 | 1ac3349d | Kostas Papadimitriou | r = self.user_client.get(reverse('project_add'), follow=True) |
159 | 1ac3349d | Kostas Papadimitriou | self.assertRedirects(r, reverse('project_list')) |
160 | 1ac3349d | Kostas Papadimitriou | self.assertContains(r, "You are not allowed to create a new project") |
161 | 1ac3349d | Kostas Papadimitriou | |
162 | 50f74340 | Giorgos Korfiatis | # one project per application
|
163 | 50f74340 | Giorgos Korfiatis | self.assertEqual(Project.objects.count(), 2) |
164 | 50f74340 | Giorgos Korfiatis | |
165 | 1ac3349d | Kostas Papadimitriou | # login
|
166 | 1ac3349d | Kostas Papadimitriou | self.admin_client.get(reverse("edit_profile")) |
167 | 1ac3349d | Kostas Papadimitriou | # admin approves
|
168 | 1ac3349d | Kostas Papadimitriou | r = self.admin_client.post(reverse('project_app_approve', |
169 | 1ac3349d | Kostas Papadimitriou | kwargs={'application_id': app1_id}),
|
170 | 1ac3349d | Kostas Papadimitriou | follow=True)
|
171 | 1ac3349d | Kostas Papadimitriou | self.assertEqual(r.status_code, 200) |
172 | 1ac3349d | Kostas Papadimitriou | |
173 | 50f74340 | Giorgos Korfiatis | Q_ACTIVE = Project.o_state_q(Project.O_ACTIVE) |
174 | 50f74340 | Giorgos Korfiatis | self.assertEqual(Project.objects.filter(Q_ACTIVE).count(), 1) |
175 | 1ac3349d | Kostas Papadimitriou | |
176 | 1ac3349d | Kostas Papadimitriou | # login
|
177 | 1ac3349d | Kostas Papadimitriou | self.member_client.get(reverse("edit_profile")) |
178 | 50f74340 | Giorgos Korfiatis | # cannot join project2 (not approved yet)
|
179 | 50f74340 | Giorgos Korfiatis | join_url = reverse("project_join", kwargs={'chain_id': project2_id}) |
180 | 1ac3349d | Kostas Papadimitriou | r = self.member_client.post(join_url, follow=True) |
181 | 1ac3349d | Kostas Papadimitriou | |
182 | 50f74340 | Giorgos Korfiatis | # can join project1
|
183 | 1ac3349d | Kostas Papadimitriou | self.member_client.get(reverse("edit_profile")) |
184 | 50f74340 | Giorgos Korfiatis | join_url = reverse("project_join", kwargs={'chain_id': project1_id}) |
185 | 1ac3349d | Kostas Papadimitriou | r = self.member_client.post(join_url, follow=True) |
186 | 1ac3349d | Kostas Papadimitriou | self.assertEqual(r.status_code, 200) |
187 | 1ac3349d | Kostas Papadimitriou | |
188 | 1ac3349d | Kostas Papadimitriou | memberships = ProjectMembership.objects.all() |
189 | 1ac3349d | Kostas Papadimitriou | self.assertEqual(len(memberships), 1) |
190 | 1ac3349d | Kostas Papadimitriou | memb_id = memberships[0].id
|
191 | 1ac3349d | Kostas Papadimitriou | |
192 | 1ac3349d | Kostas Papadimitriou | reject_member_url = reverse('project_reject_member',
|
193 | 50f74340 | Giorgos Korfiatis | kwargs={'memb_id': memb_id})
|
194 | 1ac3349d | Kostas Papadimitriou | accept_member_url = reverse('project_accept_member',
|
195 | 50f74340 | Giorgos Korfiatis | kwargs={'memb_id': memb_id})
|
196 | 1ac3349d | Kostas Papadimitriou | |
197 | 1ac3349d | Kostas Papadimitriou | # only project owner is allowed to reject
|
198 | 1ac3349d | Kostas Papadimitriou | r = self.member_client.post(reject_member_url, follow=True) |
199 | 1ac3349d | Kostas Papadimitriou | self.assertContains(r, "You do not have the permissions") |
200 | 1ac3349d | Kostas Papadimitriou | self.assertEqual(r.status_code, 200) |
201 | 1ac3349d | Kostas Papadimitriou | |
202 | 1ac3349d | Kostas Papadimitriou | # user (owns project) rejects membership
|
203 | 1ac3349d | Kostas Papadimitriou | r = self.user_client.post(reject_member_url, follow=True) |
204 | 50f74340 | Giorgos Korfiatis | self.assertEqual(ProjectMembership.objects.any_accepted().count(), 0) |
205 | 1ac3349d | Kostas Papadimitriou | |
206 | 1ac3349d | Kostas Papadimitriou | # user rejoins
|
207 | 1ac3349d | Kostas Papadimitriou | self.member_client.get(reverse("edit_profile")) |
208 | 1ac3349d | Kostas Papadimitriou | join_url = reverse("project_join", kwargs={'chain_id': app1_id}) |
209 | 1ac3349d | Kostas Papadimitriou | r = self.member_client.post(join_url, follow=True) |
210 | 1ac3349d | Kostas Papadimitriou | self.assertEqual(r.status_code, 200) |
211 | 50f74340 | Giorgos Korfiatis | self.assertEqual(ProjectMembership.objects.requested().count(), 1) |
212 | 1ac3349d | Kostas Papadimitriou | |
213 | 1ac3349d | Kostas Papadimitriou | # user (owns project) accepts membership
|
214 | 1ac3349d | Kostas Papadimitriou | r = self.user_client.post(accept_member_url, follow=True) |
215 | 50f74340 | Giorgos Korfiatis | self.assertEqual(ProjectMembership.objects.any_accepted().count(), 1) |
216 | 1ac3349d | Kostas Papadimitriou | membership = ProjectMembership.objects.get() |
217 | 1ac3349d | Kostas Papadimitriou | self.assertEqual(membership.state, ProjectMembership.ACCEPTED)
|
218 | 1ac3349d | Kostas Papadimitriou | |
219 | 1ac3349d | Kostas Papadimitriou | user_quotas = quotas.get_users_quotas([self.member])
|
220 | 1ac3349d | Kostas Papadimitriou | resource = 'service1.resource'
|
221 | 1ac3349d | Kostas Papadimitriou | newlimit = user_quotas[self.member.uuid]['system'][resource]['limit'] |
222 | 1ac3349d | Kostas Papadimitriou | # 100 from initial uplimit + 100 from project
|
223 | 1ac3349d | Kostas Papadimitriou | self.assertEqual(newlimit, 200) |
224 | 1ac3349d | Kostas Papadimitriou | |
225 | 1ac3349d | Kostas Papadimitriou | remove_member_url = reverse('project_remove_member',
|
226 | 50f74340 | Giorgos Korfiatis | kwargs={'memb_id': membership.id})
|
227 | 1ac3349d | Kostas Papadimitriou | r = self.user_client.post(remove_member_url, follow=True) |
228 | 1ac3349d | Kostas Papadimitriou | self.assertEqual(r.status_code, 200) |
229 | 1ac3349d | Kostas Papadimitriou | |
230 | 1ac3349d | Kostas Papadimitriou | user_quotas = quotas.get_users_quotas([self.member])
|
231 | 1ac3349d | Kostas Papadimitriou | resource = 'service1.resource'
|
232 | 1ac3349d | Kostas Papadimitriou | newlimit = user_quotas[self.member.uuid]['system'][resource]['limit'] |
233 | 1ac3349d | Kostas Papadimitriou | # 200 - 100 from project
|
234 | 1ac3349d | Kostas Papadimitriou | self.assertEqual(newlimit, 100) |
235 | b130ec7c | Kostas Papadimitriou | |
236 | b130ec7c | Kostas Papadimitriou | # support email gets rendered in emails content
|
237 | b130ec7c | Kostas Papadimitriou | for mail in get_mailbox('user@synnefo.org'): |
238 | d4e4e501 | Christos Stavrakakis | self.assertTrue(settings.CONTACT_EMAIL in |
239 | b130ec7c | Kostas Papadimitriou | mail.message().as_string()) |