-
Notifications
You must be signed in to change notification settings - Fork 160
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
17 changed files
with
905 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
{% extends "tutorialv2/base.html" %} | ||
{% load i18n %} | ||
|
||
{% block content %} | ||
|
||
<h1>{% blocktrans %} Liens de partage pour « {{ content }} » {% endblocktrans %}</h1> | ||
|
||
<p>{% trans "Diffusez votre contenu en partageant un simple lien accessible sans incription sur le site." %}</p> | ||
|
||
<p>{% trans "Les liens de partages offrent les fonctionnalités suivantes :" %}</p> | ||
|
||
{% blocktrans %} | ||
<ul> | ||
<li>partage de la dernière bêta ou du dernier brouillon ;</li> | ||
<li>validité temporaire ou permanente ;</li> | ||
<li>désactivation et réactivation à volonté.</li> | ||
</ul> | ||
{% endblocktrans %} | ||
|
||
<a href="#create-shareable-link" class="open-modal"> | ||
{% trans "Créer un lien de partage" %} | ||
</a> | ||
|
||
<form | ||
action="{% url 'content:create-shareable-link' content.pk %}" | ||
method="post" | ||
id="create-shareable-link" | ||
class="modal modal-flex"> | ||
{% csrf_token %} | ||
{{ create_form.as_p }} | ||
<button type="submit" class="btn-submit">{% trans "Créer" %}</button> | ||
</form> | ||
|
||
|
||
|
||
<h2>{% trans "Liens actifs" %}</h2> | ||
|
||
<p> | ||
{% blocktrans %} | ||
Les personnes disposant d'un lien actif peuvent l'utiliser pour lire le contenu. | ||
Il est possible de désactiver un lien temporairement pour en interdire son usage, et le réactiver plus tard. | ||
{% endblocktrans %} | ||
</p> | ||
|
||
{% if not active_links_and_forms %} | ||
|
||
<p>{% trans "Vous n'avez pas de liens de partage actifs." %}</p> | ||
|
||
{% else %} | ||
|
||
<ul> | ||
{% for link, edit_form in active_links_and_forms reversed %} | ||
{% include 'tutorialv2/view/list_shareable_links.part.html' with link=link edit_form=edit_form content=content section="active" %} | ||
{% endfor %} | ||
</ul> | ||
|
||
{% endif %} | ||
|
||
|
||
<h2>{% trans "Liens expirés" %}</h2> | ||
|
||
<p> | ||
{% blocktrans %} | ||
Un lien de partage expiré ne permet pas de lire le contenu. | ||
Si un lien est expiré, vous pouvez modifier sa date d'expiration pour qu'il fonctionne de nouveau. | ||
{% endblocktrans %} | ||
</p> | ||
|
||
{% if not expired_links_and_forms %} | ||
|
||
<p>{% trans "Vous n'avez pas de liens de partage expirés." %}</p> | ||
|
||
{% else %} | ||
|
||
<ul> | ||
{% for link, edit_form in expired_links_and_forms reversed %} | ||
{% include 'tutorialv2/view/list_shareable_links.part.html' with link=link edit_form=edit_form content=content section="expired" %} | ||
{% endfor %} | ||
</ul> | ||
|
||
{% endif %} | ||
|
||
<h2>{% trans "Liens inactifs" %}</h2> | ||
|
||
<p> | ||
{% blocktrans %} | ||
Un lien de partage inactif ne permet pas de lire le contenu. | ||
Vous pouvez le réactiver quand vous le souhaitez pour autoriser de nouveau son usage. | ||
{% endblocktrans %} | ||
</p> | ||
|
||
{% if not inactive_links_and_forms %} | ||
|
||
<p>{% trans "Vous n'avez pas de liens de partage inactifs." %}</p> | ||
|
||
{% else %} | ||
|
||
<ul> | ||
{% for link, edit_form in inactive_links_and_forms reversed %} | ||
{% include 'tutorialv2/view/list_shareable_links.part.html' with link=link edit_form=edit_form content=content section="inactive" %} | ||
{% endfor %} | ||
</ul> | ||
|
||
{% endif %} | ||
|
||
{% endblock %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
{% load i18n %} | ||
|
||
<li class="shareable-link"> | ||
<h3>{{ link.description }}</h3> | ||
<input value="{{ link.full_url }}" /> | ||
<p> | ||
{% if link.type == "DRAFT" %} | ||
{% trans "Lien vers <em>le dernier brouillon</em>" %} | ||
{% elif link.type == "BETA" %} | ||
{% trans "Lien vers <em>la dernière bêta</em>" %} | ||
{% else %} | ||
{% trans "Lien de <em>type inconnu</em>" %} | ||
{% endif %} | ||
</p> | ||
<p> | ||
<p> | ||
{% if link.expiration and link.expired %} | ||
{% blocktrans with date=link.expiration %} | ||
Lien <em>expiré</em> depuis le {{ date }} | ||
{% endblocktrans %} | ||
{% elif link.expiration and not link.expired %} | ||
{% blocktrans with date=link.expiration %} | ||
Valide <em>jusqu'au {{ date }}</em> | ||
{% endblocktrans %} | ||
{% else %} | ||
{% trans "Valide <em>indéfiniment</em>" %} | ||
{% endif %} | ||
</p> | ||
</p> | ||
<a href="#edit-shareable-link-{{ link.id }}" class="open-modal"> | ||
{% trans "Modifier" %} | ||
</a> | ||
|
||
<form | ||
action="{% url 'content:edit-shareable-link' link.id %}" | ||
method="post" | ||
id="edit-shareable-link-{{ link.id }}" | ||
class="modal modal-flex"> | ||
{% csrf_token %} | ||
{{ edit_form.as_p }} | ||
<button type="submit" class="btn-submit">{% trans "Modifier" %}</button> | ||
</form> | ||
|
||
|
||
<a href="#delete-shareable-link-{{ link.id }}" class="open-modal"> | ||
{% trans "Supprimer" %} | ||
</a> | ||
|
||
<form | ||
action="{% url 'content:delete-shareable-link' link.id %}" | ||
method="post" | ||
id="delete-shareable-link-{{ link.id }}" | ||
class="modal modal-flex"> | ||
{% csrf_token %} | ||
<p> | ||
{% blocktrans %} | ||
<strong>Attention, ce lien sera supprimé définitivement.</strong> | ||
Vous ne pourrez pas le récupérer. | ||
Si vous souhaitez réutiliser ce lien plus tard, désactivez-le. | ||
{% endblocktrans %} | ||
</p> | ||
<button type="submit" class="btn-submit">{% trans "Supprimer" %}</button> | ||
</form> | ||
|
||
{% if section == "active" or section == "expired" %} | ||
<form action="{% url 'content:deactivate-shareable-link' link.id %}" method="post"> | ||
{% csrf_token %} | ||
<button type="submit" class="btn-cancel">{% trans "Désactiver" %}</button> | ||
</form> | ||
{% else %} | ||
<form action="{% url 'content:reactivate-shareable-link' link.id %}" method="post"> | ||
{% csrf_token %} | ||
<button type="submit" class="btn-submit">{% trans "Réactiver" %}</button> | ||
</form> | ||
{% endif %} | ||
</li> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
# Generated by Django 3.2.15 on 2022-09-29 22:07 | ||
|
||
from django.db import migrations, models | ||
import django.db.models.deletion | ||
import uuid | ||
|
||
|
||
class Migration(migrations.Migration): | ||
|
||
dependencies = [ | ||
("tutorialv2", "0041_remove_must_reindex"), | ||
] | ||
|
||
operations = [ | ||
migrations.CreateModel( | ||
name="ShareableLink", | ||
fields=[ | ||
("id", models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), | ||
("active", models.BooleanField(default=True)), | ||
("expiration", models.DateTimeField(null=True)), | ||
("description", models.CharField(default="Lien de partage", max_length=150)), | ||
( | ||
"type", | ||
models.CharField( | ||
choices=[("DRAFT", "Lien vers le dernier brouillon"), ("BETA", "Lien vers la dernière bêta")], | ||
default="DRAFT", | ||
max_length=10, | ||
), | ||
), | ||
( | ||
"content", | ||
models.ForeignKey( | ||
on_delete=django.db.models.deletion.CASCADE, | ||
to="tutorialv2.publishablecontent", | ||
verbose_name="Contenu", | ||
), | ||
), | ||
], | ||
), | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
import uuid | ||
from datetime import datetime | ||
|
||
from django.conf import settings | ||
from django.db import models | ||
from django.db.models import Q | ||
from django.urls import reverse | ||
from django.utils.translation import gettext_lazy as _ | ||
|
||
from zds.tutorialv2.models import SHAREABLE_LINK_TYPES | ||
from zds.tutorialv2.models.database import PublishableContent | ||
|
||
|
||
class ShareableLinkQuerySet(models.QuerySet): | ||
def for_content(self, content): | ||
return self.filter(content=content) | ||
|
||
def active_and_for_content(self, content): | ||
return self.for_content(content).active() | ||
|
||
def expired_and_for_content(self, content): | ||
return self.for_content(content).expired() | ||
|
||
def inactive_and_for_content(self, content): | ||
return self.for_content(content).inactive() | ||
|
||
def active(self): | ||
pivot_date = datetime.now() | ||
return self.filter(Q(active=True) & (Q(expiration__gte=pivot_date) | Q(expiration=None))) | ||
|
||
def expired(self): | ||
pivot_date = datetime.now() | ||
return self.filter(active=True, expiration__lt=pivot_date) | ||
|
||
def inactive(self): | ||
return self.filter(active=False) | ||
|
||
|
||
class ShareableLink(models.Model): | ||
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) | ||
content = models.ForeignKey(PublishableContent, verbose_name="Contenu", on_delete=models.CASCADE) | ||
active = models.BooleanField(default=True) | ||
expiration = models.DateTimeField(null=True) | ||
description = models.CharField(default=_("Lien de partage"), max_length=150) | ||
# Types | ||
# DRAFT: always points to the last draft version | ||
# BETA: always points to the last beta version | ||
type = models.CharField(max_length=10, choices=SHAREABLE_LINK_TYPES, default="DRAFT") | ||
|
||
objects = ShareableLinkQuerySet.as_manager() | ||
|
||
def full_url(self): | ||
return settings.ZDS_APP["site"]["url"] + reverse("content:shareable-link-view", kwargs={"id": self.id}) | ||
|
||
def deactivate(self): | ||
self.active = False | ||
self.save() | ||
|
||
def reactivate(self): | ||
self.active = True | ||
self.save() |
Empty file.
47 changes: 47 additions & 0 deletions
47
zds/tutorialv2/tests/tests_views/shareable_links/tests_createshareablelinkview.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
from django.test import TestCase | ||
from django.urls import reverse | ||
|
||
from zds.member.tests.factories import ProfileFactory, StaffProfileFactory | ||
from zds.tutorialv2.models.shareable_links import ShareableLink | ||
from zds.tutorialv2.tests.factories import PublishableContentFactory | ||
from zds.tutorialv2.views.shareable_links import CreateShareableLinkView | ||
|
||
|
||
class CreateShareableLinkTests(TestCase): | ||
def setUp(self): | ||
# Create users | ||
self.author = ProfileFactory().user | ||
self.staff = StaffProfileFactory().user | ||
self.outsider = ProfileFactory().user | ||
|
||
# Create a content | ||
self.content = PublishableContentFactory(author_list=[self.author]) | ||
|
||
# Get information to be reused in tests | ||
self.url = reverse("content:create-shareable-link", kwargs={"pk": self.content.pk}) | ||
self.redirect_url = reverse("content:list-shareable-links", kwargs={"pk": self.content.pk}) | ||
self.login_url = reverse("member-login") + "?next=" + self.url | ||
|
||
def test_not_authenticated(self): | ||
self.client.logout() | ||
response = self.client.post(self.url) | ||
self.assertRedirects(response, self.login_url) | ||
|
||
def test_authenticated_author(self): | ||
self.client.force_login(self.author) | ||
n_links_before = ShareableLink.objects.all().count() | ||
data = {"description": "Ceci n'est pas le lien vers La Blague", "expiration": "2042-08-01", "type": "BETA"} | ||
response = self.client.post(self.url, data=data) | ||
self.assertRedirects(response, self.redirect_url, target_status_code=200) | ||
n_links_after = ShareableLink.objects.all().count() | ||
self.assertEqual(n_links_after, n_links_before + 1) | ||
|
||
def test_authenticated_staff(self): | ||
self.client.force_login(self.staff) | ||
response = self.client.post(self.url) | ||
self.assertEqual(response.status_code, 403) | ||
|
||
def test_authenticated_outsider(self): | ||
self.client.force_login(self.outsider) | ||
response = self.client.post(self.url) | ||
self.assertEqual(response.status_code, 403) |
Oops, something went wrong.