Skip to content

Commit 146daaf

Browse files
committed
allowing link redirectior
1 parent 414a381 commit 146daaf

File tree

5 files changed

+87
-2
lines changed

5 files changed

+87
-2
lines changed

pythonpro/redirector/admin.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,15 @@
11
from django.contrib import admin
22

3-
from pythonpro.redirector.models import Redirect
3+
from pythonpro.redirector.models import Redirect, RedirectLink
4+
5+
6+
class RedirectLinkAdmin(admin.TabularInline):
7+
model = RedirectLink
8+
extra = 1
9+
readonly_fields = ['total_access', ]
410

511

612
@admin.register(Redirect)
713
class RedirectorAdmin(admin.ModelAdmin):
814
list_display = 'slug url'.split()
15+
inlines = (RedirectLinkAdmin, )

pythonpro/redirector/facade.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
1+
def _count_access_in_link(link):
2+
link.total_access += 1
3+
link.save()
4+
5+
16
def get_redirect_url(redirect):
27
if redirect.links.exists():
3-
return redirect.links.order_by('?').first().url
8+
link = redirect.links.order_by('total_access', 'id').first()
9+
_count_access_in_link(link)
10+
return link.url
411

512
return redirect.url
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Generated by Django 3.0.4 on 2020-04-22 01:05
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
dependencies = [
9+
('redirector', '0003_redirect_use_javascript'),
10+
]
11+
12+
operations = [
13+
migrations.AddField(
14+
model_name='redirectlink',
15+
name='total_access',
16+
field=models.BigIntegerField(default=0),
17+
),
18+
]

pythonpro/redirector/models.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,13 @@ class Redirect(models.Model):
1010
url = models.URLField(null=True, blank=True)
1111
use_javascript = models.BooleanField(default=False)
1212

13+
def __str__(self):
14+
return self.slug
15+
1316

1417
class RedirectLink(models.Model):
1518
created = models.DateTimeField("Criado em", default=timezone.now)
1619
updated = models.DateTimeField("Alterado em", auto_now=True)
1720
redirect = models.ForeignKey(Redirect, on_delete=models.PROTECT, related_name='links')
1821
url = models.URLField()
22+
total_access = models.BigIntegerField(default=0)
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import pytest
2+
from django.urls import reverse
3+
from model_mommy import mommy
4+
5+
from pythonpro.django_assertions import dj_assert_contains
6+
from pythonpro.redirector.models import Redirect, RedirectLink
7+
from pythonpro.redirector.facade import get_redirect_url
8+
9+
10+
@pytest.fixture
11+
def redirect(db):
12+
redirect = mommy.make(Redirect)
13+
mommy.make(RedirectLink, redirect=redirect)
14+
mommy.make(RedirectLink, redirect=redirect)
15+
return redirect
16+
17+
18+
def test_should_get_url_and_increment_access_count(redirect):
19+
url = get_redirect_url(redirect)
20+
assert RedirectLink.objects.get(url=url, redirect=redirect).total_access == 1
21+
22+
23+
def test_should_bring_always_link_with_less_access(redirect):
24+
link1 = redirect.links.first()
25+
link2 = redirect.links.last()
26+
27+
link1.total_access = 2
28+
link1.save()
29+
30+
assert get_redirect_url(redirect) == link2.url
31+
assert get_redirect_url(redirect) == link2.url
32+
33+
34+
def test_should_bring_older_link_when_access_is_even(redirect):
35+
assert get_redirect_url(redirect) == redirect.links.first().url
36+
37+
38+
@pytest.fixture
39+
def resp1(client, redirect):
40+
return client.get(reverse('redirector:redirect', kwargs={'slug': redirect.slug}), secure=True)
41+
42+
43+
@pytest.fixture
44+
def resp2(client, redirect):
45+
return client.get(reverse('redirector:redirect', kwargs={'slug': redirect.slug}), secure=True)
46+
47+
48+
def test_should_rotate_beetween_links(resp1, resp2):
49+
assert resp1['Location'] != resp2['Location']

0 commit comments

Comments
 (0)