Skip to content

Commit

Permalink
Add task views
Browse files Browse the repository at this point in the history
  • Loading branch information
Maciej Matczak committed Sep 7, 2019
1 parent b3e62b3 commit fe24ffb
Show file tree
Hide file tree
Showing 10 changed files with 226 additions and 32 deletions.
1 change: 1 addition & 0 deletions scraper/templates/scraper/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
<div class="navbar-nav mr-auto">
<a class="nav-item nav-link" href="{% url 'scraper-home' %}">Home</a>
<a class="nav-item nav-link" href="{% url 'scrapingjobs' %}">Scraping jobs</a>
<a class="nav-item nav-link" href="{% url 'scrapingtasks' %}">Scraping tasks</a>
</div>

<div class="navbar-nav">
Expand Down
20 changes: 20 additions & 0 deletions scraper/templates/scraper/scrapingtask_confirm_delete.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{% extends 'scraper/base.html' %}
{% load crispy_forms_tags %}

{% block content %}

<div class="entry-section">
<form method="POST">
{% csrf_token %}

<fieldset class="form-group">
<legend class="border-bottom mb-4">Delete task</legend>
Please confirm deleting task: "{{ object.title }}"
</fieldset>
<div class="form-group">
<button class="btn btn-outline-danger" type="submit">Yes, Delete</button>
<a class="btn btn-outline-secondary" href="{% url 'scrapingtask-detail' object.id %}">Cancel</a>
</div>
</form>
</div>
{% endblock content %}
23 changes: 23 additions & 0 deletions scraper/templates/scraper/scrapingtask_detail.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{% extends 'scraper/base.html' %}

{% block content %}
<div class="entry-section">
<div class="entry-header">
<h5 class="entry-title mr-4">{{ object.title }}</h5>
</div>

<div class="entry-content">
<pre><code class="YAML">{{ object.task }}</code></pre>
</div>

{% if object.user == user %}
<div class="mt-2">
<a class="btn btn-secondary btn-sm mt-1 mb-1" href="{% url 'scrapingtask-update' object.id %}">Update</a>
<a class="btn btn-warning btn-sm mt-1 mb-1" href="{% url 'scrapingtask-testrun' object.id %}">Test</a>
<a class="btn btn-danger btn-sm mt-1 mb-1" href="{% url 'scrapingtask-delete' object.id %}">Delete</a>
</div>
{% endif %}
</div>


{% endblock content %}
18 changes: 18 additions & 0 deletions scraper/templates/scraper/scrapingtask_form.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{% extends 'scraper/base.html' %}
{% load crispy_forms_tags %}

{% block content %}

<div class="entry-section">
<form method="POST">
{% csrf_token %}
<fieldset class="form-group">
<legend class="border-bottom mb-4">Scraping Task</legend>
{{ form|crispy }}
</fieldset>
<div class="form-group">
<button class="btn btn-outline-info" type="submit">Save</button>
</div>
</form>
</div>
{% endblock content %}
46 changes: 46 additions & 0 deletions scraper/templates/scraper/scrapingtask_list.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
{% extends 'scraper/base.html' %}

{% block content %}

{% for task in object_list %}
<div class="entry-section">
<div class="entry-header">
<h5 class="entry-title">
<a href="{% url 'scrapingtask-detail' pk=task.id %}">
{{ task.title }}
</a>
</a>
</h5>

</div>

<div class="entry-content">
<pre><code class="YAML">{{ task.task }}</code></pre>
</div>

</div>
{% endfor %}

{% if is_paginated %}

{% if page_obj.has_previous %}
<a class="btn btn-outline-info mb-4" href="?page=1">First</a>
<a class="btn btn-outline-info mb-4" href="?page={{ page_obj.previous_page_number }}">Previous</a>
{% endif %}

{% for num in page_obj.paginator.page_range %}
{% if page_obj.number == num %}
<a class="btn btn-info mb-4" href="?page={{ num }}">{{ num }}</a>
{% elif num > page_obj.number|add:'-3' and num < page_obj.number|add:'3' %}
<a class="btn btn-outline-info mb-4" href="?page={{ num }}">{{ num }}</a>
{% endif %}
{% endfor %}

{% if page_obj.has_next %}
<a class="btn btn-outline-info mb-4" href="?page={{ page_obj.next_page_number }}">Next</a>
<a class="btn btn-outline-info mb-4" href="?page={{ page_obj.paginator.num_pages }}">Last</a>
{% endif %}

{% endif %}

{% endblock content %}
2 changes: 1 addition & 1 deletion scraper/tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,4 @@ def test_scraping_jobs_for_user(user_factory, scraping_job_factory):
scraping_job_factory.create(user=user)
scraping_job_factory.create(user=user)

