Browse Source

added main navigation to layout template

rework
Holger Frey 7 years ago
parent
commit
53f36e8566
  1. 2
      ordr/resources/__init__.py
  2. 60
      ordr/templates/layout.jinja2
  3. 33
      ordr/templates/pages/welcome.jinja2
  4. 9
      tests/_functional/__init__.py
  5. 38
      tests/_functional/layout.py
  6. 15
      tests/_functional/pages.py

2
ordr/resources/__init__.py

@ -9,6 +9,8 @@ class RootResource: @@ -9,6 +9,8 @@ class RootResource:
:param pyramid.request.Request request: the current request object
'''
nav_active = 'welcome'
def __init__(self, request):
''' Create the root resource

60
ordr/templates/layout.jinja2

@ -3,25 +3,71 @@ @@ -3,25 +3,71 @@
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="ordr2">
<meta name="viewport" content="width=device-width, initial-scale=1.0, shrink-to-fit=no">
<meta name="description" content="ordr">
<meta name="author" content="IMTEk / CPI / Holger Frey">
<link rel="shortcut icon" href="{{request.static_url('ordr:static/pyramid-16x16.png')}}">
<title>Ordr2</title>
{% block title %}
<title>Ordr</title>
{% endblock title %}
<!-- Bootstrap core CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" integrity="sha384-9gVQ4dYFwwWSjIDZnLEWnxCjeSWFphJiwGPXr1jddIhOegiu1FwO5qRGvFXOdJZ4" crossorigin="anonymous">
<!-- Custom styles for this scaffold -->
<link href="{{request.static_url('ordr:static/style.css')}}" rel="stylesheet">
</head>
<body>
<nav class="navbar navbar-dark bg-dark navbar-expand-sm">
<a class="navbar-brand text-primary" href="/"><strong>ordr</strong></a>
{% if not request.user %}
<ul class="navbar-nav mr-auto">
<li class="nav-item {% if context.nav_active=='welcome' and not request.view_name %}active{% endif %}">
<a href="/" class="nav-link">Welcome</a>
</li>
<li class="nav-item {% if context.nav_active=='welcome' and request.view_name=='faq' %}active{% endif %}">
<a href="/faq" class="nav-link">FAQs</a>
</li>
<li class="nav-item {% if context.nav_active=='welcome' and request.view_name=='register' %}active{% endif %}">
<a href="/register" class="nav-link">Register</a>
</li>
</ul>
{% else %}
<ul class="navbar-nav mr-auto">
<li class="nav-item {% if context.nav_active=='orders' %}active{% endif %}">
<a href="/orders" class="nav-link">Orders</a>
</li>
<li class="nav-item {% if context.nav_active=='welcome' and request.view_name=='faq' %}active{% endif %}">
<a href="/faq" class="nav-link">FAQs</a>
</li>
{% if 'role:admin' in request.user.principals %}
<li class="nav-item {% if context.nav_active=='admin' %}active{% endif %}">
<a href="/admin" class="nav-link">Admin</a>
</li>
{% endif %}
</ul>
<ul class="navbar-nav">
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="userDrowpdown" role="button" data-toggle="dropdown">
{{ request.user }}
</a>
<div class="dropdown-menu" aria-labelledby="userDropdown">
<a class="dropdown-item" href="/logout">Logout</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="/account">Settings</a>
</div>
</li>
</ul>
{% endif %}
</nav>
{% block content %}
<p>No content</p>
{% endblock content %}
<div class="container-fluid">
{% block content %}
<p>No content</p>
{% endblock content %}
</div>
<!-- Bootstrap core JavaScript
================================================== -->

33
ordr/templates/pages/welcome.jinja2

