diff --git a/client/src/pages/project.vue b/client/src/pages/project.vue
index 21291be3..0765f7a3 100644
--- a/client/src/pages/project.vue
+++ b/client/src/pages/project.vue
@@ -13,7 +13,7 @@
@@ -23,6 +23,7 @@
import ProjectEntry from '@/components/portfolio/ProjectEntry';
import AddProjectEntry from '@/components/portfolio/AddProjectEntry';
+ import ME_QUERY from '@/graphql/gql/meQuery.gql';
import PROJECT_QUERY from '@/graphql/gql/projectQuery.gql';
export default {
@@ -40,7 +41,10 @@
specialContainerClass() {
const cls = this.project.appearance;
return [cls ? `project--${cls}` : ''];
- }
+ },
+ isOwner() {
+ return this.me.id === this.project.student.id;
+ }
},
apollo: {
@@ -56,12 +60,22 @@
this.$store.dispatch('setSpecialContainerClass', project.appearance);
return project;
}
+ },
+ me: {
+ query: ME_QUERY
}
},
data() {
return {
- project: {}
+ project: {
+ student: {
+ id: ' '
+ }
+ },
+ me: {
+ id: ''
+ }
}
},
diff --git a/server/portfolio/mutations.py b/server/portfolio/mutations.py
index 8e6dee3f..6bd4aa28 100644
--- a/server/portfolio/mutations.py
+++ b/server/portfolio/mutations.py
@@ -90,11 +90,17 @@ class MutateProjectEntry(relay.ClientIDMutation):
project_entry = graphene.Field(ProjectEntryNode)
@classmethod
- def mutate_and_get_payload(cls, *args, **kwargs):
+ def mutate_and_get_payload(cls, root, info, **kwargs):
data = kwargs.get('project_entry')
+ project = None
if data.get('project') is not None:
- data['project'] = get_object(Project, data.get('project')).id
+ project = get_object(Project, data.get('project'))
+ data['project'] = project.id
+
+ if info.context.user.id != project.student.id:
+ return cls(project_entry=None, errors=['not allowed'])
+
if data.get('id') is not None:
entity = get_object(ProjectEntry, data['id'])
serializer = ProjectEntrySerializer(entity, data=data, partial=True)
diff --git a/server/portfolio/tests/test_project_entry_mutations.py b/server/portfolio/tests/test_project_entry_mutations.py
new file mode 100644
index 00000000..092bd730
--- /dev/null
+++ b/server/portfolio/tests/test_project_entry_mutations.py
@@ -0,0 +1,64 @@
+from django.test import TestCase, RequestFactory
+from graphene.test import Client
+from graphql_relay import to_global_id
+
+from api.schema import schema
+from portfolio.factories import ProjectFactory
+from users.factories import SchoolClassFactory
+from users.models import User
+from users.services import create_users
+from api.test_utils import create_client, DefaultUserTestCase
+from portfolio.models import Project, ProjectEntry
+
+
+class ProjectMutationsTestCase(DefaultUserTestCase):
+
+ def setUp(self):
+ create_users()
+ self.teacher = User.objects.get(username='teacher')
+ self.teacher2 = User.objects.get(username='teacher2')
+ self.student = User.objects.get(username='student1')
+ self.student2 = User.objects.get(username='student2')
+ self.project1 = ProjectFactory(student=self.student)
+
+ self.mutation = '''
+ mutation AddProjectEntryMutation($input: AddProjectEntryInput!) {
+ addProjectEntry(input: $input) {
+ projectEntry {
+ id
+ activity
+ reflection
+ nextSteps
+ created
+ }
+ errors
+ }
+ }
+ '''
+
+ self.variables = {
+ 'input': {
+ 'projectEntry': {
+ 'project': to_global_id('ProjectNode', self.project1.id),
+ 'activity': 'testactivity',
+ 'nextSteps': 'teststep',
+ 'reflection': 'testreflection'
+ }
+ }
+ }
+
+ def test_add_project_entry(self):
+ client = create_client(self.student)
+ self.assertEqual(ProjectEntry.objects.count(), 0)
+ result = client.execute(self.mutation, variables=self.variables)
+ self.assertIsNone(result.get('errors'))
+ self.assertEqual(ProjectEntry.objects.count(), 1)
+ project_entry = ProjectEntry.objects.first()
+ self.assertEqual(project_entry.activity, 'testactivity')
+
+ def test_should_not_be_able_to_add_entry_as_other_person(self):
+ client = create_client(self.student2)
+ self.assertEqual(ProjectEntry.objects.count(), 0)
+ result = client.execute(self.mutation, variables=self.variables)
+ self.assertIsNone(result.get('errors'))
+ self.assertEqual(ProjectEntry.objects.count(), 0)