assert ScrapingJob.objects.filter(user=user).count() == 2, ScrapingJob.objects.all()
assert ScrapingJob.objects.filter(user=user).count() == 2, ScrapingJob.objects.count()
31 changes: 25 additions & 6 deletions scraper/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,34 @@

from .views import (home, ScrapingJobListView, ScrapingJobDetailView,
ScrapingJobCreateView, ScrapingJobUpdateView,
ScrapingJobDeleteView, scraping_job_test_run, test_site)
ScrapingJobDeleteView, scraping_job_test_run, test_site,
ScrapingTaskListView, ScrapingTaskDetailView,
ScrapingTaskCreateView, ScrapingTaskUpdateView,
ScrapingTaskDeleteView)

urlpatterns = [
path('', home, name='scraper-home'),
path('test-site/', test_site, name='scraper-testsite'),
path('scraping-jobs/', ScrapingJobListView.as_view(), name='scrapingjobs'),
path('scraping-job/<int:pk>/', ScrapingJobDetailView.as_view(), name='scrapingjob-detail'),
path('scraping-job/<int:pk>/testrun/', scraping_job_test_run, name='scrapingjob-testrun'),
path('scraping-job/new/', ScrapingJobCreateView.as_view(), name='scrapingjob-create'),
path('scraping-job/<int:pk>/update/', ScrapingJobUpdateView.as_view(), name='scrapingjob-update'),
path('scraping-job/<int:pk>/delete/', ScrapingJobDeleteView.as_view(), name='scrapingjob-delete'),
path('scraping-job/<int:pk>/', ScrapingJobDetailView.as_view(),
name='scrapingjob-detail'),
path('scraping-job/<int:pk>/testrun/',
scraping_job_test_run, name='scrapingjob-testrun'),
path('scraping-job/new/', ScrapingJobCreateView.as_view(),
name='scrapingjob-create'),
path('scraping-job/<int:pk>/update/',
ScrapingJobUpdateView.as_view(), name='scrapingjob-update'),
path('scraping-job/<int:pk>/delete/',
ScrapingJobDeleteView.as_view(), name='scrapingjob-delete'),
path('scraping-tasks/', ScrapingTaskListView.as_view(), name='scrapingtasks'),
path('scraping-task/<int:pk>/', ScrapingTaskDetailView.as_view(),
name='scrapingtask-detail'),
path('scraping-task/<int:pk>/', ScrapingTaskDetailView.as_view(),
name='scrapingtask-testrun'),
path('scraping-task/new/', ScrapingTaskCreateView.as_view(),
name='scrapingtask-create '),
path('scraping-task/<int:pk>/update/',
ScrapingTaskUpdateView.as_view(), name='scrapingtask-update'),
path('scraping-task/<int:pk>/delete/',
ScrapingTaskDeleteView.as_view(), name='scrapingtask-delete'),
]
75 changes: 57 additions & 18 deletions scraper/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@

from .item_scraper import item_scraper
from .item_scraper.validators import ValidationError as ScraptTaskValidationError
from .forms import ScrapingJobCreateForm, ScrapingJobUpdateForm
from .models import ScrapingJob
from .forms import (ScrapingJobCreateForm, ScrapingJobUpdateForm)
from .models import ScrapingJob, ScrapingTask