@ -1,8 +1,35 @@ @@ -1,8 +1,35 @@
{% extends "ordr:templates/layout.jinja2" %}
{% block content %}
<div class="content">
<h1>Ordr</h1>
<p class="lead">Welcome to <span class="font-normal">Ordr</span>, a&nbsp;Pyramid application generated&nbsp;by<br><span class="font-normal">Cookiecutter</span>.</p>
<div class="row mt-5">
<div class="col-8 offset-2">
<div class="jumbotron">
<h1 class="display-4">Welcome to <span class="text-primary">ordr</span>!</h1>
<p class="lead">An order management system to simplify your shopping for laborartory supplies.</p>
</div>
</div>
</div>
<div class="row">
<div class="col-4 offset-2">
<h4 class="mb-4">Login</h4>
<form action="/login" method="POST">
<div class="form-group">
<input type="text" class="form-control" id="input-username" placeholder="Username" name="username" autofocus="autofocus">
</div>
<div class="form-group">
<input type="text" class="form-control" id="input-password" placeholder="Password" name="password">
</div>
<button type="submit" class="btn btn-primary">Login</button>
<small class="float-right mt-2"><a href="/forgot">Forgot your password?</a></small>
</form>
</div>
<div class="col-4">
<h4 class="mb-4">Register</h4>
<p>
Registration is easy as 1-2-3.
Just fill out the <a href="/register">form</a> and as soon as your
account has been activated you can start shopping.
</p>
</div>
</div>
{% endblock content %}

9
tests/_functional/__init__.py

@ -14,6 +14,15 @@ class CustomTestApp(webtest.TestApp): @@ -14,6 +14,15 @@ class CustomTestApp(webtest.TestApp):
''' might add custom functionality to webtest.TestApp '''
pass
def login(self, username, password):
''' stub for user login '''
self.logout()
pass
def logout(self):
''' stub for user logout '''
pass
def create_users(dbsession):
''' create example users '''

38
tests/_functional/layout.py

@ -0,0 +1,38 @@ @@ -0,0 +1,38 @@
''' functional tests for ordr2.templates.layout
The tests for the layout are performed on '/faqs' or '/orders', since these
two urls are accessible by either everyone or all active users
'''
import pytest
from . import testapp # noqa: F401
def test_navbar_no_user(testapp): # noqa: F811
result = testapp.get('/faq')
navbar = result.html.find('nav', class_='navbar-dark')
expected = ['/', '/', '/faq', '/register']
hrefs = [a['href'] for a in navbar.find_all('a')]
assert expected == hrefs
assert '/orders' not in result
assert 'nav-item dropdown' not in result
@pytest.mark.xfail # noqa: F811
@pytest.mark.parametrize(
'username,password,expected', [
('user', 'password', ['/', '/orders', '/logout', '/account']),
('purchaser', 'password', ['/', '/orders', '/logout', '/account']),
('admin', 'password', [
'/', '/orders', '/admin', '/logout', '/account'
]),
]
)
def test_navbar_with_user(testapp, username, password, expected):
testapp.login(username, password)
result = testapp.get('/faq')
navbar = result.html.find('nav', class_='navbar-dark')
hrefs = [a['href'] for a in navbar.find_all('a')]
assert expected == hrefs
assert 'nav-item dropdown' in result

15
tests/_functional/pages.py

@ -5,9 +5,20 @@ from . import testapp # noqa: F401 @@ -5,9 +5,20 @@ from . import testapp # noqa: F401
def test_welcome(testapp): # noqa: F811
result = testapp.get('/')
assert 'Ordr' in result
active = result.html.find('li', class_='active')
assert active.a['href'] == '/'
expected = {'/', '/faq', '/register', '/forgot', '/register'}
hrefs = {a['href'] for a in result.html.find_all('a')}
assert expected == hrefs
forms = result.html.find_all('form')
assert len(forms) == 1
login_form = forms[0]
assert login_form['action'] == '/login'
assert login_form['method'] == 'POST'
assert 'wrong username' not in result
def test_faq(testapp): # noqa: F811
result = testapp.get('/faq')
assert 'FAQ' in result
active = result.html.find('li', class_='active')
assert active.a['href'] == '/faq'