Commit ce15bef8 authored by Ola Hermann Opheim's avatar Ola Hermann Opheim
Browse files

Merge branch 'feat/edit_own_project' into 'master'

Edit project and tests for edit project and sorting

See merge request olahop/agreelance123!5
parents cb7ab366 a9778683
......@@ -10,30 +10,94 @@
{% block content %}
<h3 class="my-3">{{ project.title }}</h3>
<p>Project status: {{project.get_status_display}}</p>
<p>Project total budget: {{total_budget}}</p>
<h3>Description</h3>
<p class="project-description">{{ project.description }}</p>
<h4>Category: {{project.category}}</h4>
{% if user == project.user.user %}
{% if project.edit %}
<form method="post">
{% csrf_token %}
<button class="btn btn-primary" name="edit_project" type="submit">Save</button>
<p>Project status: {{project.get_status_display}}</p>
<p>Project total budget: {{total_budget}}</p>
<h3>Description</h3>
<textarea
type="text"
name="project_description"
required
maxlength="500"
class="form-control"
>{{ project.description }}</textarea>
<h4>Category: {{project.category}}</h4>
{% if user.is_authenticated %}
{% if project.status == project.OPEN %}
<h3 class="my-3">Tasks:</h3>
<div id="task_container">
{% for task in tasks %}
<div class="task">
<h4>{{task.title}}</h4>
Budget:
<textarea
type="number"
min = "0"
name="task{{task.id}}_budget"
required
maxlength="200"
class="form-control"
>{{ task.id }}</textarea>
Description:
<textarea
type="text"
name="task{{task.id}}_description"
required
maxlength="500"
class="form-control"
>{{task.description}}</textarea>
</div>
{% endfor %}
</div>
{% endif %}
{% endif %}
</form>
{% else %}
<form method="post">
{% csrf_token %}
<button class="btn btn-primary" name="edit_project" type="submit">Edit</button>
<p>Project status: {{project.get_status_display}}</p>
<p>Project total budget: {{total_budget}}</p>
<h3>Description</h3>
<p class="project-description">{{ project.description }}</p>
<h4>Category: {{project.category}}</h4>
{% if user.is_authenticated %}
{% if project.status == project.OPEN %}
<h3 class="my-3">Tasks:</h3>
<div id="task_container">
{% for task in tasks %}
<div class="task">
<h4>{{task.title}}</h4>
<p>Budget: {{task.budget}} </p>
<p>Description: <br> {{task.description}}</p>
</div>
{% endfor %}
</div>
{% endif %}
{% endif %}
</form>
{% endif %}
{% endif %}
{% if user.is_authenticated %}
{% if user == project.user.user %}
{% if project.status == project.OPEN %}
<h3 class="my-3">Tasks:</h3>
<div id="task_container">
{% for task in tasks %}
<div class="task">
<h4>{{task.title}}</h4>
<p>Budget: {{task.budget}} </p>
<p>Description: <br> {{task.description}}</p>
</div>
{% endfor %}
</div>
{% for task in tasks %}
{% define task|get_all_taskoffers as task_offers %}
......
......@@ -18,6 +18,12 @@ class ProjectForm(forms.ModelForm):
model = Project
fields = ('title', 'description', 'category_id')
class EditProjectForm(forms.ModelForm):
class Meta:
model = Project
fields = ('edit',)
class TaskFileForm(forms.ModelForm):
file = forms.FileField()
......
# Generated by Django 2.1.7 on 2020-03-05 10:20
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('projects', '0003_projects'),
]
operations = [
migrations.AddField(
model_name='project',
name='edit',
field=models.BooleanField(default=False),
),
]
......@@ -60,7 +60,7 @@ class Project(models.Model):
description = models.TextField(max_length=500)
participants = models.ManyToManyField(Profile, related_name='project_participants')
category = models.ForeignKey(ProjectCategory, on_delete=models.CASCADE, related_name='project_category')
edit = models.BooleanField(default=False)
OPEN = 'o'
INPROG = 'i'
FINISHED = 'f'
......
......@@ -58,25 +58,32 @@ class ProjectTest(unittest.TestCase):
})
# Test project_view POST route offer response
taskofferid = get_all_taskoffers(self.testTask)[0].id
self.client.login(username= 'Owner', password= 'top_secret')
self.client.post('/projects/' + str(Project.objects.last().pk) + '/', {
'offer_response': True,
'taskofferid': taskofferid,
'taskofferid': 0,
'status': 'a',
'feedback': 'ja',
})
# Test project_view POST route edit project
self.client.post('/projects/' + str(Project.objects.last().pk) + '/', {
'edit_project': True,
#'edit': True,
})
self.client.post('/projects/' + str(Project.objects.last().pk) + '/', {
'edit_project': True,
'project_description': 'edited',
f'task{self.testTask.id}_budget': '100',
f'task{self.testTask.id}_description': 'edited',
})
# Test project_view POST route status change
self.client.post('/projects/' + str(Project.objects.last().pk) + '/', {
'status_change': True,
'status': 'o',
})
def test_edit_project_integration(self):
#TODO
self.assertTrue(True)
class UserTaskPermissionTest(unittest.TestCase):
def setUp(self):
self.client = Client()
......@@ -129,10 +136,9 @@ class UserTaskPermissionTest(unittest.TestCase):
'taskvalue': Project.objects.last().pk,
})
self.client.login(username= 'Owner2', password= 'top_secret')
taskofferid = get_all_taskoffers(self.testTask2)[0].id
response = self.client.post('/projects/' + str(Project.objects.last().pk) + '/', {
'offer_response': True,
'taskofferid': taskofferid,
'taskofferid': 0,
'status': 'a',
'feedback': 'ja',
})
......@@ -142,14 +148,119 @@ class SortingTest(unittest.TestCase):
def setUp(self):
self.client = Client()
self.sorting_category = ProjectCategory.objects.create(name='sorting_category')
self.user_a = User.objects.create_user(
username='aUser',
email='test@test.com',
password='top_secret'
)
self.user_b = User.objects.create_user(
username='bUser',
email='test@test.com',
password='top_secret'
)
self.user_c = User.objects.create_user(
username='cUser',
email='test@test.com',
password='top_secret'
)
Project.objects.all().delete()
self.project_a = Project.objects.create(
user=self.user_c.profile,
title='A Project',
description='',
category=self.sorting_category,
status='o'
)
self.project_c = Project.objects.create(
user=self.user_b.profile,
title='C Project',
description='',
category=self.sorting_category,
status='o'
)
self.project_b = Project.objects.create(
user=self.user_a.profile,
title='B Project',
description='',
category=self.sorting_category,
status='o'
)
self.project_a_task = Task.objects.create(
project=self.project_a,
title='Test task 1',
description='',
budget=20,
status='ad',
feedback=''
)
self.project_b_task = Task.objects.create(
project=self.project_b,
title='Test task 1',
description='',
budget=20,
status='ad',
feedback=''
)
self.project_c_task = Task.objects.create(
project=self.project_c,
title='Test task 1',
description='',
budget=20,
status='ad',
feedback=''
)
def test_error_free_sorting(self):
# Test sorting by title ASC
response = self.client.post('/projects/', {
'sort_form': '',
'sort_by': 't',
})
self.assertEqual(response.status_code, 200)
self.assertEqual(response.context['projects'][0], self.project_a)
self.assertEqual(response.context['projects'][1], self.project_b)
self.assertEqual(response.context['projects'][2], self.project_c)
# Test sorting by title DESC
response = self.client.post('/projects/', {
'sort_form': '',
'sort_by': '!t',
})
self.assertEqual(response.status_code, 200)
self.assertEqual(response.context['projects'][0], self.project_c)
self.assertEqual(response.context['projects'][1], self.project_b)
self.assertEqual(response.context['projects'][2], self.project_a)
#TODO: possibly add more
# Test sorting by owner username ASC
response = self.client.post('/projects/', {
'sort_form': '',
'sort_by': 'o',
})
self.assertEqual(response.status_code, 200)
self.assertEqual(response.context['projects'][0], self.project_b)
self.assertEqual(response.context['projects'][1], self.project_c)
self.assertEqual(response.context['projects'][2], self.project_a)
# Test sorting by owner username DESC
response = self.client.post('/projects/', {
'sort_form': '',
'sort_by': '!o',
})
self.assertEqual(response.status_code, 200)
self.assertEqual(response.context['projects'][0], self.project_a)
self.assertEqual(response.context['projects'][1], self.project_c)
self.assertEqual(response.context['projects'][2], self.project_b)
class ProjectOfferTest(unittest.TestCase):
def setUp(self):
......@@ -166,3 +277,73 @@ class ProjectOfferTest(unittest.TestCase):
def test_edit_project_offer_integration(self):
#TODO
self.assertTrue(True)
class EditProjectTest(unittest.TestCase):
def setUp(self):
self.client = Client()
self.edit_project_category = ProjectCategory.objects.create(name='edit_project_category')
self.project_owner = User.objects.create_user(
username='ProjectOwner',
email='test@test.com',
password='top_secret'
)
self.edit_project_test_project = Project.objects.create(
user=self.project_owner.profile,
title='Edit project test project',
description='',
category=self.edit_project_category,
status='o'
)
self.edit_project_test_task1 = Task.objects.create(
project=self.edit_project_test_project,
title='Test task 1',
description='',
budget=20,
status='ad',
feedback=''
)
self.edit_project_test_task2 = Task.objects.create(
project=self.edit_project_test_project,
title='Test task 2',
description='',
budget=30,
status='ad',
feedback=''
)
def test_edit_project_and_tasks(self):
# Test project pre edit
self.client.login(username= 'ProjectOwner', password= 'top_secret')
response = self.client.get('/projects/' + str(Project.objects.last().pk) + '/')
self.assertEqual(response.status_code, 200)
self.assertEqual(response.context['project'], self.edit_project_test_project)
# Test project post edit
self.client.post('/projects/' + str(Project.objects.last().pk) + '/', {
'edit_project': True,
})
self.client.post('/projects/' + str(Project.objects.last().pk) + '/', {
'edit_project': True,
'project_description': 'edited',
f'task{self.edit_project_test_task1.id}_budget': '40',
f'task{self.edit_project_test_task1.id}_description': 'edited task1',
f'task{self.edit_project_test_task2.id}_budget': '50',
f'task{self.edit_project_test_task2.id}_description': 'edited task2',
})
response = self.client.get('/projects/' + str(Project.objects.last().pk) + '/')
self.assertEqual(response.status_code, 200)
self.assertEqual(response.context['project'].description, 'edited')
self.assertEqual(response.context['total_budget'], 90)
self.assertEqual(response.context['tasks'][0].description, 'edited task1')
self.assertEqual(response.context['tasks'][0].budget, 40)
self.assertEqual(response.context['tasks'][1].description, 'edited task2')
self.assertEqual(response.context['tasks'][1].budget, 50)
\ No newline at end of file
from django.http import HttpResponse, HttpResponseRedirect
from user.models import Profile
from .models import Project, Task, TaskFile, TaskOffer, Delivery, ProjectCategory, Team, TaskFileTeam, directory_path
from .forms import ProjectForm, TaskFileForm, ProjectStatusForm, TaskOfferForm, TaskOfferResponseForm, TaskPermissionForm, DeliveryForm, TaskDeliveryResponseForm, TeamForm, TeamAddForm, SortForm
from .forms import EditProjectForm, ProjectForm, TaskFileForm, ProjectStatusForm, TaskOfferForm, TaskOfferResponseForm, TaskPermissionForm, DeliveryForm, TaskDeliveryResponseForm, TeamForm, TeamAddForm, SortForm
from django.shortcuts import render, redirect, get_object_or_404
from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import User
......@@ -105,6 +105,19 @@ def project_view(request, project_id):
offer_response.save()
offer_response_form = TaskOfferResponseForm()
if request.method == 'POST' and 'edit_project' in request.POST:
edit_project_form = EditProjectForm(request.POST)
if edit_project_form.is_valid() and project.status == 'o':
if project.edit:
project.description = request.POST['project_description']
for task in tasks:
task.budget = request.POST[f'task{task.id}_budget']
task.description = request.POST[f'task{task.id}_description']
task.save()
project.edit = not project.edit
project.save()
edit_project_form = EditProjectForm()
if request.method == 'POST' and 'status_change' in request.POST:
status_form = ProjectStatusForm(request.POST)
if status_form.is_valid():
......@@ -119,6 +132,7 @@ def project_view(request, project_id):
'status_form': status_form,
'total_budget': total_budget,
'offer_response_form': offer_response_form,
'edit_project_form': edit_project_form,
})
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment