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
=== added directory 'ticket_system/project'
=== added file 'ticket_system/project/__init__.py'
--- ticket_system/project/__init__.py 1970-01-01 00:00:00 +0000
+++ ticket_system/project/__init__.py 2013-12-09 19:42:24 +0000
@@ -0,0 +1,14 @@
1# Ubuntu Continuous Integration Engine
2# Copyright 2013 Canonical Ltd.
3
4# This program is free software: you can redistribute it and/or modify it
5# under the terms of the GNU Affero General Public License version 3, as
6# published by the Free Software Foundation.
7
8# This program is distributed in the hope that it will be useful, but
9# WITHOUT ANY WARRANTY; without even the implied warranties of
10# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
11# PURPOSE. See the GNU Affero General Public License for more details.
12
13# You should have received a copy of the GNU Affero General Public License
14# along with this program. If not, see <http://www.gnu.org/licenses/>.
015
=== added file 'ticket_system/project/admin.py'
--- ticket_system/project/admin.py 1970-01-01 00:00:00 +0000
+++ ticket_system/project/admin.py 2013-12-09 19:42:24 +0000
@@ -0,0 +1,31 @@
1# Ubuntu Continuous Integration Engine
2# Copyright 2013 Canonical Ltd.
3
4# This program is free software: you can redistribute it and/or modify it
5# under the terms of the GNU Affero General Public License version 3, as
6# published by the Free Software Foundation.
7
8# This program is distributed in the hope that it will be useful, but
9# WITHOUT ANY WARRANTY; without even the implied warranties of
10# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
11# PURPOSE. See the GNU Affero General Public License for more details.
12
13# You should have received a copy of the GNU Affero General Public License
14# along with this program. If not, see <http://www.gnu.org/licenses/>.
15
16from django.contrib import admin
17from project.models import SourcePackage, BinaryPackage
18
19
20class SourcePackageAdmin(admin.ModelAdmin):
21 search_fields = ['name']
22 list_display = ('name',)
23
24
25class BinaryPackageAdmin(admin.ModelAdmin):
26 list_filter = ['seeded']
27 search_fields = ['name', 'sourcepackage']
28 list_display = ('name', 'sourcepackage', 'seeded')
29
30admin.site.register(SourcePackage, SourcePackageAdmin)
31admin.site.register(BinaryPackage, BinaryPackageAdmin)
032
=== added file 'ticket_system/project/api.py'
--- ticket_system/project/api.py 1970-01-01 00:00:00 +0000
+++ ticket_system/project/api.py 2013-12-09 19:42:24 +0000
@@ -0,0 +1,42 @@
1# Ubuntu Continuous Integration Engine
2# Copyright 2013 Canonical Ltd.
3
4# This program is free software: you can redistribute it and/or modify it
5# under the terms of the GNU Affero General Public License version 3, as
6# published by the Free Software Foundation.
7
8# This program is distributed in the hope that it will be useful, but
9# WITHOUT ANY WARRANTY; without even the implied warranties of
10# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
11# PURPOSE. See the GNU Affero General Public License for more details.
12
13# You should have received a copy of the GNU Affero General Public License
14# along with this program. If not, see <http://www.gnu.org/licenses/>.
15
16from tastypie import fields
17from tastypie.resources import ModelResource
18from tastypie.constants import ALL
19from project.models import SourcePackage, BinaryPackage
20
21
22class SourcePackageResource(ModelResource):
23
24 class Meta:
25 queryset = SourcePackage.objects.all()
26 allowed_methods = ['get']
27 filtering = {
28 "name": ('exact', 'startswith'),
29 }
30
31
32class BinaryPackageResource(ModelResource):
33 sourcepackage = fields.ToOneField(SourcePackageResource, 'sourcepackage',
34 full=True)
35
36 class Meta:
37 queryset = BinaryPackage.objects.all()
38 allowed_methods = ['get']
39 filtering = {
40 "name": ('exact', 'startswith'),
41 "seeded": ALL,
42 }
043
=== added directory 'ticket_system/project/migrations'
=== added file 'ticket_system/project/migrations/0001_initial.py'
--- ticket_system/project/migrations/0001_initial.py 1970-01-01 00:00:00 +0000
+++ ticket_system/project/migrations/0001_initial.py 2013-12-09 19:42:24 +0000
@@ -0,0 +1,51 @@
1# -*- coding: utf-8 -*-
2import datetime
3from south.db import db
4from south.v2 import SchemaMigration
5from django.db import models
6
7
8class Migration(SchemaMigration):
9
10 def forwards(self, orm):
11 # Adding model 'SourcePackage'
12 db.create_table('sourcepackage', (
13 (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
14 ('name', self.gf('django.db.models.fields.CharField')(max_length=4096)),
15 ))
16 db.send_create_signal(u'project', ['SourcePackage'])
17
18 # Adding model 'BinaryPackage'
19 db.create_table('binarypackage', (
20 (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
21 ('name', self.gf('django.db.models.fields.CharField')(max_length=4096)),
22 ('sourcepackage', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['project.SourcePackage'])),
23 ('seeded', self.gf('django.db.models.fields.BooleanField')(default=False)),
24 ))
25 db.send_create_signal(u'project', ['BinaryPackage'])
26
27
28 def backwards(self, orm):
29 # Deleting model 'SourcePackage'
30 db.delete_table('sourcepackage')
31
32 # Deleting model 'BinaryPackage'
33 db.delete_table('binarypackage')
34
35
36 models = {
37 u'project.binarypackage': {
38 'Meta': {'object_name': 'BinaryPackage', 'db_table': "'binarypackage'"},
39 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
40 'name': ('django.db.models.fields.CharField', [], {'max_length': '4096'}),
41 'seeded': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
42 'sourcepackage': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['project.SourcePackage']"})
43 },
44 u'project.sourcepackage': {
45 'Meta': {'object_name': 'SourcePackage', 'db_table': "'sourcepackage'"},
46 u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
47 'name': ('django.db.models.fields.CharField', [], {'max_length': '4096'})
48 }
49 }
50
51 complete_apps = ['project']
0\ No newline at end of file52\ No newline at end of file
153
=== added file 'ticket_system/project/migrations/__init__.py'
=== added file 'ticket_system/project/models.py'
--- ticket_system/project/models.py 1970-01-01 00:00:00 +0000
+++ ticket_system/project/models.py 2013-12-09 19:42:24 +0000
@@ -0,0 +1,38 @@
1# Ubuntu Continuous Integration Engine
2# Copyright 2013 Canonical Ltd.
3
4# This program is free software: you can redistribute it and/or modify it
5# under the terms of the GNU Affero General Public License version 3, as
6# published by the Free Software Foundation.
7
8# This program is distributed in the hope that it will be useful, but
9# WITHOUT ANY WARRANTY; without even the implied warranties of
10# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
11# PURPOSE. See the GNU Affero General Public License for more details.
12
13# You should have received a copy of the GNU Affero General Public License
14# along with this program. If not, see <http://www.gnu.org/licenses/>.
15
16from django.db import models
17
18
19class SourcePackage(models.Model):
20 class Meta:
21 db_table = "sourcepackage"
22
23 name = models.CharField(max_length=4096)
24
25 def __unicode__(self):
26 return self.name
27
28
29class BinaryPackage(models.Model):
30 class Meta:
31 db_table = "binarypackage"
32
33 name = models.CharField(max_length=4096)
34 sourcepackage = models.ForeignKey("SourcePackage")
35 seeded = models.BooleanField(default=False)
36
37 def __unicode__(self):
38 return self.name
039
=== added file 'ticket_system/project/tests.py'
--- ticket_system/project/tests.py 1970-01-01 00:00:00 +0000
+++ ticket_system/project/tests.py 2013-12-09 19:42:24 +0000
@@ -0,0 +1,136 @@
1# Ubuntu Continuous Integration Engine
2# Copyright 2013 Canonical Ltd.
3
4# This program is free software: you can redistribute it and/or modify it
5# under the terms of the GNU Affero General Public License version 3, as
6# published by the Free Software Foundation.
7
8# This program is distributed in the hope that it will be useful, but
9# WITHOUT ANY WARRANTY; without even the implied warranties of
10# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
11# PURPOSE. See the GNU Affero General Public License for more details.
12
13# You should have received a copy of the GNU Affero General Public License
14# along with this program. If not, see <http://www.gnu.org/licenses/>.
15
16from django.test import TestCase
17from tastypie.test import ResourceTestCase
18from project.models import SourcePackage, BinaryPackage
19
20
21def create_sourcepackage(name="awesome-package"):
22 package = SourcePackage()
23 package.name = name
24 package.save()
25 return package
26
27
28def create_binarypackage(name="awesome-binary", sourcepackage=None,
29 seeded=False):
30 binary = BinaryPackage()
31 binary.name = name
32 binary.sourcepackage = sourcepackage
33 binary.seeded = seeded
34 binary.save()
35 return binary
36
37
38class SourcePackageModelTest(TestCase):
39
40 def test_creating_a_sourcepackage(self):
41 package = create_sourcepackage()
42 package_in_database = SourcePackage.objects.all()
43 self.assertEquals(len(package_in_database), 1)
44 only_package_in_database = package_in_database[0]
45 self.assertEquals(only_package_in_database, package)
46
47 self.assertEquals(only_package_in_database.name, "awesome-package")
48
49
50class BinaryPackageModelTest(TestCase):
51
52 def setUp(self):
53 self.sourcepackage = create_sourcepackage()
54 self.binarypackage = create_binarypackage(
55 sourcepackage=self.sourcepackage)
56
57 def test_creating_a_binarypackage(self):
58 binarypackage_in_database = BinaryPackage.objects.all()
59 self.assertEquals(len(binarypackage_in_database), 1)
60 only_binarypackage_in_database = binarypackage_in_database[0]
61 self.assertEquals(only_binarypackage_in_database, self.binarypackage)
62
63 self.assertEquals(only_binarypackage_in_database.name,
64 "awesome-binary")
65
66
67class SourcePackageResourceTest(ResourceTestCase):
68
69 def setUp(self):
70 super(SourcePackageResourceTest, self).setUp()
71 create_sourcepackage()
72 self.sourcepackage_1 = SourcePackage.objects.get(
73 name='awesome-package')
74 self.detail_url = '/api/v1/sourcepackage/{0}/'.format(
75 self.sourcepackage_1.pk)
76
77 def test_get_sourcepackage_list_json(self):
78 resp = self.api_client.get('/api/v1/sourcepackage/', format='json')
79 self.assertValidJSONResponse(resp)
80 self.assertEqual(len(self.deserialize(resp)['objects']), 1)
81 self.assertEqual(self.deserialize(resp)['objects'][0], {
82 u'id': self.sourcepackage_1.pk,
83 u'name': u'awesome-package',
84 u'resource_uri': u'/api/v1/sourcepackage/{0}/'.format(
85 self.sourcepackage_1.pk)
86 })
87
88 def test_get_sourcepackage_detail_json(self):
89 resp = self.api_client.get(self.detail_url)
90 self.assertValidJSONResponse(resp)
91
92 # We use ``assertKeys`` here to just verify the keys, not all the data.
93 self.assertKeys(self.deserialize(resp),
94 ['id', 'name', 'resource_uri'])
95 self.assertEqual(self.deserialize(resp)['name'], 'awesome-package')
96
97
98class BinaryPackageResourceTest(ResourceTestCase):
99
100 def setUp(self):
101 super(BinaryPackageResourceTest, self).setUp()
102 create_sourcepackage()
103 self.sourcepackage_1 = SourcePackage.objects.get(
104 name='awesome-package')
105 create_binarypackage(sourcepackage=self.sourcepackage_1)
106 self.binarypackage_1 = BinaryPackage.objects.get(
107 name='awesome-binary')
108 self.detail_url = '/api/v1/binarypackage/{0}/'.format(
109 self.binarypackage_1.pk)
110
111 def test_get_binarypackage_list_json(self):
112 resp = self.api_client.get('/api/v1/binarypackage/', format='json')
113 self.assertValidJSONResponse(resp)
114 self.assertEqual(len(self.deserialize(resp)['objects']), 1)
115 self.assertEqual(self.deserialize(resp)['objects'][0], {
116 u'id': self.binarypackage_1.pk,
117 u'name': u'awesome-binary',
118 u'seeded': False,
119 u'sourcepackage': {
120 u'id': self.sourcepackage_1.pk,
121 u'name': u'awesome-package',
122 u'resource_uri': u'/api/v1/sourcepackage/{0}/'.format(
123 self.sourcepackage_1.pk)},
124 u'resource_uri': u'/api/v1/binarypackage/{0}/'.format(
125 self.binarypackage_1.pk)
126 })
127
128 def test_get_binarypackage_detail_json(self):
129 resp = self.api_client.get(self.detail_url)
130 self.assertValidJSONResponse(resp)
131
132 # We use ``assertKeys`` here to just verify the keys, not all the data.
133 self.assertKeys(self.deserialize(resp),
134 ['id', 'name', 'resource_uri', 'seeded',
135 'sourcepackage'])
136 self.assertEqual(self.deserialize(resp)['name'], 'awesome-binary')
0137
=== modified file 'ticket_system/ticket_system/settings.py'
--- ticket_system/ticket_system/settings.py 2013-12-09 17:43:12 +0000
+++ ticket_system/ticket_system/settings.py 2013-12-09 19:42:24 +0000
@@ -140,6 +140,7 @@
140140
141LOCAL_APPS = (141LOCAL_APPS = (
142 'people',142 'people',
143 'project',
143)144)
144145
145INSTALLED_APPS = LOCAL_APPS + INSTALLED_APPS146INSTALLED_APPS = LOCAL_APPS + INSTALLED_APPS
146147
=== modified file 'ticket_system/ticket_system/urls.py'
--- ticket_system/ticket_system/urls.py 2013-12-09 17:43:12 +0000
+++ ticket_system/ticket_system/urls.py 2013-12-09 19:42:24 +0000
@@ -17,10 +17,13 @@
17from django.contrib import admin17from django.contrib import admin
18from tastypie.api import Api18from tastypie.api import Api
19from people.api import PersonResource19from people.api import PersonResource
20from project.api import SourcePackageResource, BinaryPackageResource
2021
21admin.autodiscover()22admin.autodiscover()
22v1_api = Api(api_name='v1')23v1_api = Api(api_name='v1')
23v1_api.register(PersonResource())24v1_api.register(PersonResource())
25v1_api.register(SourcePackageResource())
26v1_api.register(BinaryPackageResource())
2427
25urlpatterns = patterns(28urlpatterns = patterns(
26 '',29 '',

Subscribers

People subscribed via source and target branches