Merge lp:~cjohnston/ubuntu-ci-services-itself/ts-project into lp:ubuntu-ci-services-itself

Proposed by Chris Johnston
Status: Merged
Approved by: Chris Johnston
Approved revision: 19
Merged at revision: 22
Proposed branch: lp:~cjohnston/ubuntu-ci-services-itself/ts-project
Merge into: lp:ubuntu-ci-services-itself
Diff against target: 375 lines (+316/-0)
8 files modified
ticket_system/project/__init__.py (+14/-0)
ticket_system/project/admin.py (+31/-0)
ticket_system/project/api.py (+42/-0)
ticket_system/project/migrations/0001_initial.py (+51/-0)
ticket_system/project/models.py (+38/-0)
ticket_system/project/tests.py (+136/-0)
ticket_system/ticket_system/settings.py (+1/-0)
ticket_system/ticket_system/urls.py (+3/-0)
To merge this branch: bzr merge lp:~cjohnston/ubuntu-ci-services-itself/ts-project
Reviewer Review Type Date Requested Status
Andy Doan (community) Approve
Review via email: mp+198304@code.launchpad.net

Commit message

Add project app and read API

To post a comment you must log in.
Revision history for this message
Andy Doan (doanac) wrote :

stuff like:

287 + resp = self.api_client.get('/api/v1/sourcepackage/', format='json')
288 + self.assertValidJSONResponse(resp)
289 + self.assertEqual(len(self.deserialize(resp)['objects']), 1)

could probably get folded into:

http://bazaar.launchpad.net/~canonical-ci-engineering/ubuntu-ci-services-itself/trunk/view/head:/ci-utils/ci_utils/tastypie/test.py

In particular it could probably work with the getResource method.

