combo/tests/test_pwa.py

206 lines
7.9 KiB
Python

import base64
import os
import mock
import pytest
from webtest import Upload
try:
import pywebpush
except ImportError:
pywebpush = None
from django.conf import settings
from django.core.files import File
from django.core.urlresolvers import reverse
from django.template import Context, Template
from django.test import override_settings
from django.test.client import RequestFactory
from django.utils.six import BytesIO
from combo.apps.notifications.models import Notification
from combo.apps.pwa.models import PushSubscription, PwaSettings, PwaNavigationEntry
from combo.data.models import Page
from .test_manager import login
pytestmark = pytest.mark.django_db
def test_manifest_json(app):
assert app.get('/manifest.json', status=200).json['name'] == 'Compte Citoyen'
with override_settings(TEMPLATE_VARS={'global_title': 'FooBar'}):
assert app.get('/manifest.json', status=200).json['name'] == 'FooBar'
def test_service_worker(app):
app.get('/service-worker.js', status=200)
app.get('/service-worker-registration.js', status=200)
def test_webpush_subscription(app, john_doe, jane_doe):
app.post_json(reverse('pwa-subscribe-push'), params={'sample': 'content'}, status=403)
app.get(reverse('pwa-subscribe-push'), status=403)
app = login(app, john_doe.username, john_doe.username)
app.post_json(reverse('pwa-subscribe-push'), params={'sample': 'content'}, status=200)
assert PushSubscription.objects.count() == 1
app.post_json(reverse('pwa-subscribe-push'), params={'sample': 'content2'}, status=200)
assert PushSubscription.objects.count() == 2
app = login(app, jane_doe.username, jane_doe.username)
app.post_json(reverse('pwa-subscribe-push'), params={'sample': 'content'}, status=200)
assert PushSubscription.objects.count() == 3
app = login(app, john_doe.username, john_doe.username)
app.post_json(reverse('pwa-subscribe-push'), params=None, status=200)
assert PushSubscription.objects.count() == 1
@pytest.mark.skipif('pywebpush is None')
def test_webpush_notification(app, john_doe):
PushSubscription.objects.all().delete()
app = login(app, john_doe.username, john_doe.username)
app.post_json(reverse('pwa-subscribe-push'), params={'sample': 'content'}, status=200)
with mock.patch('pywebpush.webpush') as webpush:
notification = Notification.notify(john_doe, 'test', body='hello world')
assert webpush.call_count == 1
assert webpush.call_args[1]['subscription_info'] == {'sample': 'content'}
def test_no_pwa_manager(app, admin_user):
app = login(app)
resp = app.get('/manage/', status=200)
assert not '/manage/pwa/' in resp.text
def test_pwa_manager(app, admin_user):
app = login(app)
with override_settings(TEMPLATE_VARS={'pwa_display': 'standalone'}):
resp = app.get('/manage/', status=200)
assert '/manage/pwa/' in resp.text
resp = app.get('/manage/pwa/')
resp.form['offline_text'] = 'You are offline.'
assert resp.form['offline_retry_button'].checked
resp.form['offline_retry_button'].checked = False
resp = resp.form.submit().follow()
assert resp.form['offline_text'].value == 'You are offline.'
assert resp.form['offline_retry_button'].checked is False
resp = app.get('/manage/pwa/')
resp = resp.click('Add a navigation entry')
resp.form['label'] = 'Hello'
resp.form['url'] = 'https://www.example.net'
resp = resp.form.submit().follow()
assert PwaNavigationEntry.objects.all().count() == 1
page = Page(title='test', slug='test')
page.save()
resp = resp.click('Add a navigation entry')
resp.form['link_page'] = page.id
resp = resp.form.submit().follow()
assert PwaNavigationEntry.objects.all().count() == 2
for i in range(3):
resp = resp.click('Add a navigation entry')
resp.form['label'] = 'Hello %s' % i
resp.form['url'] = 'https://www.example.net'
resp = resp.form.submit().follow()
# max 5 items
assert 'Add a navigation entry' not in resp.text
# reorder items, reverse them all
entries = PwaNavigationEntry.objects.all()
app.get('/manage/pwa/navigation/order/?new-order=%s' %
','.join(reversed([str(x.id) for x in entries])))
entries = PwaNavigationEntry.objects.all()
assert entries[0].label == 'Hello 2'
# remove first item
resp = app.get('/manage/pwa/')
resp = resp.click(href='delete', index=0)
resp = resp.form.submit().follow()
assert 'Hello 2' not in resp.text
assert 'Add a navigation entry' in resp.text
# rename item
resp = resp.click('Hello 1')
resp.form['label'] = 'Hello 12'
resp = resp.form.submit().follow()
assert PwaNavigationEntry.objects.all()[0].label == 'Hello 12'
# check error handling
resp = resp.click('Hello 12')
resp.form['label'] = ''
resp.form['url'] = ''
resp = resp.form.submit()
assert 'A label is required' in resp.text
assert 'An URL is required' in resp.text
resp.form['url'] = 'foobar'
resp.form['link_page'] = page.id
resp = resp.form.submit()
assert 'An URL cannot be specified' in resp.text
# add an icon
resp = app.get('/manage/pwa/')
resp.form['application_icon'] = Upload('test.png',
base64.decodestring(b'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQAAAAA3bvkkAAAACklEQVQI12NoAAAAggCB3UNq9AAAAABJRU5ErkJggg=='),
'image/png')
resp = resp.form.submit().follow()
assert PwaSettings.singleton().application_icon.name == 'pwa/test.png'
def test_pwa_offline_page(app):
PwaSettings.objects.all().delete()
resp = app.get('/__pwa__/offline/')
assert 'You are currently offline.' in resp.text
assert 'Retry' in resp.text
pwa_settings = PwaSettings.singleton()
pwa_settings.offline_text = 'You are offline.'
pwa_settings.offline_retry_button = False
pwa_settings.save()
resp = app.get('/__pwa__/offline/')
assert 'You are offline.' in resp.text
assert 'Retry' not in resp.text
def test_pwa_navigation_templatetag(app):
page = Page(title='One', slug='one')
page.save()
entry1 = PwaNavigationEntry(label='a', url='/', notification_count=True,
use_user_name_as_label=True, order=0)
entry2 = PwaNavigationEntry(link_page=page, order=1, icon=File(BytesIO(b'te\30st'), 'test.png'))
entry1.save()
entry2.save()
t = Template('{% load pwa %}{% pwa_navigation %}')
assert t.render(Context({})) == ''
with override_settings(TEMPLATE_VARS={'pwa_display': 'standalone'}):
request = RequestFactory().get('/')
nav = t.render(Context({'request': request}))
assert '<span>a</span>' in nav
assert '<span>One</span>' in nav
assert nav.count('background-image') == 1
assert nav.count('data-notification-count-url=') == 1
assert nav.count('data-pwa-user-name=""') == 1
nav = t.render(Context({'request': request, 'render_skeleton': True}))
assert 'data-pwa-user-name="{% block placeholder-user-name %}' in nav
def test_pwa_application_icon(app, admin_user):
app = login(app)
with override_settings(TEMPLATE_VARS={'pwa_display': 'standalone'}):
PwaSettings.objects.all().delete()
resp = app.get('/manage/pwa/')
resp.form['application_icon'] = Upload('test.png',
base64.decodestring(b'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQAAAAA3bvkkAAAACklEQVQI12NoAAAAggCB3UNq9AAAAABJRU5ErkJggg=='),
'image/png')
resp = resp.form.submit().follow()
resp = app.get('/manifest.json', status=200)
assert len(resp.json['icons']) == 5
# make sure largest icon is referenced in service worker
resp2 = app.get('/service-worker.js', status=200)
assert resp.json['icons'][-1]['src'].split('/')[-1] in resp.text