diff --git a/issue/fixtures/test_perms.json b/issue/fixtures/test_perms.json new file mode 100644 index 0000000..5af24e5 --- /dev/null +++ b/issue/fixtures/test_perms.json @@ -0,0 +1 @@ +[{"pk": 1, "model": "contenttypes.contenttype", "fields": {"model": "logentry", "name": "log entry", "app_label": "admin"}}, {"pk": 2, "model": "contenttypes.contenttype", "fields": {"model": "permission", "name": "permission", "app_label": "auth"}}, {"pk": 3, "model": "contenttypes.contenttype", "fields": {"model": "group", "name": "group", "app_label": "auth"}}, {"pk": 4, "model": "contenttypes.contenttype", "fields": {"model": "user", "name": "user", "app_label": "auth"}}, {"pk": 5, "model": "contenttypes.contenttype", "fields": {"model": "contenttype", "name": "content type", "app_label": "contenttypes"}}, {"pk": 6, "model": "contenttypes.contenttype", "fields": {"model": "session", "name": "session", "app_label": "sessions"}}, {"pk": 7, "model": "contenttypes.contenttype", "fields": {"model": "site", "name": "site", "app_label": "sites"}}, {"pk": 8, "model": "contenttypes.contenttype", "fields": {"model": "project", "name": "project", "app_label": "issue"}}, {"pk": 9, "model": "contenttypes.contenttype", "fields": {"model": "label", "name": "label", "app_label": "issue"}}, {"pk": 10, "model": "contenttypes.contenttype", "fields": {"model": "milestone", "name": "milestone", "app_label": "issue"}}, {"pk": 11, "model": "contenttypes.contenttype", "fields": {"model": "issue", "name": "issue", "app_label": "issue"}}, {"pk": 12, "model": "contenttypes.contenttype", "fields": {"model": "event", "name": "event", "app_label": "issue"}}, {"pk": 13, "model": "contenttypes.contenttype", "fields": {"model": "settings", "name": "settings", "app_label": "issue"}}, {"pk": 14, "model": "contenttypes.contenttype", "fields": {"model": "team", "name": "team", "app_label": "issue"}}, {"pk": 15, "model": "contenttypes.contenttype", "fields": {"model": "globalpermission", "name": "global permission", "app_label": "issue"}}, {"pk": 16, "model": "contenttypes.contenttype", "fields": {"model": "projectpermission", "name": "project permission", "app_label": "issue"}}, {"pk": 17, "model": "contenttypes.contenttype", "fields": {"model": "user", "name": "user", "app_label": "issue"}}, {"pk": "pqd4c9l1pxxcglphnell7nj10nwgxhv5", "model": "sessions.session", "fields": {"expire_date": "2014-08-22T21:39:30.632Z", "session_data": "ODAwMGQyMTQzZWRmOTQxYWM5NzhhZTRkYmMxZjIyYTU1YWJiMDg4Zjp7Il9hdXRoX3VzZXJfYmFja2VuZCI6ImRqYW5nby5jb250cmliLmF1dGguYmFja2VuZHMuTW9kZWxCYWNrZW5kIiwiX2F1dGhfdXNlcl9pZCI6MywiX2F1dGhfdXNlcl9oYXNoIjoiNGJlYzJmNzMyZTI5MmY5ZGFlYTZmNGFhYTc0MDI5NjExOGE0ZmQzMCJ9"}}, {"pk": "ulbl2kkyz1mmstv1obcb2isxzxbd40pb", "model": "sessions.session", "fields": {"expire_date": "2014-08-22T21:16:54.042Z", "session_data": "ODAwMGQyMTQzZWRmOTQxYWM5NzhhZTRkYmMxZjIyYTU1YWJiMDg4Zjp7Il9hdXRoX3VzZXJfYmFja2VuZCI6ImRqYW5nby5jb250cmliLmF1dGguYmFja2VuZHMuTW9kZWxCYWNrZW5kIiwiX2F1dGhfdXNlcl9pZCI6MywiX2F1dGhfdXNlcl9oYXNoIjoiNGJlYzJmNzMyZTI5MmY5ZGFlYTZmNGFhYTc0MDI5NjExOGE0ZmQzMCJ9"}}, {"pk": "xkl50v01skood5nezx6zhg3bfwruxhi2", "model": "sessions.session", "fields": {"expire_date": "2014-08-22T16:41:38.940Z", "session_data": "ZWExYjgwZmIyZTIxNGU4Y2RjOWJiMDc0NWJmMWI4Yjk0OTE2YjE3MDp7Il9hdXRoX3VzZXJfYmFja2VuZCI6ImRqYW5nby5jb250cmliLmF1dGguYmFja2VuZHMuTW9kZWxCYWNrZW5kIiwiX2F1dGhfdXNlcl9pZCI6MSwiX2F1dGhfdXNlcl9oYXNoIjoiYTMzMjc1MjY4NjdjNDFiYzM1MmVjNzcxMWMxMzlmMzRkZThkOTVlZCJ9"}}, {"pk": 1, "model": "sites.site", "fields": {"domain": "example.com", "name": "example.com"}}, {"pk": "project-1", "model": "issue.project", "fields": {"display_name": "Project 1", "description": "This is a public project.", "public": true}}, {"pk": "project-2", "model": "issue.project", "fields": {"display_name": "Project 2", "description": "This is a private project.", "public": false}}, {"pk": 1, "model": "issue.label", "fields": {"project": "project-1", "deleted": false, "name": "bug", "color": "#FF0000", "inverted": true}}, {"pk": 2, "model": "issue.label", "fields": {"project": "project-1", "deleted": false, "name": "feature", "color": "#00A000", "inverted": true}}, {"pk": 3, "model": "issue.label", "fields": {"project": "project-1", "deleted": false, "name": "documentation", "color": "#1D3DBE", "inverted": true}}, {"pk": 4, "model": "issue.label", "fields": {"project": "project-2", "deleted": false, "name": "bug", "color": "#FF0000", "inverted": true}}, {"pk": 5, "model": "issue.label", "fields": {"project": "project-2", "deleted": false, "name": "feature", "color": "#00A000", "inverted": true}}, {"pk": 6, "model": "issue.label", "fields": {"project": "project-2", "deleted": false, "name": "documentation", "color": "#1D3DBE", "inverted": true}}, {"pk": 1, "model": "issue.globalpermission", "fields": {"create_project": true, "grantee_name": "user3", "manage_permission": false, "manage_team": false, "delete_project": false, "grantee_type": 0, "modify_project": false, "add_team": true}}, {"pk": 4, "model": "issue.globalpermission", "fields": {"create_project": false, "grantee_name": "group1", "manage_permission": false, "manage_team": false, "delete_project": false, "grantee_type": 1, "modify_project": true, "add_team": true}}, {"pk": 5, "model": "issue.globalpermission", "fields": {"create_project": false, "grantee_name": "team1", "manage_permission": false, "manage_team": false, "delete_project": true, "grantee_type": 2, "modify_project": false, "add_team": true}}, {"pk": 1, "model": "issue.projectpermission", "fields": {"create_issue": true, "grantee_name": "user3", "modify_label": false, "create_comment": false, "delete_milestone": false, "modify_comment": false, "delete_comment": false, "project": "project-1", "modify_milestone": false, "modify_issue": false, "create_milestone": false, "delete_issue": false, "create_label": false, "delete_label": false, "grantee_type": 0}}, {"pk": 2, "model": "issue.projectpermission", "fields": {"create_issue": false, "grantee_name": "group1", "modify_label": false, "create_comment": false, "delete_milestone": false, "modify_comment": false, "delete_comment": false, "project": "project-1", "modify_milestone": false, "modify_issue": true, "create_milestone": false, "delete_issue": false, "create_label": false, "delete_label": false, "grantee_type": 1}}, {"pk": 3, "model": "issue.projectpermission", "fields": {"create_issue": false, "grantee_name": "team1", "modify_label": false, "create_comment": false, "delete_milestone": false, "modify_comment": false, "delete_comment": false, "project": "project-1", "modify_milestone": false, "modify_issue": false, "create_milestone": false, "delete_issue": true, "create_label": false, "delete_label": false, "grantee_type": 2}}, {"pk": 4, "model": "issue.projectpermission", "fields": {"create_issue": false, "grantee_name": "user2", "modify_label": false, "create_comment": false, "delete_milestone": false, "modify_comment": false, "delete_comment": false, "project": "project-2", "modify_milestone": false, "modify_issue": false, "create_milestone": false, "delete_issue": false, "create_label": false, "delete_label": false, "grantee_type": 0}}, {"pk": 1, "model": "auth.permission", "fields": {"codename": "add_logentry", "name": "Can add log entry", "content_type": 1}}, {"pk": 2, "model": "auth.permission", "fields": {"codename": "change_logentry", "name": "Can change log entry", "content_type": 1}}, {"pk": 3, "model": "auth.permission", "fields": {"codename": "delete_logentry", "name": "Can delete log entry", "content_type": 1}}, {"pk": 4, "model": "auth.permission", "fields": {"codename": "add_permission", "name": "Can add permission", "content_type": 2}}, {"pk": 5, "model": "auth.permission", "fields": {"codename": "change_permission", "name": "Can change permission", "content_type": 2}}, {"pk": 6, "model": "auth.permission", "fields": {"codename": "delete_permission", "name": "Can delete permission", "content_type": 2}}, {"pk": 7, "model": "auth.permission", "fields": {"codename": "add_group", "name": "Can add group", "content_type": 3}}, {"pk": 8, "model": "auth.permission", "fields": {"codename": "change_group", "name": "Can change group", "content_type": 3}}, {"pk": 9, "model": "auth.permission", "fields": {"codename": "delete_group", "name": "Can delete group", "content_type": 3}}, {"pk": 10, "model": "auth.permission", "fields": {"codename": "add_user", "name": "Can add user", "content_type": 4}}, {"pk": 11, "model": "auth.permission", "fields": {"codename": "change_user", "name": "Can change user", "content_type": 4}}, {"pk": 12, "model": "auth.permission", "fields": {"codename": "delete_user", "name": "Can delete user", "content_type": 4}}, {"pk": 13, "model": "auth.permission", "fields": {"codename": "add_contenttype", "name": "Can add content type", "content_type": 5}}, {"pk": 14, "model": "auth.permission", "fields": {"codename": "change_contenttype", "name": "Can change content type", "content_type": 5}}, {"pk": 15, "model": "auth.permission", "fields": {"codename": "delete_contenttype", "name": "Can delete content type", "content_type": 5}}, {"pk": 16, "model": "auth.permission", "fields": {"codename": "add_session", "name": "Can add session", "content_type": 6}}, {"pk": 17, "model": "auth.permission", "fields": {"codename": "change_session", "name": "Can change session", "content_type": 6}}, {"pk": 18, "model": "auth.permission", "fields": {"codename": "delete_session", "name": "Can delete session", "content_type": 6}}, {"pk": 19, "model": "auth.permission", "fields": {"codename": "add_site", "name": "Can add site", "content_type": 7}}, {"pk": 20, "model": "auth.permission", "fields": {"codename": "change_site", "name": "Can change site", "content_type": 7}}, {"pk": 21, "model": "auth.permission", "fields": {"codename": "delete_site", "name": "Can delete site", "content_type": 7}}, {"pk": 22, "model": "auth.permission", "fields": {"codename": "add_project", "name": "Can add project", "content_type": 8}}, {"pk": 23, "model": "auth.permission", "fields": {"codename": "change_project", "name": "Can change project", "content_type": 8}}, {"pk": 24, "model": "auth.permission", "fields": {"codename": "delete_project", "name": "Can delete project", "content_type": 8}}, {"pk": 25, "model": "auth.permission", "fields": {"codename": "add_label", "name": "Can add label", "content_type": 9}}, {"pk": 26, "model": "auth.permission", "fields": {"codename": "change_label", "name": "Can change label", "content_type": 9}}, {"pk": 27, "model": "auth.permission", "fields": {"codename": "delete_label", "name": "Can delete label", "content_type": 9}}, {"pk": 28, "model": "auth.permission", "fields": {"codename": "add_milestone", "name": "Can add milestone", "content_type": 10}}, {"pk": 29, "model": "auth.permission", "fields": {"codename": "change_milestone", "name": "Can change milestone", "content_type": 10}}, {"pk": 30, "model": "auth.permission", "fields": {"codename": "delete_milestone", "name": "Can delete milestone", "content_type": 10}}, {"pk": 31, "model": "auth.permission", "fields": {"codename": "add_issue", "name": "Can add issue", "content_type": 11}}, {"pk": 32, "model": "auth.permission", "fields": {"codename": "change_issue", "name": "Can change issue", "content_type": 11}}, {"pk": 33, "model": "auth.permission", "fields": {"codename": "delete_issue", "name": "Can delete issue", "content_type": 11}}, {"pk": 34, "model": "auth.permission", "fields": {"codename": "add_event", "name": "Can add event", "content_type": 12}}, {"pk": 35, "model": "auth.permission", "fields": {"codename": "change_event", "name": "Can change event", "content_type": 12}}, {"pk": 36, "model": "auth.permission", "fields": {"codename": "delete_event", "name": "Can delete event", "content_type": 12}}, {"pk": 37, "model": "auth.permission", "fields": {"codename": "add_settings", "name": "Can add settings", "content_type": 13}}, {"pk": 38, "model": "auth.permission", "fields": {"codename": "change_settings", "name": "Can change settings", "content_type": 13}}, {"pk": 39, "model": "auth.permission", "fields": {"codename": "delete_settings", "name": "Can delete settings", "content_type": 13}}, {"pk": 40, "model": "auth.permission", "fields": {"codename": "add_team", "name": "Can add team", "content_type": 14}}, {"pk": 41, "model": "auth.permission", "fields": {"codename": "change_team", "name": "Can change team", "content_type": 14}}, {"pk": 42, "model": "auth.permission", "fields": {"codename": "delete_team", "name": "Can delete team", "content_type": 14}}, {"pk": 43, "model": "auth.permission", "fields": {"codename": "add_globalpermission", "name": "Can add global permission", "content_type": 15}}, {"pk": 44, "model": "auth.permission", "fields": {"codename": "change_globalpermission", "name": "Can change global permission", "content_type": 15}}, {"pk": 45, "model": "auth.permission", "fields": {"codename": "delete_globalpermission", "name": "Can delete global permission", "content_type": 15}}, {"pk": 46, "model": "auth.permission", "fields": {"codename": "add_projectpermission", "name": "Can add project permission", "content_type": 16}}, {"pk": 47, "model": "auth.permission", "fields": {"codename": "change_projectpermission", "name": "Can change project permission", "content_type": 16}}, {"pk": 48, "model": "auth.permission", "fields": {"codename": "delete_projectpermission", "name": "Can delete project permission", "content_type": 16}}, {"pk": 1, "model": "auth.group", "fields": {"name": "group1", "permissions": []}}, {"pk": 1, "model": "auth.user", "fields": {"username": "admin", "first_name": "", "last_name": "", "is_active": true, "is_superuser": true, "is_staff": true, "last_login": "2014-08-08T21:34:26.790Z", "groups": [], "user_permissions": [], "password": "pbkdf2_sha256$12000$qy5asFJAVx57$RneUin16DMOU6PIIdctZqjtUa0PjE2yDIiGAXg3qteI=", "email": "", "date_joined": "2014-08-08T16:41:05.033Z"}}, {"pk": 2, "model": "auth.user", "fields": {"username": "user1", "first_name": "", "last_name": "", "is_active": true, "is_superuser": false, "is_staff": false, "last_login": "2014-08-08T16:42:31Z", "groups": [], "user_permissions": [], "password": "pbkdf2_sha256$12000$drENNTEqIkBE$2GqTBGncULxAw9bLc6vyta1p/uJGFYuU0zrurDK77nI=", "email": "", "date_joined": "2014-08-08T16:42:31Z"}}, {"pk": 3, "model": "auth.user", "fields": {"username": "user2", "first_name": "", "last_name": "", "is_active": true, "is_superuser": false, "is_staff": false, "last_login": "2014-08-08T21:39:30.498Z", "groups": [1], "user_permissions": [], "password": "pbkdf2_sha256$12000$3EduBVRie3iD$qHAbiBebSQq7RlJogSxeoWlinw8w7bcSXdOgn3WiyeM=", "email": "", "date_joined": "2014-08-08T18:26:40Z"}}, {"pk": 4, "model": "auth.user", "fields": {"username": "user3", "first_name": "", "last_name": "", "is_active": true, "is_superuser": false, "is_staff": false, "last_login": "2014-08-08T18:27:04Z", "groups": [], "user_permissions": [], "password": "pbkdf2_sha256$12000$9ReiA9Yfsiu2$o+T1rHBTb1wFYIbzDoGliOFhqdHMvvLyOAk80JQnCeg=", "email": "", "date_joined": "2014-08-08T18:27:04Z"}}, {"pk": 5, "model": "auth.user", "fields": {"username": "user4", "first_name": "", "last_name": "", "is_active": true, "is_superuser": false, "is_staff": false, "last_login": "2014-08-08T18:54:24.705Z", "groups": [], "user_permissions": [], "password": "pbkdf2_sha256$12000$V83PwKTT9uhM$E+uXxLKQ7nmrDnJH+b/+MSp8jfkMkH0UxOZjqSjHJw4=", "email": "", "date_joined": "2014-08-08T18:54:24.705Z"}}, {"pk": 1, "model": "issue.team", "fields": {"name": "team1", "groups": [], "users": [2]}}, {"pk": 2, "model": "issue.team", "fields": {"name": "team2", "groups": [1], "users": []}}, {"pk": 1, "model": "admin.logentry", "fields": {"action_flag": 1, "action_time": "2014-08-08T16:42:31.376Z", "object_repr": "user1", "object_id": "2", "change_message": "", "user": 1, "content_type": 4}}, {"pk": 2, "model": "admin.logentry", "fields": {"action_flag": 1, "action_time": "2014-08-08T18:26:25.358Z", "object_repr": "group1", "object_id": "1", "change_message": "", "user": 1, "content_type": 3}}, {"pk": 3, "model": "admin.logentry", "fields": {"action_flag": 1, "action_time": "2014-08-08T18:26:40.841Z", "object_repr": "user2", "object_id": "3", "change_message": "", "user": 1, "content_type": 4}}, {"pk": 4, "model": "admin.logentry", "fields": {"action_flag": 1, "action_time": "2014-08-08T18:26:44.875Z", "object_repr": "team1", "object_id": "1", "change_message": "", "user": 1, "content_type": 14}}, {"pk": 5, "model": "admin.logentry", "fields": {"action_flag": 1, "action_time": "2014-08-08T18:26:53.220Z", "object_repr": "team2", "object_id": "2", "change_message": "", "user": 1, "content_type": 14}}, {"pk": 6, "model": "admin.logentry", "fields": {"action_flag": 1, "action_time": "2014-08-08T18:27:04.108Z", "object_repr": "user3", "object_id": "4", "change_message": "", "user": 1, "content_type": 4}}, {"pk": 7, "model": "admin.logentry", "fields": {"action_flag": 2, "action_time": "2014-08-08T18:27:15.492Z", "object_repr": "user3", "object_id": "4", "change_message": "Changed groups.", "user": 1, "content_type": 4}}, {"pk": 8, "model": "admin.logentry", "fields": {"action_flag": 2, "action_time": "2014-08-08T18:34:58.697Z", "object_repr": "team1", "object_id": "1", "change_message": "Changed users.", "user": 1, "content_type": 14}}, {"pk": 9, "model": "admin.logentry", "fields": {"action_flag": 2, "action_time": "2014-08-08T18:35:14.882Z", "object_repr": "user3", "object_id": "4", "change_message": "Changed groups.", "user": 1, "content_type": 4}}, {"pk": 10, "model": "admin.logentry", "fields": {"action_flag": 2, "action_time": "2014-08-08T18:35:20.072Z", "object_repr": "user1", "object_id": "2", "change_message": "Changed groups.", "user": 1, "content_type": 4}}, {"pk": 11, "model": "admin.logentry", "fields": {"action_flag": 2, "action_time": "2014-08-08T18:36:02.040Z", "object_repr": "user1", "object_id": "2", "change_message": "Changed groups.", "user": 1, "content_type": 4}}, {"pk": 12, "model": "admin.logentry", "fields": {"action_flag": 2, "action_time": "2014-08-08T18:36:10.947Z", "object_repr": "team1", "object_id": "1", "change_message": "No fields changed.", "user": 1, "content_type": 14}}, {"pk": 13, "model": "admin.logentry", "fields": {"action_flag": 2, "action_time": "2014-08-08T18:36:24.856Z", "object_repr": "user2", "object_id": "3", "change_message": "Changed groups.", "user": 1, "content_type": 4}}, {"pk": 14, "model": "admin.logentry", "fields": {"action_flag": 2, "action_time": "2014-08-08T18:36:30.902Z", "object_repr": "team2", "object_id": "2", "change_message": "No fields changed.", "user": 1, "content_type": 14}}, {"pk": 15, "model": "admin.logentry", "fields": {"action_flag": 2, "action_time": "2014-08-08T18:37:56.866Z", "object_repr": "team1", "object_id": "1", "change_message": "No fields changed.", "user": 1, "content_type": 14}}, {"pk": 16, "model": "admin.logentry", "fields": {"action_flag": 1, "action_time": "2014-08-08T18:54:24.771Z", "object_repr": "user4", "object_id": "5", "change_message": "", "user": 1, "content_type": 4}}] \ No newline at end of file diff --git a/issue/tests.py b/issue/tests.py index 7ce503c..93922d8 100644 --- a/issue/tests.py +++ b/issue/tests.py @@ -1,3 +1,98 @@ -from django.test import TestCase +from django.test import TestCase, Client -# Create your tests here. +from issue.models import * + + +class TestPermissions(TestCase): + + fixtures = ['test_perms'] + + def test_team_user_membership(self): + user = User.objects.get(username='user1') + team = Team.objects.get(name='team1') + self.assertEqual(len(user.teams), 1) + self.assertEqual(user.teams[0], team) + + def test_team_group_membership(self): + user = User.objects.get(username='user2') + team = Team.objects.get(name='team2') + self.assertEqual(len(user.teams), 1) + self.assertEqual(user.teams[0], team) + + def test_global_no_perms(self): + user = User.objects.get(username='user4') + self.assertFalse(user.has_perm('create_project')) + self.assertFalse(user.has_perm('modify_project')) + self.assertFalse(user.has_perm('delete_project')) + + def test_global_user_perms(self): + user = User.objects.get(username='user3') + self.assertTrue(user.has_perm('create_project')) + self.assertFalse(user.has_perm('modify_project')) + self.assertFalse(user.has_perm('delete_project')) + + def test_global_group_perms(self): + user = User.objects.get(username='user2') + self.assertFalse(user.has_perm('create_project')) + self.assertTrue(user.has_perm('modify_project')) + self.assertFalse(user.has_perm('delete_project')) + + def test_global_team_perms(self): + user = User.objects.get(username='user1') + self.assertFalse(user.has_perm('create_project')) + self.assertFalse(user.has_perm('modify_project')) + self.assertTrue(user.has_perm('delete_project')) + + def test_project_no_perms(self): + user = User.objects.get(username='user4') + project = Project.objects.get(name='project-1') + self.assertFalse(user.has_perm('create_issue', project)) + self.assertFalse(user.has_perm('modify_issue', project)) + self.assertFalse(user.has_perm('delete_issue', project)) + + def test_project_user_perms(self): + user = User.objects.get(username='user3') + project = Project.objects.get(name='project-1') + self.assertTrue(user.has_perm('create_issue', project)) + self.assertFalse(user.has_perm('modify_issue', project)) + self.assertFalse(user.has_perm('delete_issue', project)) + + def test_project_group_perms(self): + user = User.objects.get(username='user2') + project = Project.objects.get(name='project-1') + self.assertFalse(user.has_perm('create_issue', project)) + self.assertTrue(user.has_perm('modify_issue', project)) + self.assertFalse(user.has_perm('delete_issue', project)) + + def test_project_team_perms(self): + user = User.objects.get(username='user1') + project = Project.objects.get(name='project-1') + self.assertFalse(user.has_perm('create_issue', project)) + self.assertFalse(user.has_perm('modify_issue', project)) + self.assertTrue(user.has_perm('delete_issue', project)) + + def test_unregistered_project_list(self): + response = self.client.get('/') + projects = response.context['projects'] + project = Project.objects.get(name='project-1') + self.assertEqual(len(projects), 1) + self.assertEqual(projects[0], project) + + def test_ungranted_project_list(self): + self.client.login(username='user1', password='user1') + response = self.client.get('/') + projects = response.context['projects'] + project = Project.objects.get(name='project-1') + self.assertEqual(len(projects), 1) + self.assertEqual(projects[0], project) + self.client.logout() + + def test_granted_project_list(self): + self.client.login(username='user2', password='user2') + response = self.client.get('/') + projects = response.context['projects'] + project1 = Project.objects.get(name='project-1') + project2 = Project.objects.get(name='project-2') + self.assertEqual(len(projects), 2) + self.assertTrue(project1 in projects) + self.assertTrue(project2 in projects)