Revision history for this message
Andy Doan (doanac) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added directory 'ticket_system/project'
2=== added file 'ticket_system/project/__init__.py'
3--- ticket_system/project/__init__.py 1970-01-01 00:00:00 +0000
4+++ ticket_system/project/__init__.py 2013-12-09 19:42:24 +0000
5@@ -0,0 +1,14 @@
6+# Ubuntu Continuous Integration Engine
7+# Copyright 2013 Canonical Ltd.
8+
9+# This program is free software: you can redistribute it and/or modify it
10+# under the terms of the GNU Affero General Public License version 3, as
11+# published by the Free Software Foundation.
12+
13+# This program is distributed in the hope that it will be useful, but
14+# WITHOUT ANY WARRANTY; without even the implied warranties of
15+# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
16+# PURPOSE. See the GNU Affero General Public License for more details.
17+
18+# You should have received a copy of the GNU Affero General Public License
19+# along with this program. If not, see <http://www.gnu.org/licenses/>.
20
21=== added file 'ticket_system/project/admin.py'
22--- ticket_system/project/admin.py 1970-01-01 00:00:00 +0000
23+++ ticket_system/project/admin.py 2013-12-09 19:42:24 +0000
24@@ -0,0 +1,31 @@
25+# Ubuntu Continuous Integration Engine
26+# Copyright 2013 Canonical Ltd.
27+
28+# This program is free software: you can redistribute it and/or modify it
29+# under the terms of the GNU Affero General Public License version 3, as
30+# published by the Free Software Foundation.
31+
32+# This program is distributed in the hope that it will be useful, but
33+# WITHOUT ANY WARRANTY; without even the implied warranties of
34+# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
35+# PURPOSE. See the GNU Affero General Public License for more details.
36+
37+# You should have received a copy of the GNU Affero General Public License
38+# along with this program. If not, see <http://www.gnu.org/licenses/>.
39+
40+from django.contrib import admin
41+from project.models import SourcePackage, BinaryPackage
42+
43+
44+class SourcePackageAdmin(admin.ModelAdmin):
45+ search_fields = ['name']
46+ list_display = ('name',)
47+
48+
49+class BinaryPackageAdmin(admin.ModelAdmin):
50+ list_filter = ['seeded']
51+ search_fields = ['name', 'sourcepackage']
52+ list_display = ('name', 'sourcepackage', 'seeded')
53+
54+admin.site.register(SourcePackage, SourcePackageAdmin)
55+admin.site.register(BinaryPackage, BinaryPackageAdmin)
56
57=== added file 'ticket_system/project/api.py'
58--- ticket_system/project/api.py 1970-01-01 00:00:00 +0000
59+++ ticket_system/project/api.py 2013-12-09 19:42:24 +0000
60@@ -0,0 +1,42 @@
61+# Ubuntu Continuous Integration Engine
62+# Copyright 2013 Canonical Ltd.
63+
64+# This program is free software: you can redistribute it and/or modify it
65+# under the terms of the GNU Affero General Public License version 3, as
66+# published by the Free Software Foundation.
67+
68+# This program is distributed in the hope that it will be useful, but
69+# WITHOUT ANY WARRANTY; without even the implied warranties of
70+# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
71+# PURPOSE. See the GNU Affero General Public License for more details.
72+
73+# You should have received a copy of the GNU Affero General Public License
74+# along with this program. If not, see <http://www.gnu.org/licenses/>.
75+
76+from tastypie import fields
77+from tastypie.resources import ModelResource
78+from tastypie.constants import ALL
79+from project.models import SourcePackage, BinaryPackage
80+
81+
82+class SourcePackageResource(ModelResource):
83+
84+ class Meta:
85+ queryset = SourcePackage.objects.all()
86+ allowed_methods = ['get']
87+ filtering = {
88+ "name": ('exact', 'startswith'),
89+ }
90+
91+
92+class BinaryPackageResource(ModelResource):
93+ sourcepackage = fields.ToOneField(SourcePackageResource, 'sourcepackage',
94+ full=True)
95+
96+ class Meta:
97+ queryset = BinaryPackage.objects.all()
98+ allowed_methods = ['get']
99+ filtering = {
100+ "name": ('exact', 'startswith'),
101+ "seeded": ALL,
102+ }
103
104=== added directory 'ticket_system/project/migrations'
105=== added file 'ticket_system/project/migrations/0001_initial.py'
106--- ticket_system/project/migrations/0001_initial.py 1970-01-01 00:00:00 +0000
107+++ ticket_system/project/migrations/0001_initial.py 2013-12-09 19:42:24 +0000
108@@ -0,0 +1,51 @@
109+# -*- coding: utf-8 -*-
110+import datetime
111+from south.db import db
112+from south.v2 import SchemaMigration
113+from django.db import models
114+
115+
116+class Migration(SchemaMigration):
117+
118+ def forwards(self, orm):
119+ # Adding model 'SourcePackage'
120+ db.create_table('sourcepackage', (
121+ (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
122+ ('name', self.gf('django.db.models.fields.CharField')(max_length=4096)),
123+ ))
124+ db.send_create_signal(u'project', ['SourcePackage'])
125+
126+ # Adding model 'BinaryPackage'
127+ db.create_table('binarypackage', (
128+ (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
129+ ('name', self.gf('django.db.models.fields.CharField')(max_length=4096)),
130+ ('sourcepackage', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['project.SourcePackage'])),
131+ ('seeded', self.gf('django.db.models.fields.BooleanField')(default=False)),
132+ ))
133+ db.send_create_signal(u'project', ['BinaryPackage'])
134+
135+
136+ def backwards(self, orm):
137+ # Deleting model 'SourcePackage'
138+ db.delete_table('sourcepackage')
139+
140+ # Deleting model 'BinaryPackage'
141+ db.delete_table('binarypackage')
142+
143+
144+ models = {
145+ u'project.binarypackage': {
146+ 'Meta': {'object_name': 'BinaryPackage', 'db_table': "'binarypackage'"},
147+ u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
148+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '4096'}),
149+ 'seeded': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
150+ 'sourcepackage': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['project.SourcePackage']"})
151+ },
152+ u'project.sourcepackage': {
153+ 'Meta': {'object_name': 'SourcePackage', 'db_table': "'sourcepackage'"},
154+ u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
155+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '4096'})
156+ }
157+ }
158+
159+ complete_apps = ['project']
160\ No newline at end of file
161
162=== added file 'ticket_system/project/migrations/__init__.py'
163=== added file 'ticket_system/project/models.py'
164--- ticket_system/project/models.py 1970-01-01 00:00:00 +0000
165+++ ticket_system/project/models.py 2013-12-09 19:42:24 +0000
166@@ -0,0 +1,38 @@
167+# Ubuntu Continuous Integration Engine
168+# Copyright 2013 Canonical Ltd.
169+
170+# This program is free software: you can redistribute it and/or modify it
171+# under the terms of the GNU Affero General Public License version 3, as
172+# published by the Free Software Foundation.
173+
174+# This program is distributed in the hope that it will be useful, but
175+# WITHOUT ANY WARRANTY; without even the implied warranties of
176+# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
177+# PURPOSE. See the GNU Affero General Public License for more details.
178+
179+# You should have received a copy of the GNU Affero General Public License
180+# along with this program. If not, see <http://www.gnu.org/licenses/>.
181+
182+from django.db import models
183+
184+
185+class SourcePackage(models.Model):
186+ class Meta:
187+ db_table = "sourcepackage"
188+
189+ name = models.CharField(max_length=4096)
190+
191+ def __unicode__(self):
192+ return self.name
193+
194+
195+class BinaryPackage(models.Model):
196+ class Meta:
197+ db_table = "binarypackage"
198+
199+ name = models.CharField(max_length=4096)
200+ sourcepackage = models.ForeignKey("SourcePackage")
201+ seeded = models.BooleanField(default=False)
202+
203+ def __unicode__(self):
204+ return self.name
205
206=== added file 'ticket_system/project/tests.py'
207--- ticket_system/project/tests.py 1970-01-01 00:00:00 +0000
208+++ ticket_system/project/tests.py 2013-12-09 19:42:24 +0000
209@@ -0,0 +1,136 @@
210+# Ubuntu Continuous Integration Engine
211+# Copyright 2013 Canonical Ltd.
212+
213+# This program is free software: you can redistribute it and/or modify it
214+# under the terms of the GNU Affero General Public License version 3, as
215+# published by the Free Software Foundation.
216+
217+# This program is distributed in the hope that it will be useful, but
218+# WITHOUT ANY WARRANTY; without even the implied warranties of
219+# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
220+# PURPOSE. See the GNU Affero General Public License for more details.
221+
222+# You should have received a copy of the GNU Affero General Public License
223+# along with this program. If not, see <http://www.gnu.org/licenses/>.
224+
225+from django.test import TestCase
226+from tastypie.test import ResourceTestCase
227+from project.models import SourcePackage, BinaryPackage
228+
229+
230+def create_sourcepackage(name="awesome-package"):
231+ package = SourcePackage()
232+ package.name = name
233+ package.save()
234+ return package
235+
236+
237+def create_binarypackage(name="awesome-binary", sourcepackage=None,
238+ seeded=False):
239+ binary = BinaryPackage()
240+ binary.name = name
241+ binary.sourcepackage = sourcepackage
242+ binary.seeded = seeded
243+ binary.save()
244+ return binary
245+
246+
247+class SourcePackageModelTest(TestCase):
248+
249+ def test_creating_a_sourcepackage(self):
250+ package = create_sourcepackage()
251+ package_in_database = SourcePackage.objects.all()
252+ self.assertEquals(len(package_in_database), 1)
253+ only_package_in_database = package_in_database[0]
254+ self.assertEquals(only_package_in_database, package)
255+
256+ self.assertEquals(only_package_in_database.name, "awesome-package")
257+
258+
259+class BinaryPackageModelTest(TestCase):
260+
261+ def setUp(self):
262+ self.sourcepackage = create_sourcepackage()
263+ self.binarypackage = create_binarypackage(
264+ sourcepackage=self.sourcepackage)
265+
266+ def test_creating_a_binarypackage(self):
267+ binarypackage_in_database = BinaryPackage.objects.all()
268+ self.assertEquals(len(binarypackage_in_database), 1)
269+ only_binarypackage_in_database = binarypackage_in_database[0]
270+ self.assertEquals(only_binarypackage_in_database, self.binarypackage)
271+
272+ self.assertEquals(only_binarypackage_in_database.name,
273+ "awesome-binary")
274+
275+
276+class SourcePackageResourceTest(ResourceTestCase):
277+
278+ def setUp(self):
279+ super(SourcePackageResourceTest, self).setUp()
280+ create_sourcepackage()
281+ self.sourcepackage_1 = SourcePackage.objects.get(
282+ name='awesome-package')
283+ self.detail_url = '/api/v1/sourcepackage/{0}/'.format(
284+ self.sourcepackage_1.pk)
285+
286+ def test_get_sourcepackage_list_json(self):
287+ resp = self.api_client.get('/api/v1/sourcepackage/', format='json')
288+ self.assertValidJSONResponse(resp)
289+ self.assertEqual(len(self.deserialize(resp)['objects']), 1)
290+ self.assertEqual(self.deserialize(resp)['objects'][0], {
291+ u'id': self.sourcepackage_1.pk,
292+ u'name': u'awesome-package',
293+ u'resource_uri': u'/api/v1/sourcepackage/{0}/'.format(
294+ self.sourcepackage_1.pk)
295+ })
296+
297+ def test_get_sourcepackage_detail_json(self):
298+ resp = self.api_client.get(self.detail_url)
299+ self.assertValidJSONResponse(resp)
300+
301+ # We use ``assertKeys`` here to just verify the keys, not all the data.
302+ self.assertKeys(self.deserialize(resp),
303+ ['id', 'name', 'resource_uri'])
304+ self.assertEqual(self.deserialize(resp)['name'], 'awesome-package')
305+
306+
307+class BinaryPackageResourceTest(ResourceTestCase):
308+
309+ def setUp(self):
310+ super(BinaryPackageResourceTest, self).setUp()
311+ create_sourcepackage()
312+ self.sourcepackage_1 = SourcePackage.objects.get(
313+ name='awesome-package')
314+ create_binarypackage(sourcepackage=self.sourcepackage_1)
315+ self.binarypackage_1 = BinaryPackage.objects.get(
316+ name='awesome-binary')
317+ self.detail_url = '/api/v1/binarypackage/{0}/'.format(
318+ self.binarypackage_1.pk)
319+
320+ def test_get_binarypackage_list_json(self):
321+ resp = self.api_client.get('/api/v1/binarypackage/', format='json')
322+ self.assertValidJSONResponse(resp)
323+ self.assertEqual(len(self.deserialize(resp)['objects']), 1)
324+ self.assertEqual(self.deserialize(resp)['objects'][0], {
325+ u'id': self.binarypackage_1.pk,
326+ u'name': u'awesome-binary',
327+ u'seeded': False,
328+ u'sourcepackage': {
329+ u'id': self.sourcepackage_1.pk,
330+ u'name': u'awesome-package',
331+ u'resource_uri': u'/api/v1/sourcepackage/{0}/'.format(
332+ self.sourcepackage_1.pk)},
333+ u'resource_uri': u'/api/v1/binarypackage/{0}/'.format(
334+ self.binarypackage_1.pk)
335+ })
336+
337+ def test_get_binarypackage_detail_json(self):
338+ resp = self.api_client.get(self.detail_url)
339+ self.assertValidJSONResponse(resp)
340+
341+ # We use ``assertKeys`` here to just verify the keys, not all the data.
342+ self.assertKeys(self.deserialize(resp),
343+ ['id', 'name', 'resource_uri', 'seeded',
344+ 'sourcepackage'])
345+ self.assertEqual(self.deserialize(resp)['name'], 'awesome-binary')
346
347=== modified file 'ticket_system/ticket_system/settings.py'
348--- ticket_system/ticket_system/settings.py 2013-12-09 17:43:12 +0000
349+++ ticket_system/ticket_system/settings.py 2013-12-09 19:42:24 +0000
350@@ -140,6 +140,7 @@
351
352 LOCAL_APPS = (
353 'people',
354+ 'project',
355 )
356
357 INSTALLED_APPS = LOCAL_APPS + INSTALLED_APPS
358
359=== modified file 'ticket_system/ticket_system/urls.py'
360--- ticket_system/ticket_system/urls.py 2013-12-09 17:43:12 +0000
361+++ ticket_system/ticket_system/urls.py 2013-12-09 19:42:24 +0000
362@@ -17,10 +17,13 @@
363 from django.contrib import admin
364 from tastypie.api import Api
365 from people.api import PersonResource
366+from project.api import SourcePackageResource, BinaryPackageResource
367
368 admin.autodiscover()
369 v1_api = Api(api_name='v1')
370 v1_api.register(PersonResource())
371+v1_api.register(SourcePackageResource())
372+v1_api.register(BinaryPackageResource())
373
374 urlpatterns = patterns(
375 '',

Subscribers

People subscribed via source and target branches