deals = [
{
Expand Down Expand Up @@ -68,6 +68,60 @@ def test_request_vs_object_user(view):
return False


class ScrapingTaskListView(LoginRequiredMixin, ListView):
model = ScrapingTask
ordering = ['favourite', 'title']
paginate_by = 10

def get_queryset(self, *args, **kwargs):
user = self.request.user
return ScrapingTask.objects.filter(user=user)


class ScrapingTaskDetailView(LoginRequiredMixin, UserPassesTestMixin, DetailView):
model = ScrapingTask

def test_func(self):
return test_request_vs_object_user(self)


class ScrapingTaskCreateView(LoginRequiredMixin, CreateView):
model = ScrapingTask
fields = [
'title',
'favourite',
'task',
]

def form_valid(self, form):
form.instance.user = self.request.user
return super().form_valid(form)


class ScrapingTaskUpdateView(LoginRequiredMixin, UserPassesTestMixin, UpdateView):
model = ScrapingTask
fields = [
'title',
'favourite',
'task',
]

def form_valid(self, form):
form.instance.user = self.request.user
return super().form_valid(form)

def test_func(self):
return test_request_vs_object_user(self)


class ScrapingTaskDeleteView(LoginRequiredMixin, UserPassesTestMixin, DeleteView):
model = ScrapingTask
success_url = '/scraping-tasks/'

def test_func(self):
return test_request_vs_object_user(self)


class ScrapingJobListView(LoginRequiredMixin, ListView):
model = ScrapingJob
context_object_name = 'tasks'
Expand All @@ -89,13 +143,6 @@ def test_func(self):
class ScrapingJobCreateView(LoginRequiredMixin, CreateView):
model = ScrapingJob
form_class = ScrapingJobCreateForm
# fields = [
# 'url',
# 'active',
# 'multiple',
# 'task',
# 'running_time',
# ]

def form_valid(self, form):
form.instance.user = self.request.user
Expand All @@ -105,14 +152,6 @@ def form_valid(self, form):
class ScrapingJobUpdateView(LoginRequiredMixin, UserPassesTestMixin, UpdateView):
model = ScrapingJob
form_class = ScrapingJobUpdateForm
# fields = [
# 'url',
# 'active',
# 'multiple',
# 'running_time',
# 'scraping_task',
# 'description',
# ]

def form_valid(self, form):
form.instance.user = self.request.user
Expand All @@ -124,7 +163,7 @@ def test_func(self):

class ScrapingJobDeleteView(LoginRequiredMixin, UserPassesTestMixin, DeleteView):
model = ScrapingJob
success_url = '/scraping-tasks/'
success_url = '/scraping-jobs/'

def test_func(self):
return test_request_vs_object_user(self)
Expand Down
38 changes: 33 additions & 5 deletions tests/test_functional.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,18 @@ def test_standard_scenario(live_server, browser, user_factory,
assert len(jobs_divs) == 2

# but let's double check if detail view of the other one gives an error
browser.get(live_server.url + reverse('scrapingjob-detail', args=[job21.pk]))
browser.get(live_server.url +
reverse('scrapingjob-detail', args=[job21.pk]))
assert '403' in browser.page_source

# let's assume we just can find both task data within the detail
# page
browser.get(live_server.url + reverse('scrapingjob-detail', args=[job11.pk]))
browser.get(live_server.url +
reverse('scrapingjob-detail', args=[job11.pk]))
assert task11.task in browser.find_element_by_tag_name('body').text,\
browser.find_element_by_tag_name('body').text
browser.get(live_server.url + reverse('scrapingjob-detail', args=[job12 .pk]))
browser.get(live_server.url +
reverse('scrapingjob-detail', args=[job12 .pk]))
assert task12.task in browser.find_element_by_tag_name('body').text,\
browser.find_element_by_tag_name('body').text

Expand All @@ -78,10 +81,35 @@ def test_standard_scenario(live_server, browser, user_factory,

# and after all this change we and with following:
# job11 still have task11
browser.get(live_server.url + reverse('scrapingjob-detail', args=[job11.pk]))
browser.get(live_server.url +
reverse('scrapingjob-detail', args=[job11.pk]))
assert task11.task in browser.find_element_by_tag_name('body').text,\
browser.find_element_by_tag_name('body').text
# but job12 should have task11
browser.get(live_server.url + reverse('scrapingjob-detail', args=[job12.pk]))
browser.get(live_server.url +
reverse('scrapingjob-detail', args=[job12.pk]))
assert task12.task not in browser.find_element_by_tag_name('body').text,\
browser.find_element_by_tag_name('body').text


@pytest.mark.django_db
def test_working_with_tasks(live_server, browser, user_factory,
scraping_job_factory, scraping_task_factory):
user1 = user_factory.create(password=make_password('1234'))

task1 = scraping_task_factory.create(user=user1)
task2 = scraping_task_factory.create(user=user1)

# Open the home page and log in as user1
browser.get(live_server.url)
browser.find_element_by_partial_link_text("jobs").click()
browser.find_element_by_name('username').send_keys(user1.username)
browser.find_element_by_name('password').send_keys('1234')
browser.find_element_by_css_selector("button[type='submit']").click()

browser.find_element_by_partial_link_text("tasks").click()
found_titles = {el.text for el in browser.find_elements_by_css_selector(
'.entry-title a')}
expected_titles = {t.title for t in (task1, task2)}

assert found_titles == expected_titles
4 changes: 2 additions & 2 deletions users/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
@pytest.mark.django_db
def test_standard_scenario(user_factory):
user1 = user_factory.create()
assert User.objects.all().count() == 1
assert User.objects.count() == 1

user2 = user_factory.create()
assert User.objects.all().count() == 2
assert User.objects.count() == 2

0 comments on commit fe24ffb

Please sign in to comment.