fix an error in the form with url :P

This commit is contained in:
FoxMaSk 2022-01-29 21:07:35 +01:00
parent ef19460455
commit 2c49e35683
17 changed files with 653 additions and 20 deletions

50
.gitlab-ci.yml Normal file
View File

@ -0,0 +1,50 @@
# You can override the included template(s) by including variable overrides
# SAST customization: https://docs.gitlab.com/ee/user/application_security/sast/#customizing-the-sast-settings
# Secret Detection customization: https://docs.gitlab.com/ee/user/application_security/secret_detection/#customizing-settings
# Dependency Scanning customization: https://docs.gitlab.com/ee/user/application_security/dependency_scanning/#customizing-the-dependency-scanning-settings
# Note that environment variables can be set in several places
# See https://docs.gitlab.com/ee/ci/variables/#cicd-variable-precedence
include:
- template: Jobs/SAST.gitlab-ci.yml
- template: Security/SAST.gitlab-ci.yml
- template: Security/Dependency-Scanning.gitlab-ci.yml
- template: Security/Secret-Detection.gitlab-ci.yml
image: python:3.10
variables:
PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip"
DS_EXCLUDED_ANALYZERS: bundler-audit, retire.js, gemnasium, gemnasium-maven
cache:
paths:
- ".cache/pip"
- venv/
before_script:
- python -V
- pip install virtualenv
- virtualenv venv
- source venv/bin/activate
test:
script:
- pip install -r requirements-dev.txt
- cp shaarpy/env.sample shaarpy/.env
# - python -m pytest -s
- coverage run --source='.' manage.py test
coverage: '/TOTAL.+ ([0-9]{1,3}%)/'
deploy:
script:
- cat $PYPIRC > /tmp/.pypirc
- cat $PYPIRC_PYPI > /tmp/.pypirc_pypi
- pip install twine
- python setup.py bdist_wheel
- python -m twine upload --repository gitlab dist/* --config-file /tmp/.pypirc
- python -m twine upload dist/* --config-file /tmp/.pypirc_pypi
only:
- tags
stages:
- test
sast:
variables:
SAST_EXCLUDED_ANALYZERS: bandit, brakeman, eslint, flawfinder, gosec, kubesec,
nodejs-scan, phpcs-security-audit, pmd-apex, security-code-scan, sobelow, spotbugs
SAST_EXCLUDED_PATHS: venv
SAST_SEMGREP_METRICS: 'false'
stage: test

View File

@ -1,7 +1,7 @@
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2021 FoxMaSk <foxmask+wtfpl@pm.me>
Copyright (C) 2022 FoxMaSk <foxmask+wtfpl@pm.me>
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long

View File

@ -151,7 +151,6 @@ DB_PORT=''
TIME_ZONE='Europe/Paris'
LANGUAGE_CODE='en-en'
USE_I18N=True
USE_L10N=True
USE_TZ=True
```
@ -175,6 +174,25 @@ python manage.py runserver localhost:8001
then, access the project with your browser http://127.0.0.1:8001/
### Test
```bash
python manage.py test
```
or
```bash
pytest
```
or
```bash
coverage run --source='.' -m pytest
coverage report -m
```
## Logo

4
pytest.ini Normal file
View File

@ -0,0 +1,4 @@
# -- FILE: pytest.ini (or tox.ini)
[pytest]
DJANGO_SETTINGS_MODULE = shaarpy.settings
python_files = tests.py test_*.py *_tests.py

View File

@ -2,6 +2,7 @@
coverage
flake8
pytest-django
tox
semgrep
pipdeptree
twine
wheel
tox

View File

@ -25,5 +25,4 @@ DB_PORT=''
TIME_ZONE='Europe/Paris'
LANGUAGE_CODE='en-en'
USE_I18N=True
USE_L10N=True
USE_TZ=True

View File

@ -2,7 +2,6 @@
"""
ShaarPy :: Models
"""
import datetime
from django.db import models

View File

@ -132,7 +132,6 @@ CACHE_MIDDLEWARE_SECONDS = 600
LANGUAGE_CODE = env.str('LANGUAGE_CODE', default='en-en')
TIME_ZONE = env.str('TIME_ZONE', default='UTC')
USE_I18N = env.bool('USE_I18N', default=True)
USE_L10N = env.bool('USE_L10N', default=True)
USE_TZ = env.bool('USE_TZ', default=True)

View File

View File

@ -0,0 +1,31 @@
# coding: utf-8
"""
ShaarPy
"""
from django.conf import settings
from django.test import TestCase
import os
class SettingsTestCase(TestCase):
"""
check that all the needed config is present
"""
def test_env_file(self):
assert os.path.isfile('shaarpy/.env')
def test_get_config_service(self):
self.assertIs(type(settings.SHAARPY_NAME), str)
self.assertIs(type(settings.SHAARPY_DESCRIPTION), str)
self.assertIs(type(settings.SHAARPY_AUTHOR), str)
self.assertIs(type(settings.SHAARPY_ROBOT), str)
self.assertIs(type(settings.SHAARPY_LOCALSTORAGE_MD), str)
self.assertIs(type(settings.SHAARPY_STYLE), str)
self.assertIs(type(settings.LANGUAGE_CODE), str)
self.assertIs(type(settings.TIME_ZONE), str)
self.assertIs(type(settings.USE_TZ), bool)
self.assertIs(type(settings.ALLOWED_HOSTS), list)
self.assertIs(type(settings.SECRET_KEY), str)
self.assertIs(type(settings.CSRF_TRUSTED_ORIGINS), list)

View File

@ -0,0 +1,27 @@
# coding: utf-8
"""
ShaarPy
"""
from django.test import TestCase
from shaarpy.models import Links
class LinksTest(TestCase):
"""
Links Model
"""
def create_link(self):
url = 'https://foxmask.org/'
title = 'Le Free de la passion'
text = '# Le Free de la Passion'
private = False
sticky = True
return Links.objects.create(url=url, title=title, text=text, private=private, sticky=sticky)
def test_folders(self):
inst = self.create_link()
self.assertTrue(isinstance(inst, Links))

View File

@ -0,0 +1,18 @@
# coding: utf-8
"""
ShaarPy
"""
from django.test import TestCase
import shaarpy
import os
class VersionTestCase(TestCase):
"""
check VERSION.txt
"""
def test_version(self):
assert os.path.isfile('VERSION.txt')
self.assertIs(type(shaarpy.__version__), str)

457
shaarpy/tests/test_views.py Normal file
View File

@ -0,0 +1,457 @@
# coding: utf-8
"""
ShaarPy
"""
from django.test import RequestFactory, TestCase
from django.contrib.auth.models import User
from django.urls import reverse
from shaarpy.forms import LinksForm
from shaarpy.models import Links
from shaarpy.views import HomeView, LinksCreate, LinksDetail, PrivateLinks, PublicLinks, LinksUpdate
from shaarpy.views import DailyLinks, TagsList, LinksByTagList, MeView, MeUpdate
from shaarpy.views import link_delete
class ViewFunction(TestCase):
def create_link(self):
url = 'https://foxmask.org/'
title = 'Le Free de la passion'
text = '# Le Free de la Passion'
private = False
sticky = True
return Links.objects.create(url=url, title=title, text=text, private=private, sticky=sticky)
def setUp(self):
super(ViewFunction, self).setUp()
self.request = RequestFactory().get('/')
self.user = User.objects.create_user(username='foxmask', email='my@email.org', password='top_secret')
def test_link_delete(self):
link = self.create_link()
# Setup request and view.
request = RequestFactory().get('/')
request.user = self.user
response = link_delete(request=request, pk=link.id)
# Check.
self.assertEqual(response.status_code, 302)
def test_link_delete_with_page(self):
link = self.create_link()
# Setup request and view.
request = RequestFactory().get('/', {"page": "1"})
request.user = self.user
response = link_delete(request=request, pk=link.id)
# Check.
self.assertEqual(response.status_code, 302)
class HomeViewTestCase(TestCase):
def setUp(self):
super(HomeViewTestCase, self).setUp()
self.factory = RequestFactory()
self.user = User.objects.create_user(username='foxmask', email='my@email.org', password='top_secret')
def test_all_links_list(self):
template = "shaarpy/links_list.html"
# Setup request and view.
request = RequestFactory().get('/')
request.user = self.user
view = HomeView.as_view(template_name=template)
# Run.
response = view(request)
# Check.
self.assertEqual(response.status_code, 200)
self.assertEqual(response.template_name[0], template)
class PrivateLinksTestCase(TestCase):
def setUp(self):
super(PrivateLinksTestCase, self).setUp()
self.factory = RequestFactory()
self.user = User.objects.create_user(username='foxmask', email='my@email.org', password='top_secret')
def test_private_links_list(self):
template = "shaarpy/links_list.html"
# Setup request and view.
request = RequestFactory().get('/links/private/')
request.user = self.user
view = PrivateLinks.as_view(template_name=template)
# Run.
response = view(request)
# Check.
self.assertEqual(response.status_code, 200)
self.assertEqual(response.template_name[0], template)
class PublicLinksTestCase(TestCase):
def setUp(self):
super(PublicLinksTestCase, self).setUp()
self.factory = RequestFactory()
self.user = User.objects.create_user(username='foxmask', email='my@email.org', password='top_secret')
def test_private_links_list(self):
template = "shaarpy/links_list.html"
# Setup request and view.
request = RequestFactory().get('/links/public/')
request.user = self.user
view = PublicLinks.as_view(template_name=template)
# Run.
response = view(request)
# Check.
self.assertEqual(response.status_code, 200)
self.assertEqual(response.template_name[0], template)
class LinksUpdateTestCase(TestCase):
def create_links(self):
url = 'https://foxmask.org/'
title = 'Le Free de la passion'
text = '# Le Free de la Passion'
private = False
sticky = True
return Links.objects.create(url=url, title=title, text=text, private=private, sticky=sticky)
def setUp(self):
super(LinksUpdateTestCase, self).setUp()
self.factory = RequestFactory()
self.user = User.objects.create_user(username='foxmask', email='my@email.org', password='top_secret')
def test_link_update(self):
link = self.create_links()
template = "shaarpy/links_form.html"
# Setup request and view.
request = RequestFactory().get(reverse('link_edit', kwargs={'pk': link.id}))
request.user = self.user
view = LinksUpdate.as_view(template_name=template)
# Run.
response = view(request, pk=link.id)
# Check.
self.assertEqual(response.status_code, 200)
self.assertEqual(response.template_name[0], template)
class LinksDetailTestCase(TestCase):
def create_links(self):
url = 'https://foxmask.org/'
title = 'Le Free de la passion'
text = '# Le Free de la Passion'
private = False
sticky = True
return Links.objects.create(url=url, title=title, text=text, private=private, sticky=sticky)
def setUp(self):
super(LinksDetailTestCase, self).setUp()
self.factory = RequestFactory()
def test_link_detail(self):
link = self.create_links()
template = "shaarpy/links_detail.html"
# Setup request and view.
request = RequestFactory().get(reverse('link_detail', kwargs={'slug': link.url_hashed}))
view = LinksDetail.as_view(template_name=template)
# Run.
response = view(request, pk=link.id) # @TODO why pk=link.id and not slug=link.url_hashed ?
# Check.
self.assertEqual(response.status_code, 200)
self.assertEqual(response.template_name[0], template)
class DailyLinksTestCase(TestCase):
def create_links(self):
url = 'https://foxmask.org/'
title = 'Le Free de la passion'
text = '# Le Free de la Passion'
private = False
sticky = True
tags = 'home'
return Links.objects.create(url=url, title=title, text=text, private=private, sticky=sticky, tags=tags)
def setUp(self):
super(DailyLinksTestCase, self).setUp()
self.factory = RequestFactory()
def test_daily(self):
self.create_links()
template = "daily_list.html"
# Setup request and view.
request = RequestFactory().get(reverse('daily'))
view = DailyLinks.as_view(template_name=template)
# Run.
response = view(request)
# Check.
self.assertEqual(response.status_code, 200)
self.assertEqual(response.template_name[0], template)
def test_previous(self):
self.create_links()
template = "daily_list.html"
yesterday = "2022-01-01"
# Setup request and view.
request = RequestFactory().get(reverse('daily'), kwargs={'yesterday': yesterday})
view = DailyLinks.as_view(template_name=template)
# Run.
response = view(request, yesterday=yesterday)
# Check.
self.assertEqual(response.status_code, 200)
self.assertEqual(response.template_name[0], template)
class TagsListTestCase(TestCase):
def create_links(self):
url = 'https://foxmask.org/'
title = 'Le Free de la passion'
text = '# Le Free de la Passion'
private = False
sticky = True
tags = 'home'
return Links.objects.create(url=url, title=title, text=text, private=private, sticky=sticky, tags=tags)
def create_links_no_tags(self):
url = 'https://foxmask.org/'
title = 'Le Free de la passion'
text = '# Le Free de la Passion'
private = False
sticky = True
return Links.objects.create(url=url, title=title, text=text, private=private, sticky=sticky)
def setUp(self):
super(TagsListTestCase, self).setUp()
self.factory = RequestFactory()
self.user = User.objects.create_user(username='foxmask', email='my@email.org', password='top_secret')
def test_tag_index(self):
self.create_links()
self.create_links_no_tags()
template = "tags_list.html"
# Setup request and view.
request = RequestFactory().get(reverse('tags_list'))
request.user = self.user
view = TagsList.as_view(template_name=template)
# Run.
response = view(request)
# Check.
self.assertEqual(response.status_code, 200)
self.assertEqual(response.template_name[0], template)
class LinksByTagListTestCase(TestCase):
def create_links(self):
url = 'https://foxmask.org/'
title = 'Le Free de la passion'
text = '# Le Free de la Passion'
private = False
sticky = True
tags = 'home'
return Links.objects.create(url=url, title=title, text=text, private=private, sticky=sticky, tags=tags)
def setUp(self):
super(LinksByTagListTestCase, self).setUp()
self.factory = RequestFactory()
self.user = User.objects.create_user(username='foxmask', email='my@email.org', password='top_secret')
def test_one_tag(self):
link = self.create_links()
template = "links_list.html"
# Setup request and view.
tags = link.tags
request = RequestFactory().get(reverse('links_by_tag_list', kwargs={'tags': tags}))
request.user = self.user
view = LinksByTagList.as_view(template_name=template)
# Run.
response = view(request, tags=tags)
# Check.
self.assertEqual(response.status_code, 200)
self.assertEqual(response.template_name[0], template)
def test_no_tag(self):
self.create_links()
template = "links_list.html"
# Setup request and view.
request = RequestFactory().get(reverse('links_by_tag_list', kwargs={'tags': '0Tag'}))
tags = '0Tag'
request.user = self.user
view = LinksByTagList.as_view(template_name=template)
# Run.
response = view(request, tags=tags)
# Check.
self.assertEqual(response.status_code, 200)
self.assertEqual(response.template_name[0], template)
class MeTestCase(TestCase):
def setUp(self):
super(MeTestCase, self).setUp()
self.factory = RequestFactory()
self.user = User.objects.create_user(username='foxmask', email='my@email.org', password='top_secret')
def test_me(self):
template = "me.html"
# Setup request and view.
request = RequestFactory().get(reverse('me'))
request.user = self.user
view = MeView.as_view(template_name=template)
# Run.
response = view(request)
# Check.
self.assertEqual(response.status_code, 200)
self.assertEqual(response.template_name[0], template)
class MeUpdateTestCase(TestCase):
def setUp(self):
super(MeUpdateTestCase, self).setUp()
self.factory = RequestFactory()
self.user = User.objects.create_user(username='foxmask', email='my@email.org', password='top_secret')
def test_me(self):
template = "edit_me.html"
# Setup request and view.
request = RequestFactory().get(reverse('edit_me'))
request.user = self.user
view = MeUpdate.as_view(template_name=template)
# Run.
response = view(request)
# Check.
self.assertEqual(response.status_code, 200)
self.assertEqual(response.template_name[0], template)
class CreateLinksTestCase(TestCase):
def setUp(self):
super(CreateLinksTestCase, self).setUp()
self.factory = RequestFactory()
self.user = User.objects.create_user(username='foxmask', email='my@email.org', password='top_secret')
def test_get_the_form(self):
template = "link_form.html"
# Setup request and view.
url_to_create = 'https://foxmask.org/feeds/all.rss.xml'
title = 'Le Free de la passion'
request = RequestFactory().get(reverse('link_create') + '?post=' + url_to_create + '&title=' + title)
request.user = self.user
view = LinksCreate.as_view(template_name=template)
# Run.
response = view(request)
# Check.
self.assertEqual(response.status_code, 200)
self.assertEqual(response.template_name[0], template)
def test_create(self):
# Setup request and view.
url_to_create = 'https://foxmask.org/feeds/all.rss.xml'
title = 'Le Free de la passion'
data = {
'url': url_to_create,
'title': title,
}
request = RequestFactory().post(reverse('link_create'), data=data)
request.user = self.user
view = LinksCreate.as_view()
# Run.
response = view(request)
# Check.
self.assertEqual(response.status_code, 302)
def test_create_note(self):
# Setup request and view.
title = 'Le Free de la passion'
text = '# Le Free de la passion'
data = {
'title': title,
'text': text,
}
request = RequestFactory().post(reverse('link_create'), data=data)
request.user = self.user
view = LinksCreate.as_view()
# Run.
response = view(request)
# Check.
self.assertEqual(response.status_code, 302)
def test_create_note_wo_title(self):
# Setup request and view.
text = '# Le Free de la passion'
data = {
'text': text,
}
request = RequestFactory().post(reverse('link_create'), data=data)
request.user = self.user
view = LinksCreate.as_view()
# Run.
response = view(request)
# Check.
self.assertEqual(response.status_code, 302)
def create_links(self):
url = 'https://foxmask.org/'
title = 'Le Free de la passion'
text = '# Le Free de la Passion'
private = False
sticky = True
tags = 'home'
return Links.objects.create(url=url, title=title, text=text, private=private, sticky=sticky, tags=tags)
def test_create2(self):
# create an entry into the model
self.create_links()
url = 'https://foxmask.org/'
title = 'Le Free de la passion'
text = '# Le Free de la Passion'
private = False
sticky = True
tags = 'home'
data = {
'url': url,
'title': title,
'text': text,
'private': private,
'sticky': sticky,
'tags': tags,
}
# try to create an entry from the form but with same URL
request = RequestFactory().post(reverse('link_create'), data=data)
request.user = self.user
view = LinksCreate.as_view()
# Run.
response = view(request)
# Check.
self.assertEqual(response.status_code, 302)
def test_form_valid(self):
data = {'url': 'https://foxmask.org/'}
form = LinksForm(data=data)
self.assertTrue(form.is_valid())
def test_form_valid2(self):
data = {'title': 'My note', 'text': 'note text'}
form = LinksForm(data=data)
self.assertTrue(form.is_valid())
def test_form_invalid(self):
data = {'url': '', 'title': '', 'text': ''}
form = LinksForm(data=data)
self.assertFalse(form.is_valid())

View File

@ -39,10 +39,11 @@ def url_cleaning(url):
"""
drop unexpected content of the URL from the bookmarklet
"""
for pattern in ('&utm_source=', '?utm_source=', '&utm_medium=', '#xtor=RSS-'):
pos = url.find(pattern)
if pos > 0:
url = url[0:pos]
if url:
for pattern in ('&utm_source=', '?utm_source=', '&utm_medium=', '#xtor=RSS-'):
pos = url.find(pattern)
if pos > 0:
url = url[0:pos]
return url

View File

@ -18,7 +18,7 @@ from django.contrib import admin
from django.contrib.auth import views as auth_views
from django.urls import path, re_path, include
from shaarpy.views import (HomeView, LinksCreate, LinksDetail, LinksUpdate, link_delete, TagsList, LinksByTagList)
from shaarpy.views import (DailyLinks, LatestLinksFeed, me, MeUpdate, PrivateLinks, PublicLinks)
from shaarpy.views import (DailyLinks, LatestLinksFeed, MeView, MeUpdate, PrivateLinks, PublicLinks)
from shaarpy import settings
urlpatterns = [
@ -26,7 +26,7 @@ urlpatterns = [
path('accounts/login/', auth_views.LoginView.as_view(
extra_context={'SHAARPY_NAME': settings.SHAARPY_NAME}),
name="login"),
path('accounts/profile/', me, name="me"),
path('accounts/profile/', MeView.as_view(), name="me"),
path('accounts/profile/edit/', MeUpdate.as_view(), name='edit_me'),
path('accounts/', include('django.contrib.auth.urls')),
# THE APP

View File

@ -15,6 +15,7 @@ from django.shortcuts import redirect, render
from django.urls import reverse, reverse_lazy
from django.utils import timezone
from django.views.generic import ListView, CreateView, UpdateView, DetailView
from django.views.generic.base import TemplateView
import pypandoc
from shaarpy.forms import LinksForm, LinksFormEdit, MeForm
from shaarpy.models import Links
@ -246,6 +247,7 @@ class LinksByTagList(SettingsMixin, ListView):
"""
get the links with that tags
"""
print(self.kwargs)
tags = None if self.kwargs['tags'] == '0Tag' else self.kwargs['tags']
# when tags is None
# get the data with tags is null
@ -366,16 +368,19 @@ def logout_view(request):
logout(request)
@login_required()
def me(request):
class MeView(LoginRequiredMixin, TemplateView):
"""
access to the profile page
"""
return render(request,
'me.html',
{'object': request.user,
'SHAARPY_NAME': settings.SHAARPY_NAME}
)
template_name = "me.html"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['object'] = self.request.user
context['SHAARPY_NAME'] = settings.SHAARPY_NAME
return context
class MeUpdate(SettingsMixin, LoginRequiredMixin, UpdateView):

24
tox.ini Normal file
View File

@ -0,0 +1,24 @@
[tox]
language: python
env:
matrix:
- TOXENV=py38
- TOXENV=py39
- TOXENV=py310
[testenv]
changedir = shaarpy
deps =
-r{toxinidir}/requirements-dev.txt
setenv =
PYTHONPATH = {toxinidir}
PYTHONHASHSEED = 0
TEST_DATABASE_URL = sqlite:///db_test.sqlite3
HOME = my_tox
commands =
cp env.sample .env
{envbindir}/flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
{envbindir}/flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
{envbindir}/pytest {posargs}