From 2ebf9ba931895f32d7657847fbb7f0bf4a728219 Mon Sep 17 00:00:00 2001 From: Dave Cranwell Date: Thu, 17 Apr 2014 17:54:54 +0100 Subject: [PATCH 001/141] first commit of new styleguide --- .../wagtailadmin/scss/layouts/styleguide.scss | 77 +++++++ .../wagtailadmin/styleguide/base.html | 213 ++++++++++++++++++ wagtail/wagtailadmin/urls.py | 2 + wagtail/wagtailadmin/views/styleguide.py | 9 + 4 files changed, 301 insertions(+) create mode 100644 wagtail/wagtailadmin/static/wagtailadmin/scss/layouts/styleguide.scss create mode 100644 wagtail/wagtailadmin/templates/wagtailadmin/styleguide/base.html create mode 100644 wagtail/wagtailadmin/views/styleguide.py diff --git a/wagtail/wagtailadmin/static/wagtailadmin/scss/layouts/styleguide.scss b/wagtail/wagtailadmin/static/wagtailadmin/scss/layouts/styleguide.scss new file mode 100644 index 000000000..8e0894baa --- /dev/null +++ b/wagtail/wagtailadmin/static/wagtailadmin/scss/layouts/styleguide.scss @@ -0,0 +1,77 @@ +@import "../variables.scss"; +@import "../mixins.scss"; +@import "../grid.scss"; + +section{ + border-top:1px solid $color-grey-3; + padding:0 0 2em 0; + + > h2:first-child{ + margin:0; + font-size:1em; + background:$color-grey-4; + padding:1em; + margin-bottom:1em; + } +} + +#palette{ + @include clearfix(); + + ul{ + @include clearfix(); + @include unlist(); + } + + li{ + float:left; + width:100px; + height:100px; + padding:10px; + color:black; + } + + .color-teal{ + background-color:$color-teal; + } + .color-teal-darker{ + background-color:$color-teal-darker; + } + .color-teal-dark{ + background-color:$color-teal-dark; + } + .color-red{ + background-color:$color-red; + } + .color-orange{ + background-color:$color-orange; + } + .color-green{ + background-color:$color-green; + } + .color-grey-1{ + background-color:$color-grey-1; + } + .color-grey-1-1{ + background-color:$color-grey-1-1; + } + .color-grey-2{ + background-color:$color-grey-2; + } + .color-grey-3{ + background-color:$color-grey-3; + } + .color-grey-4{ + background-color:$color-grey-4; + } + .color-grey-5{ + background-color:$color-grey-5; + } +} + + +#icons{ + ul{ + @include unlist(); + } +} \ No newline at end of file diff --git a/wagtail/wagtailadmin/templates/wagtailadmin/styleguide/base.html b/wagtail/wagtailadmin/templates/wagtailadmin/styleguide/base.html new file mode 100644 index 000000000..9f9eea922 --- /dev/null +++ b/wagtail/wagtailadmin/templates/wagtailadmin/styleguide/base.html @@ -0,0 +1,213 @@ +{% extends "wagtailadmin/base.html" %} +{% load wagtailadmin_tags %} +{% load compress i18n %} + +{% block extra_css %} + {% compress css %} + + {% endcompress %} +{% endblock %} + +{% block titletag %}{% trans 'Styleguide' %}{% endblock %} +{% block bodyclass %}styleguide{% endblock %} + +{% block content %} + {% trans "Styleguide" as title_trans %} + {% include "wagtailadmin/shared/header.html" with title=title_trans %} + +
+

Styleguide

+ + +
+

Colour palette

+ +
    +
  • color-teal
  • +
  • color-teal-darker
  • +
  • color-teal-dark
  • +
  • color-red
  • +
  • color-orange
  • +
  • color-green
  • +
+
    +
  • color-grey-1
  • +
  • color-grey-1-1
  • +
  • color-grey-2
  • +
  • color-grey-3
  • +
  • color-grey-4
  • +
  • color-grey-5
  • +
+
+ +
+

Typography

+

This is an h1

+

This is an h2

+

This is an h3

+

This is an h4

+
This is an h5
+

This is a paragraph

+ +
    +
  • These are
  • +
  • items in an
  • +
  • unordered list
  • +
+ +
    +
  1. These are
  2. +
  3. items in an
  4. +
  5. ordered list
  6. +
+ +
+ +
+

Listings

+
+ +
+

Buttons

+ +
button
+ +
button-secondary
+ +
yes
+ +
no / serious
+ +
bicolor with icon
+ +
button-small
+ +
bicolo button-small
+ +
mixed
+ +
+ + + + + +
+

Messages

+
+ +
+

Forms

+
+ +
+

Page editor

+
+ +
+

Tabs

+
+ + + +
+

Misc formatters

+

Avatar icons

+

Status tags

+
+ +
+

Icons

+ +
    +
  • wagtail
  • +
  • wagtail-inverse
  • +
  • cogs
  • +
  • doc-empty-inverse
  • +
  • doc-empty
  • +
  • edit
  • +
  • arrow-up
  • +
  • arrow-down
  • + +
  • cross
  • +
  • folder-open-1
  • +
  • folder-inverse
  • +
  • mail
  • +
  • arrows-up-down
  • +
  • locked
  • +
  • unlocked
  • +
  • arrow-right
  • +
  • doc-full / file-text-alt
  • +
  • image / picture
  • +
  • doc-full-inverse
  • +
  • folder
  • +
  • plus
  • +
  • tag
  • +
  • folder-open-inverse
  • +
  • cog
  • +
  • tick
  • +
  • user
  • +
  • arrow-left
  • +
  • tick-inverse
  • +
  • plus-inverse
  • +
  • snippet
  • +
  • bold
  • +
  • italic
  • +
  • undo
  • +
  • repeat
  • +
  • list-ol
  • +
  • list-ul
  • + +
  • radio-full
  • +
  • radio-empty
  • +
  • arrow-up-big
  • +
  • arrow-down-big
  • +
  • group
  • +
  • media
  • +
  • horizontalrule
  • +
  • password
  • +
  • download
  • +
  • order
  • +
  • grip
  • +
  • home
  • +
  • order-down
  • +
  • order-up
  • +
  • bin
  • +
  • spinner
  • +
  • pick
  • +
  • redirect
  • +
  • view
  • +
  • collapse-up
  • +
  • collapse-down
  • +
  • help
  • +
  • warning
  • +
  • success
  • +
+ +
+ + +
+{% endblock %} \ No newline at end of file diff --git a/wagtail/wagtailadmin/urls.py b/wagtail/wagtailadmin/urls.py index 3b1a98535..1241004a2 100644 --- a/wagtail/wagtailadmin/urls.py +++ b/wagtail/wagtailadmin/urls.py @@ -82,4 +82,6 @@ urlpatterns += patterns( url(r'^userbar/(\d+)/$', 'userbar.for_frontend', name='wagtailadmin_userbar_frontend'), url(r'^userbar/moderation/(\d+)/$', 'userbar.for_moderation', name='wagtailadmin_userbar_moderation'), + + url(r'^styleguide/$', 'styleguide.index', name='wagtailadmin_styleguide'), ) diff --git a/wagtail/wagtailadmin/views/styleguide.py b/wagtail/wagtailadmin/views/styleguide.py new file mode 100644 index 000000000..33c87034c --- /dev/null +++ b/wagtail/wagtailadmin/views/styleguide.py @@ -0,0 +1,9 @@ +from django.shortcuts import render + +from wagtail.wagtailadmin.userbar import EditPageItem, AddPageItem, ApproveModerationEditPageItem, RejectModerationEditPageItem +from wagtail.wagtailadmin import hooks +from wagtail.wagtailcore.models import Page, PageRevision + +def index(request): + # Render the edit bird + return render(request, 'wagtailadmin/styleguide/base.html', {}) From f9f07f4a83eee89fd740393b364b5744d62e9562 Mon Sep 17 00:00:00 2001 From: Dave Cranwell Date: Wed, 30 Apr 2014 11:37:38 +0100 Subject: [PATCH 002/141] altered buttons --- .../wagtailadmin/templates/wagtailadmin/styleguide/base.html | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/wagtail/wagtailadmin/templates/wagtailadmin/styleguide/base.html b/wagtail/wagtailadmin/templates/wagtailadmin/styleguide/base.html index 9f9eea922..75f5bcc17 100644 --- a/wagtail/wagtailadmin/templates/wagtailadmin/styleguide/base.html +++ b/wagtail/wagtailadmin/templates/wagtailadmin/styleguide/base.html @@ -100,7 +100,9 @@
bicolo button-small
-
mixed
+
mixed 1
+ +
mixed 2
From 0f3b74817f7c1fa741c2e5fad18de51f12c323d9 Mon Sep 17 00:00:00 2001 From: Dave Cranwell Date: Thu, 8 May 2014 14:26:32 +0100 Subject: [PATCH 003/141] updates to styleguide --- .../scss/components/dropdowns.scss | 53 ++--- .../scss/components/formatters.scss | 4 + .../wagtailadmin/scss/components/listing.scss | 2 + .../wagtailadmin/scss/layouts/styleguide.scss | 13 +- .../wagtailadmin/styleguide/base.html | 186 +++++++++++++++++- wagtail/wagtailadmin/urls.py | 4 +- wagtail/wagtailadmin/views/styleguide.py | 44 ++++- 7 files changed, 269 insertions(+), 37 deletions(-) diff --git a/wagtail/wagtailadmin/static/wagtailadmin/scss/components/dropdowns.scss b/wagtail/wagtailadmin/static/wagtailadmin/scss/components/dropdowns.scss index ee618f377..1428f0fd9 100644 --- a/wagtail/wagtailadmin/static/wagtailadmin/scss/components/dropdowns.scss +++ b/wagtail/wagtailadmin/static/wagtailadmin/scss/components/dropdowns.scss @@ -3,7 +3,18 @@ @include clearfix(); .dropdown-toggle{ + color:white; + text-transform:uppercase; + background-color:$color-teal; + line-height:3em; + padding-left:1em; + padding-right:1em; cursor:pointer; + + &:before, + &:after{ + margin:0; + } } input[type=button], input[type=submit], button, .button{ @@ -27,10 +38,9 @@ li{ float:none; - border-top:1px solid rgba(255,255,255,0.2); - } - li:first-child{ - border-top:0; + border-color: rgba(255,255,255,0.2); + border-style: solid; + border-width:1px 0 0 0; } a{ @@ -101,6 +111,10 @@ @include box-shadow(0px -3px 3px 0 rgba(0,0,0,0.2)); top:auto; bottom:100%; + + li{ + border-width:0 0 1px 0; + } } @@ -134,10 +148,22 @@ } /* Styles for dropdowns which are also buttons e.g page editor */ + &.dropdown-button{ .dropdown-toggle{ @include border-radius(0 3px 3px 0); } + &.open{ + > input[type=button], > input[type=submit], > button, > .button{ + @include border-radius(3px 3px 0px 0px); + } + .dropdown-toggle{ + @include border-radius(0 3px 0 0); + } + } + } + + &.dropup.dropdown-button{ &.open{ > input[type=button], > input[type=submit], > button, > .button{ @include border-radius(0 0 3px 3px); @@ -215,25 +241,6 @@ h2 .dropdown{ } -footer .actions .dropdown-toggle{ - text-transform:uppercase; - background-color:$color-teal; - line-height:3em; - color:white; - padding-left:1em; - padding-right:1em; - - &:before, - &:after{ - margin:0; - } -} - -footer .actions .dropdown ul li{ - border-bottom:1px solid rgba(255,255,255,0.2); - border-top:0; -} - /* Transitions */ .dropdown ul{ diff --git a/wagtail/wagtailadmin/static/wagtailadmin/scss/components/formatters.scss b/wagtail/wagtailadmin/static/wagtailadmin/scss/components/formatters.scss index 569821e10..150611f8f 100644 --- a/wagtail/wagtailadmin/static/wagtailadmin/scss/components/formatters.scss +++ b/wagtail/wagtailadmin/static/wagtailadmin/scss/components/formatters.scss @@ -177,4 +177,8 @@ a.tag:hover{ /* make a block-level element inline */ .inline{ display:inline; +} + +.unlist{ + @include unlist(); } \ No newline at end of file diff --git a/wagtail/wagtailadmin/static/wagtailadmin/scss/components/listing.scss b/wagtail/wagtailadmin/static/wagtailadmin/scss/components/listing.scss index edf5e65f8..e79d8b28d 100644 --- a/wagtail/wagtailadmin/static/wagtailadmin/scss/components/listing.scss +++ b/wagtail/wagtailadmin/static/wagtailadmin/scss/components/listing.scss @@ -52,6 +52,7 @@ ul.listing{ } } + /* .dropdown{ padding:0; } @@ -65,6 +66,7 @@ ul.listing{ background-color:white; margin-left:-$grid-gutter-width * 2; } + */ } &.full-width td:first-child, diff --git a/wagtail/wagtailadmin/static/wagtailadmin/scss/layouts/styleguide.scss b/wagtail/wagtailadmin/static/wagtailadmin/scss/layouts/styleguide.scss index 8e0894baa..18c40d2d8 100644 --- a/wagtail/wagtailadmin/static/wagtailadmin/scss/layouts/styleguide.scss +++ b/wagtail/wagtailadmin/static/wagtailadmin/scss/layouts/styleguide.scss @@ -2,8 +2,11 @@ @import "../mixins.scss"; @import "../grid.scss"; + + section{ border-top:1px solid $color-grey-3; + margin-top:2em; padding:0 0 2em 0; > h2:first-child{ @@ -71,7 +74,15 @@ section{ #icons{ + :before, :after{ + font-size:2em; + } ul{ - @include unlist(); + -webkit-column-count:3; /* Chrome, Safari, Opera */ + -moz-column-count:3; /* Firefox */ + column-count:3; + } + li{ + margin-bottom:1em; } } \ No newline at end of file diff --git a/wagtail/wagtailadmin/templates/wagtailadmin/styleguide/base.html b/wagtail/wagtailadmin/templates/wagtailadmin/styleguide/base.html index 75f5bcc17..acb90f138 100644 --- a/wagtail/wagtailadmin/templates/wagtailadmin/styleguide/base.html +++ b/wagtail/wagtailadmin/templates/wagtailadmin/styleguide/base.html @@ -1,6 +1,7 @@ {% extends "wagtailadmin/base.html" %} {% load wagtailadmin_tags %} {% load compress i18n %} +{% load gravatar %} {% block extra_css %} {% compress css %} @@ -16,16 +17,15 @@ {% include "wagtailadmin/shared/header.html" with title=title_trans %}
-

Styleguide

+

Contents

+ + +{% endblock %} + +{% block extra_js %} + {% endblock %} \ No newline at end of file From 5a840c421bc813c71206aff9d4a6ba5172b6939f Mon Sep 17 00:00:00 2001 From: Dave Cranwell Date: Tue, 13 May 2014 13:05:46 +0100 Subject: [PATCH 013/141] added form icon to font, font icomoon project and styleguide --- .../wagtailadmin/scss/components/icons.scss | 3 + .../scss/fonts/wagtail-icomoon.json | 282 ++++++++++-------- .../wagtailadmin/scss/fonts/wagtail.eot | Bin 25940 -> 26032 bytes .../wagtailadmin/scss/fonts/wagtail.svg | 1 + .../wagtailadmin/scss/fonts/wagtail.ttf | Bin 25776 -> 25868 bytes .../wagtailadmin/scss/fonts/wagtail.woff | Bin 15000 -> 15080 bytes .../wagtailadmin/styleguide/base.html | 1 + 7 files changed, 158 insertions(+), 129 deletions(-) diff --git a/wagtail/wagtailadmin/static/wagtailadmin/scss/components/icons.scss b/wagtail/wagtailadmin/static/wagtailadmin/scss/components/icons.scss index 9319d7bd1..a1aa3cca0 100644 --- a/wagtail/wagtailadmin/static/wagtailadmin/scss/components/icons.scss +++ b/wagtail/wagtailadmin/static/wagtailadmin/scss/components/icons.scss @@ -243,6 +243,9 @@ .icon-date:before{ content:"7"; } +.icon-form:before{ + content:"$"; +} .icon.text-replace{ font-size:0em; line-height:0; diff --git a/wagtail/wagtailadmin/static/wagtailadmin/scss/fonts/wagtail-icomoon.json b/wagtail/wagtailadmin/static/wagtailadmin/scss/fonts/wagtail-icomoon.json index 654e78566..fead2733b 100755 --- a/wagtail/wagtailadmin/static/wagtailadmin/scss/fonts/wagtail-icomoon.json +++ b/wagtail/wagtailadmin/static/wagtailadmin/scss/fonts/wagtail-icomoon.json @@ -1,6 +1,27 @@ { "IcoMoonType": "selection", "icons": [ + { + "icon": { + "paths": [ + "M102.030 101.608v819.555h819.555v-819.555h-819.555zM352.717 791.689h-165.288v-85.398h301.65v85.398zM792.109 360.562h-604.678v-128.099h603.303v128.099zM790.731 591.965h-603.303v-128.099h603.303v128.099z" + ], + "grid": 0, + "tags": [ + "form" + ] + }, + "properties": { + "order": 1, + "id": 63, + "prevSize": 32, + "code": 36, + "name": "form", + "ligatures": "" + }, + "setIdx": 0, + "iconIdx": 0 + }, { "icon": { "paths": [ @@ -11,14 +32,14 @@ }, "properties": { "id": 0, - "order": 1, + "order": 2, "prevSize": 32, "code": 97, "name": "uni61", "ligatures": "" }, "setIdx": 0, - "iconIdx": 0 + "iconIdx": 1 }, { "icon": { @@ -30,14 +51,14 @@ }, "properties": { "id": 1, - "order": 2, + "order": 3, "prevSize": 32, "code": 98, "name": "uni62", "ligatures": "" }, "setIdx": 0, - "iconIdx": 1 + "iconIdx": 2 }, { "icon": { @@ -49,14 +70,14 @@ }, "properties": { "id": 2, - "order": 3, + "order": 4, "prevSize": 32, "code": 99, "name": "uni63", "ligatures": "" }, "setIdx": 0, - "iconIdx": 2 + "iconIdx": 3 }, { "icon": { @@ -68,14 +89,14 @@ }, "properties": { "id": 3, - "order": 4, + "order": 5, "prevSize": 32, "code": 100, "name": "uni64", "ligatures": "" }, "setIdx": 0, - "iconIdx": 3 + "iconIdx": 4 }, { "icon": { @@ -87,14 +108,14 @@ }, "properties": { "id": 4, - "order": 5, + "order": 6, "prevSize": 32, "code": 101, "name": "uni65", "ligatures": "" }, "setIdx": 0, - "iconIdx": 4 + "iconIdx": 5 }, { "icon": { @@ -106,14 +127,14 @@ }, "properties": { "id": 5, - "order": 6, + "order": 7, "prevSize": 32, "code": 102, "name": "uni66", "ligatures": "" }, "setIdx": 0, - "iconIdx": 5 + "iconIdx": 6 }, { "icon": { @@ -125,14 +146,14 @@ }, "properties": { "id": 6, - "order": 7, + "order": 8, "prevSize": 32, "code": 103, "name": "uni67", "ligatures": "" }, "setIdx": 0, - "iconIdx": 6 + "iconIdx": 7 }, { "icon": { @@ -144,14 +165,14 @@ }, "properties": { "id": 7, - "order": 8, + "order": 9, "prevSize": 32, "code": 105, "name": "uni69", "ligatures": "" }, "setIdx": 0, - "iconIdx": 7 + "iconIdx": 8 }, { "icon": { @@ -163,14 +184,14 @@ }, "properties": { "id": 8, - "order": 9, + "order": 10, "prevSize": 32, "code": 106, "name": "uni6A", "ligatures": "" }, "setIdx": 0, - "iconIdx": 8 + "iconIdx": 9 }, { "icon": { @@ -182,14 +203,14 @@ }, "properties": { "id": 9, - "order": 10, + "order": 11, "prevSize": 32, "code": 107, "name": "uni6B", "ligatures": "" }, "setIdx": 0, - "iconIdx": 9 + "iconIdx": 10 }, { "icon": { @@ -201,14 +222,14 @@ }, "properties": { "id": 10, - "order": 11, + "order": 12, "prevSize": 32, "code": 108, "name": "uni6C", "ligatures": "" }, "setIdx": 0, - "iconIdx": 10 + "iconIdx": 11 }, { "icon": { @@ -220,14 +241,14 @@ }, "properties": { "id": 11, - "order": 12, + "order": 13, "prevSize": 32, "code": 109, "name": "uni6D", "ligatures": "" }, "setIdx": 0, - "iconIdx": 11 + "iconIdx": 12 }, { "icon": { @@ -239,14 +260,14 @@ }, "properties": { "id": 12, - "order": 13, + "order": 14, "prevSize": 32, "code": 110, "name": "uni6E", "ligatures": "" }, "setIdx": 0, - "iconIdx": 12 + "iconIdx": 13 }, { "icon": { @@ -258,14 +279,14 @@ }, "properties": { "id": 13, - "order": 14, + "order": 15, "prevSize": 32, "code": 104, "name": "uni68", "ligatures": "" }, "setIdx": 0, - "iconIdx": 13 + "iconIdx": 14 }, { "icon": { @@ -277,14 +298,14 @@ }, "properties": { "id": 14, - "order": 15, + "order": 16, "prevSize": 32, "code": 111, "name": "uni6F", "ligatures": "" }, "setIdx": 0, - "iconIdx": 14 + "iconIdx": 15 }, { "icon": { @@ -296,14 +317,14 @@ }, "properties": { "id": 15, - "order": 16, + "order": 17, "prevSize": 32, "code": 112, "name": "uni70", "ligatures": "" }, "setIdx": 0, - "iconIdx": 15 + "iconIdx": 16 }, { "icon": { @@ -315,14 +336,14 @@ }, "properties": { "id": 16, - "order": 17, + "order": 18, "prevSize": 32, "code": 113, "name": "uni71", "ligatures": "" }, "setIdx": 0, - "iconIdx": 16 + "iconIdx": 17 }, { "icon": { @@ -334,14 +355,14 @@ }, "properties": { "id": 17, - "order": 18, + "order": 19, "prevSize": 32, "code": 114, "name": "uni72", "ligatures": "" }, "setIdx": 0, - "iconIdx": 17 + "iconIdx": 18 }, { "icon": { @@ -353,14 +374,14 @@ }, "properties": { "id": 18, - "order": 19, + "order": 20, "prevSize": 32, "code": 115, "name": "uni73", "ligatures": "" }, "setIdx": 0, - "iconIdx": 18 + "iconIdx": 19 }, { "icon": { @@ -372,14 +393,14 @@ }, "properties": { "id": 19, - "order": 20, + "order": 21, "prevSize": 32, "code": 116, "name": "uni74", "ligatures": "" }, "setIdx": 0, - "iconIdx": 19 + "iconIdx": 20 }, { "icon": { @@ -391,14 +412,14 @@ }, "properties": { "id": 20, - "order": 21, + "order": 22, "prevSize": 32, "code": 117, "name": "uni75", "ligatures": "" }, "setIdx": 0, - "iconIdx": 20 + "iconIdx": 21 }, { "icon": { @@ -410,14 +431,14 @@ }, "properties": { "id": 21, - "order": 22, + "order": 23, "prevSize": 32, "code": 118, "name": "uni76", "ligatures": "" }, "setIdx": 0, - "iconIdx": 21 + "iconIdx": 22 }, { "icon": { @@ -429,14 +450,14 @@ }, "properties": { "id": 22, - "order": 23, + "order": 24, "prevSize": 32, "code": 119, "name": "uni77", "ligatures": "" }, "setIdx": 0, - "iconIdx": 22 + "iconIdx": 23 }, { "icon": { @@ -448,14 +469,14 @@ }, "properties": { "id": 23, - "order": 24, + "order": 25, "prevSize": 32, "code": 120, "name": "uni78", "ligatures": "" }, "setIdx": 0, - "iconIdx": 23 + "iconIdx": 24 }, { "icon": { @@ -467,14 +488,14 @@ }, "properties": { "id": 24, - "order": 25, + "order": 26, "prevSize": 32, "code": 122, "name": "uni7A", "ligatures": "" }, "setIdx": 0, - "iconIdx": 24 + "iconIdx": 25 }, { "icon": { @@ -486,14 +507,14 @@ }, "properties": { "id": 25, - "order": 26, + "order": 27, "prevSize": 32, "code": 65, "name": "uni41", "ligatures": "" }, "setIdx": 0, - "iconIdx": 25 + "iconIdx": 26 }, { "icon": { @@ -505,14 +526,14 @@ }, "properties": { "id": 26, - "order": 27, + "order": 28, "prevSize": 32, "code": 66, "name": "uni42", "ligatures": "" }, "setIdx": 0, - "iconIdx": 26 + "iconIdx": 27 }, { "icon": { @@ -524,14 +545,14 @@ }, "properties": { "id": 27, - "order": 28, + "order": 29, "prevSize": 32, "code": 68, "name": "uni44", "ligatures": "" }, "setIdx": 0, - "iconIdx": 27 + "iconIdx": 28 }, { "icon": { @@ -543,14 +564,14 @@ }, "properties": { "id": 28, - "order": 29, + "order": 30, "prevSize": 32, "code": 67, "name": "uni43", "ligatures": "" }, "setIdx": 0, - "iconIdx": 28 + "iconIdx": 29 }, { "icon": { @@ -562,14 +583,14 @@ }, "properties": { "id": 29, - "order": 30, + "order": 31, "prevSize": 32, "code": 69, "name": "uni45", "ligatures": "" }, "setIdx": 0, - "iconIdx": 29 + "iconIdx": 30 }, { "icon": { @@ -581,14 +602,14 @@ }, "properties": { "id": 30, - "order": 31, + "order": 32, "prevSize": 32, "code": 70, "name": "uni46", "ligatures": "" }, "setIdx": 0, - "iconIdx": 30 + "iconIdx": 31 }, { "icon": { @@ -600,14 +621,14 @@ }, "properties": { "id": 31, - "order": 32, + "order": 33, "prevSize": 32, "code": 71, "name": "uni47", "ligatures": "" }, "setIdx": 0, - "iconIdx": 31 + "iconIdx": 32 }, { "icon": { @@ -619,14 +640,14 @@ }, "properties": { "id": 32, - "order": 33, + "order": 34, "prevSize": 32, "code": 72, "name": "uni48", "ligatures": "" }, "setIdx": 0, - "iconIdx": 32 + "iconIdx": 33 }, { "icon": { @@ -638,14 +659,14 @@ }, "properties": { "id": 33, - "order": 34, + "order": 35, "prevSize": 32, "code": 73, "name": "uni49", "ligatures": "" }, "setIdx": 0, - "iconIdx": 33 + "iconIdx": 34 }, { "icon": { @@ -657,14 +678,14 @@ }, "properties": { "id": 34, - "order": 35, + "order": 36, "prevSize": 32, "code": 74, "name": "uni4A", "ligatures": "" }, "setIdx": 0, - "iconIdx": 34 + "iconIdx": 35 }, { "icon": { @@ -676,14 +697,14 @@ }, "properties": { "id": 35, - "order": 36, + "order": 37, "prevSize": 32, "code": 75, "name": "uni4B", "ligatures": "" }, "setIdx": 0, - "iconIdx": 35 + "iconIdx": 36 }, { "icon": { @@ -695,14 +716,14 @@ }, "properties": { "id": 36, - "order": 37, + "order": 38, "prevSize": 32, "code": 76, "name": "uni4C", "ligatures": "" }, "setIdx": 0, - "iconIdx": 36 + "iconIdx": 37 }, { "icon": { @@ -714,14 +735,14 @@ }, "properties": { "id": 37, - "order": 38, + "order": 39, "prevSize": 32, "code": 77, "name": "uni4D", "ligatures": "" }, "setIdx": 0, - "iconIdx": 37 + "iconIdx": 38 }, { "icon": { @@ -733,14 +754,14 @@ }, "properties": { "id": 38, - "order": 39, + "order": 40, "prevSize": 32, "code": 78, "name": "uni4E", "ligatures": "" }, "setIdx": 0, - "iconIdx": 38 + "iconIdx": 39 }, { "icon": { @@ -752,14 +773,14 @@ }, "properties": { "id": 39, - "order": 40, + "order": 41, "prevSize": 32, "code": 79, "name": "uni4F", "ligatures": "" }, "setIdx": 0, - "iconIdx": 39 + "iconIdx": 40 }, { "icon": { @@ -771,14 +792,14 @@ }, "properties": { "id": 40, - "order": 41, + "order": 42, "prevSize": 32, "code": 80, "name": "uni50", "ligatures": "" }, "setIdx": 0, - "iconIdx": 40 + "iconIdx": 41 }, { "icon": { @@ -790,14 +811,14 @@ }, "properties": { "id": 41, - "order": 42, + "order": 43, "prevSize": 32, "code": 81, "name": "uni51", "ligatures": "" }, "setIdx": 0, - "iconIdx": 41 + "iconIdx": 42 }, { "icon": { @@ -809,14 +830,14 @@ }, "properties": { "id": 42, - "order": 43, + "order": 44, "prevSize": 32, "code": 121, "name": "uni79", "ligatures": "" }, "setIdx": 0, - "iconIdx": 42 + "iconIdx": 43 }, { "icon": { @@ -828,14 +849,14 @@ }, "properties": { "id": 43, - "order": 44, + "order": 45, "prevSize": 32, "code": 82, "name": "uni52", "ligatures": "" }, "setIdx": 0, - "iconIdx": 43 + "iconIdx": 44 }, { "icon": { @@ -847,14 +868,14 @@ }, "properties": { "id": 44, - "order": 45, + "order": 46, "prevSize": 32, "code": 84, "name": "uni54", "ligatures": "" }, "setIdx": 0, - "iconIdx": 44 + "iconIdx": 45 }, { "icon": { @@ -866,14 +887,14 @@ }, "properties": { "id": 45, - "order": 46, + "order": 47, "prevSize": 32, "code": 87, "name": "uni57", "ligatures": "" }, "setIdx": 0, - "iconIdx": 45 + "iconIdx": 46 }, { "icon": { @@ -885,14 +906,14 @@ }, "properties": { "id": 46, - "order": 47, + "order": 48, "prevSize": 32, "code": 88, "name": "uni58", "ligatures": "" }, "setIdx": 0, - "iconIdx": 46 + "iconIdx": 47 }, { "icon": { @@ -904,14 +925,14 @@ }, "properties": { "id": 47, - "order": 48, + "order": 49, "prevSize": 32, "code": 89, "name": "uni59", "ligatures": "" }, "setIdx": 0, - "iconIdx": 47 + "iconIdx": 48 }, { "icon": { @@ -923,14 +944,14 @@ }, "properties": { "id": 48, - "order": 49, + "order": 50, "prevSize": 32, "code": 90, "name": "uni5A", "ligatures": "" }, "setIdx": 0, - "iconIdx": 48 + "iconIdx": 49 }, { "icon": { @@ -942,14 +963,14 @@ }, "properties": { "id": 49, - "order": 50, + "order": 51, "prevSize": 32, "code": 86, "name": "uni56", "ligatures": "" }, "setIdx": 0, - "iconIdx": 49 + "iconIdx": 50 }, { "icon": { @@ -961,14 +982,14 @@ }, "properties": { "id": 50, - "order": 51, + "order": 52, "prevSize": 32, "code": 49, "name": "uni31", "ligatures": "" }, "setIdx": 0, - "iconIdx": 50 + "iconIdx": 51 }, { "icon": { @@ -980,14 +1001,14 @@ }, "properties": { "id": 51, - "order": 52, + "order": 53, "prevSize": 32, "code": 85, "name": "uni55", "ligatures": "" }, "setIdx": 0, - "iconIdx": 51 + "iconIdx": 52 }, { "icon": { @@ -999,14 +1020,14 @@ }, "properties": { "id": 52, - "order": 53, + "order": 54, "prevSize": 32, "code": 51, "name": "uni33", "ligatures": "" }, "setIdx": 0, - "iconIdx": 52 + "iconIdx": 53 }, { "icon": { @@ -1018,14 +1039,14 @@ }, "properties": { "id": 53, - "order": 54, + "order": 55, "prevSize": 32, "code": 50, "name": "uni32", "ligatures": "" }, "setIdx": 0, - "iconIdx": 53 + "iconIdx": 54 }, { "icon": { @@ -1037,14 +1058,14 @@ }, "properties": { "id": 54, - "order": 55, + "order": 56, "prevSize": 32, "code": 53, "name": "uni35", "ligatures": "" }, "setIdx": 0, - "iconIdx": 54 + "iconIdx": 55 }, { "icon": { @@ -1056,14 +1077,14 @@ }, "properties": { "id": 55, - "order": 56, + "order": 57, "prevSize": 32, "code": 54, "name": "uni36", "ligatures": "" }, "setIdx": 0, - "iconIdx": 55 + "iconIdx": 56 }, { "icon": { @@ -1075,14 +1096,14 @@ }, "properties": { "id": 56, - "order": 57, + "order": 58, "prevSize": 32, "code": 48, "name": "uni30", "ligatures": "" }, "setIdx": 0, - "iconIdx": 56 + "iconIdx": 57 }, { "icon": { @@ -1094,14 +1115,14 @@ }, "properties": { "id": 57, - "order": 58, + "order": 59, "prevSize": 32, "code": 63, "name": "uni3F", "ligatures": "" }, "setIdx": 0, - "iconIdx": 57 + "iconIdx": 58 }, { "icon": { @@ -1113,14 +1134,14 @@ }, "properties": { "id": 58, - "order": 59, + "order": 60, "prevSize": 32, "code": 33, "name": "uni21", "ligatures": "" }, "setIdx": 0, - "iconIdx": 58 + "iconIdx": 59 }, { "icon": { @@ -1132,14 +1153,14 @@ }, "properties": { "id": 59, - "order": 60, + "order": 61, "prevSize": 32, "code": 57, "name": "uni39", "ligatures": "" }, "setIdx": 0, - "iconIdx": 59 + "iconIdx": 60 }, { "icon": { @@ -1151,14 +1172,14 @@ }, "properties": { "id": 60, - "order": 61, + "order": 62, "prevSize": 32, "code": 83, "name": "uni53", "ligatures": "" }, "setIdx": 0, - "iconIdx": 60 + "iconIdx": 61 }, { "icon": { @@ -1170,14 +1191,14 @@ }, "properties": { "id": 61, - "order": 62, + "order": 63, "prevSize": 32, "code": 52, "name": "uni34", "ligatures": "" }, "setIdx": 0, - "iconIdx": 61 + "iconIdx": 62 }, { "icon": { @@ -1189,14 +1210,14 @@ }, "properties": { "id": 62, - "order": 63, + "order": 64, "prevSize": 32, "code": 55, "name": "uni37", "ligatures": "" }, "setIdx": 0, - "iconIdx": 62 + "iconIdx": 63 } ], "height": 1024, @@ -1211,15 +1232,18 @@ "metadata": { "fontFamily": "wagtail", "majorVersion": 1, - "minorVersion": 1 + "minorVersion": 0 }, "metrics": { "emSize": 512, "baseline": 6.25, "whitespace": 50 }, - "embed": false, - "showVersion": true + "includeMetadata": false, + "showMetrics": false, + "showMetadata": false, + "showVersion": false, + "resetPoint": 33 }, "imagePref": {}, "historySize": 100, diff --git a/wagtail/wagtailadmin/static/wagtailadmin/scss/fonts/wagtail.eot b/wagtail/wagtailadmin/static/wagtailadmin/scss/fonts/wagtail.eot index 901b36d6bb81fddc69a64639aa7e2edfe89186a5..c5d6b5cc58b948ee1c15f5abeb6970cb759b23b8 100755 GIT binary patch delta 564 zcmca|igCkfMz#&93=BM}6WPpIUM0`dn&{xeXfV-VbmAhVdd5)3ISdSpG7Jn1CFzO9 z1wdK=$e#eDInr|~(^St#CfWe>X9FPw(Um-6sS2ERrZ^cQV zzy_cO%Yyvk5(Z|V6hq3J$uW%8o(Vvv2+%>y3@i+c42ldY4CV}$4E79B3|0UC{{IhB z$)ErfH2{k`G9-dU8UH{2|M35{|5yKC_<#QYNuX}V$&RVQo3)wL7(H1Sj2VO(&oZtB z8p+AP#~{qWAS|dTs3@##YAkB5XsReG3L=adXZ=g74Vpgv-z7%ff0r3`8Q17bQmjyXrxd2NOgTpRj>;+3 zV`>uWTH%ae_{yGB&26kY;1Ks2@`CjsCMuW+x GQn~;*-I}rh delta 476 zcmdmRn(@jhMz)Yt28InO6WPpI9DH6Zn&{xeXgJYdbmAhVdWI{Ej~EyjWf&M3a?%rv z3xKo$klz8MInr|~)4b0VEdufq%}bKj@-nG0tP>(a|{g0CP2PIUSh6fssaCs zlR$wGpa#o={NfS@W}p;9%7n==jMdH&K&BATLCg$H42%ql4CV}$4E79B3|0UC{{IhB z$DqJq02Xs(NCb;9{(t=c>i;YM&;LL7{{&DU<77o9;mxK@DvX<#GS7{Zlbj_ZHT6h5 zzs*+$ZYHn^=O=nMgBT!sazc{1s54j?N-zRxpgNw-8zS4?y<=u!mSX8+S;2CM zHHNi=Z3(*(2McE$=Q6H7?t8q`_*(e01bzty3H}lC6IvkBAQ~e!Pwbw!n?#YMoYV&C z2W?&xG~Q@7X + diff --git a/wagtail/wagtailadmin/static/wagtailadmin/scss/fonts/wagtail.ttf b/wagtail/wagtailadmin/static/wagtailadmin/scss/fonts/wagtail.ttf index 7e50be989f21b51cc801f25f583b67c6f0d53817..c4161bea849d4ddb060928acbc08627d98cbaa78 100755 GIT binary patch delta 519 zcmdmRlCkF$;{=6z#!$vN3=E7i3=9k<>50V!Kw1FEp8%ve(sL@)RMi)L0P<%rFeET! zq$Z{?_-#vOU`Pb=8O$<(0?dz?RDt{pK)y;wZb?NW1CKY5{{^T=ASXXLQ7M%78UsTz z3sAl*H?g9C!Jp|IkPk9nAulmkGSz@@#Yv#R2A~GZg8bqV248KM}f{{Q{|AEb~$0Vrw!7IkDu1dB5MfBgU9|7-uR{=e}5 z{Qr|c-HZ$jo68u@89iATj2VO(&oZtB8pz4O#~{qWAS|dTs3@##YAkB5XsReG3L=ad zXZ=g74Vpgv-z7%ff0r3`8Q1FwIHU3AEr~3Q^$c5>PBDuxYcV^pY+*Ua@`AOAbsgI& z_6QCw&KAxyTw8cpc=zzF;-4U>AXp)!Bvc}FOk|m8lh_e)7V#X38Imqi*QD#DFUTm# zb|@+-Rw%wx3R7C99HV?k<&^3%H3@Yt^&SlljR;L4%@vwIw03DHXy4LF&}Gn@r1wOB ZodE*_J1~raZgZJzmHe8~V6s|D7XaIIlf(c3 delta 465 zcmeA<#kk=l;{=6zhAWJZ7#J937#J9G(i4jdfV2RR-vOjK(sL@)yw4OZ0`ey?FvM@k zNKH&(aQqm{z>w$ylsC%&3NSxnQUUU7fP9sV+>(lV1|A6@e*sVrPfmVvBF9nLItGTM zH9+}}+{B6k20x~A3=GL8K)ym=Vy8KM}f{{Q{|AEb;yfx!SQ=E#r;7GwPX`2W@aSN@;>fA0SY zpgzXQA5(-kPh?bK+|0;4H%?A+mWnT1)3rH^F=%OTbn)(*BM>_!|coN=7Xxca#7@lNAw;m;EI zB^V_5N61fTfk=aBjMzM}d*W^qMUrw-8>AzoS4sboO;Y%y7^HYY$v~+=*-Uwx$`aKD zs-M)JsHdqv(lF9^quHc+No$I>mG%}LE1g?1Av!-!I|j{0~gqBOdy|4 O-kf}n(QtB8N*4g@bb^!s diff --git a/wagtail/wagtailadmin/static/wagtailadmin/scss/fonts/wagtail.woff b/wagtail/wagtailadmin/static/wagtailadmin/scss/fonts/wagtail.woff index 46fcca86df2ac9f18835a9bff332a42c6dd8132e..484c0b1279783fdfe4d00cef06b333cf25527b9e 100755 GIT binary patch delta 640 zcmbPH`l3{%+~3X3KP1GTfx+qp0~Z4jSS^^m!CZ8rCSSb=1B01IcHXLE{=xc23=HNr zK-mNk=1^icNX|_x0E*24@=HLNF_dvmdSWq9%t8Rj=YV2?jMT&wpqK=ZZwAJG+mbVY zf$ybN6or!DbAJ0wS#*l zuN=Ps|1W`iLe)a2g|mcDi|B|kiQSQqkVunwC1oM?LZ(7CKz6+xpZsCvBIVmE1uEZE z!__#|rmOGNxT?VI;>a^eY z!%?*RkKPZx?(QFYfAqRpzYG3;D{9%@z3sbpcXtBockS;vqQ4Jycc1=#u)Euvwfi@R z=x-nk%H3SSTyH%2r&*b60?_Xw3<3sl^C;~&-oWYX8o*{~%>i^&W|ADd$3<^L| z1F)zgLn2s|@&Duh5C32LfA#-`|L6aooV?ClTo)LW42(b>{6HGSX3(0K{3@Q`<|_j? x6WEyZ(|274F+lX>59a2QE?{9O0n!9i#{iGP+E*vb@Y_FqzM)3jo!evTXnW delta 567 zcmaD+I-^vg+~3X3KP1GTfx&790~Z4jSOqXJGB8fQXeBaHhr6DMfx(Q)@Omwef3Ut0 zko^OwA_0Usl-LcDa}x^~7|bJp{2Va8!uTjXu^1$F1jy%rVu6g*#1x>|86e*bj2%D5 zW&i~l7%W(Td=(I8e#E4bky}y$6w_c}VB`VedIlpNiQL2rpn;YqKt*g|>>R+5mzbLh z6te*;vIJoR{uL(+@{3D=uCJK*!c#PdUlu4_C7^%mnl&3j;gQ*Sri}OdFWlnYEd{SvIiTXXR!6#Ad=C&i;qvI+q?-1$QRTJ-!S4 zy9DM5SqpUwYYBG?zY#qoHb?x1gqp-E$sbZHWGrL_WbVmnS6and|FsiztaTphI_a6{eb?vhHBd6RY*b`)(Ri-$zscX2IydiUt}|w2 zm~3NS?hFc0AqD{kW(JTO6&cJKEE((>q8O_F|NZ|TD96B{z+eCtb7V*ai!uIx{Qv6z zEC0{`KllFxP#-A%gtdY32vpAxGy@nKlCu`Q@NtOexB1Gz4UAPFI6u+58AeaGu`m~P e1`9(8kS3ryp2warning
  • success
  • date
  • +
  • form
  • From bc99de529be8259e71a334fb4295f775233b10e7 Mon Sep 17 00:00:00 2001 From: Robert Clark Date: Tue, 13 May 2014 12:46:20 -0400 Subject: [PATCH 014/141] page type business rules --- wagtail/tests/models.py | 12 +++++++ .../wagtailadmin/pages/add_subpage.html | 4 +-- wagtail/wagtailadmin/tests.py | 35 ++++++++++++++++++- wagtail/wagtailadmin/views/pages.py | 4 +-- wagtail/wagtailcore/models.py | 10 ++++-- 5 files changed, 56 insertions(+), 9 deletions(-) diff --git a/wagtail/tests/models.py b/wagtail/tests/models.py index 9124cb253..6c4b45f31 100644 --- a/wagtail/tests/models.py +++ b/wagtail/tests/models.py @@ -196,3 +196,15 @@ EventIndex.content_panels = [ FieldPanel('title', classname="full title"), FieldPanel('intro', classname="full"), ] + +class StandardIndex(Page): + pass + +class StandardChild(Page): + pass + +class BusinessIndex(Page): + subpage_types = ['tests.BusinessChild'] + +class BusinessChild(Page): + pass diff --git a/wagtail/wagtailadmin/templates/wagtailadmin/pages/add_subpage.html b/wagtail/wagtailadmin/templates/wagtailadmin/pages/add_subpage.html index 757c013b5..1158cc857 100644 --- a/wagtail/wagtailadmin/templates/wagtailadmin/pages/add_subpage.html +++ b/wagtail/wagtailadmin/templates/wagtailadmin/pages/add_subpage.html @@ -12,9 +12,9 @@

    {% trans "Choose which type of page you'd like to create." %}

    - {% if all_page_types %} + {% if page_types %}
      - {% for content_type in all_page_types %} + {% for content_type in page_types %}
    • diff --git a/wagtail/wagtailadmin/tests.py b/wagtail/wagtailadmin/tests.py index 435f29a9c..59e112b32 100644 --- a/wagtail/wagtailadmin/tests.py +++ b/wagtail/wagtailadmin/tests.py @@ -1,6 +1,6 @@ from django.test import TestCase import unittest2 as unittest -from wagtail.tests.models import SimplePage, EventPage +from wagtail.tests.models import SimplePage, EventPage, StandardIndex, StandardChild, BusinessIndex, BusinessChild from wagtail.tests.utils import login from wagtail.wagtailcore.models import Page from django.core.urlresolvers import reverse @@ -326,3 +326,36 @@ class TestEditorHooks(TestCase): self.assertEqual(response.status_code, 200) self.assertContains(response, '') self.assertContains(response, '') + + +class TestSubpageBusinessRules(TestCase): + def setUp(self): + # Find root page + self.root_page = Page.objects.get(id=2) + + # Add standard page + self.standard_index = StandardIndex() + self.standard_index.title = "Standard Index" + self.standard_index.slug = "standard-index" + self.root_page.add_child(instance=self.standard_index) + + # Add business page + self.business_index = BusinessIndex() + self.business_index.title = "Business Index" + self.business_index.slug = "business-index" + self.root_page.add_child(instance=self.business_index) + + # Login + login(self.client) + + def test_standard_subpage(self): + response = self.client.get(reverse('wagtailadmin_pages_add_subpage', args=(self.standard_index.id, ))) + self.assertEqual(response.status_code, 200) + self.assertContains(response, 'Standard Child') + self.assertContains(response, 'Business Child') + + def test_business_subpage(self): + response = self.client.get(reverse('wagtailadmin_pages_add_subpage', args=(self.business_index.id, ))) + self.assertEqual(response.status_code, 200) + self.assertNotContains(response, 'Standard Child') + self.assertContains(response, 'Business Child') diff --git a/wagtail/wagtailadmin/views/pages.py b/wagtail/wagtailadmin/views/pages.py index 6be731c3b..56c1294f9 100644 --- a/wagtail/wagtailadmin/views/pages.py +++ b/wagtail/wagtailadmin/views/pages.py @@ -68,13 +68,11 @@ def add_subpage(request, parent_page_id): if not parent_page.permissions_for_user(request.user).can_add_subpage(): raise PermissionDenied - page_types = sorted([ContentType.objects.get_for_model(model_class) for model_class in parent_page.clean_subpage_types()], key=lambda pagetype: pagetype.name.lower()) - all_page_types = sorted(get_page_types(), key=lambda pagetype: pagetype.name.lower()) + page_types = sorted(parent_page.clean_subpage_types(), key=lambda pagetype: pagetype.name.lower()) return render(request, 'wagtailadmin/pages/add_subpage.html', { 'parent_page': parent_page, 'page_types': page_types, - 'all_page_types': all_page_types, }) diff --git a/wagtail/wagtailcore/models.py b/wagtail/wagtailcore/models.py index 441c74a28..0fc1b3350 100644 --- a/wagtail/wagtailcore/models.py +++ b/wagtail/wagtailcore/models.py @@ -484,7 +484,11 @@ class Page(MP_Node, ClusterableModel, Indexed): where required """ if cls._clean_subpage_types is None: - res = [] + if len(cls.subpage_types) == 0: + res = get_page_types() + else: + res = [] + for page_type in cls.subpage_types: if isinstance(page_type, basestring): try: @@ -496,13 +500,13 @@ class Page(MP_Node, ClusterableModel, Indexed): model = get_model(app_label, model_name) if model: - res.append(model) + res.append(ContentType.objects.get_for_model(model)) else: raise NameError(_("name '{0}' (used in subpage_types list) is not defined.").format(page_type)) else: # assume it's already a model class - res.append(page_type) + res.append(ContentType.objects.get_for_model(page_type)) cls._clean_subpage_types = res From 8c4c26864103890897ca63708867621f16938a25 Mon Sep 17 00:00:00 2001 From: Karl Hobley Date: Tue, 20 May 2014 11:23:36 +0100 Subject: [PATCH 015/141] Added *args, *kwargs paramters to serve/get_context/get_template This makes it easier to pass parameters from the route method down to get_context/get_template --- wagtail/wagtailcore/models.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/wagtail/wagtailcore/models.py b/wagtail/wagtailcore/models.py index 441c74a28..fdf9e7b9a 100644 --- a/wagtail/wagtailcore/models.py +++ b/wagtail/wagtailcore/models.py @@ -394,23 +394,23 @@ class Page(MP_Node, ClusterableModel, Indexed): return revision.as_page_object() - def get_context(self, request): + def get_context(self, request, *args, **kwargs): return { 'self': self, 'request': request, } - def get_template(self, request): + def get_template(self, request, *args, **kwargs): if request.is_ajax(): return self.ajax_template or self.template else: return self.template - def serve(self, request): + def serve(self, request, *args, **kwargs): return TemplateResponse( request, - self.get_template(request), - self.get_context(request) + self.get_template(request, *args, **kwargs), + self.get_context(request, *args, **kwargs) ) def is_navigable(self): From d7c5a06929dbb175482ad92b17e9f87342966c1c Mon Sep 17 00:00:00 2001 From: Dave Cranwell Date: Fri, 23 May 2014 12:02:37 +0100 Subject: [PATCH 016/141] updated icons --- .../wagtailadmin/scss/components/icons.scss | 6 -- .../wagtailadmin/scss/fonts/wagtail.eot | Bin 26032 -> 26032 bytes .../wagtailadmin/scss/fonts/wagtail.svg | 71 +----------------- .../wagtailadmin/scss/fonts/wagtail.ttf | Bin 25868 -> 25868 bytes .../wagtailadmin/scss/fonts/wagtail.woff | Bin 15080 -> 15080 bytes 5 files changed, 1 insertion(+), 76 deletions(-) diff --git a/wagtail/wagtailadmin/static/wagtailadmin/scss/components/icons.scss b/wagtail/wagtailadmin/static/wagtailadmin/scss/components/icons.scss index 7fb3320dd..92e83bbe5 100644 --- a/wagtail/wagtailadmin/static/wagtailadmin/scss/components/icons.scss +++ b/wagtail/wagtailadmin/static/wagtailadmin/scss/components/icons.scss @@ -246,12 +246,6 @@ .icon-form:before{ content:"$"; } -.icon-date:before{ - content:"7"; -} -.icon-form:before{ - content:"$"; -} .icon.text-replace{ font-size:0em; line-height:0; diff --git a/wagtail/wagtailadmin/static/wagtailadmin/scss/fonts/wagtail.eot b/wagtail/wagtailadmin/static/wagtailadmin/scss/fonts/wagtail.eot index c5d6b5cc58b948ee1c15f5abeb6970cb759b23b8..7d7860a83289d44e2dc32b0b001995f293d6a15c 100755 GIT binary patch delta 57 zcmdmRnsLKv#tAme%N}J;wBN>@@tt+!51&LCgD)Oc@%%Pl8Mv7kK;Zn6+bS@6b3#%8 FGXSQ16;=QM delta 57 zcmdmRnsLKv#tAmeuaf6YwBN?;w=H?&51&LCLyeRB;`wd9GH^37fWZ0byDr1%%?U{X F%mA%N7Eb^G diff --git a/wagtail/wagtailadmin/static/wagtailadmin/scss/fonts/wagtail.svg b/wagtail/wagtailadmin/static/wagtailadmin/scss/fonts/wagtail.svg index f25359ec6..dcfa5a08c 100755 --- a/wagtail/wagtailadmin/static/wagtailadmin/scss/fonts/wagtail.svg +++ b/wagtail/wagtailadmin/static/wagtailadmin/scss/fonts/wagtail.svg @@ -6,7 +6,6 @@ -<<<<<<< HEAD @@ -72,72 +71,4 @@ - -======= - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ->>>>>>> master + \ No newline at end of file diff --git a/wagtail/wagtailadmin/static/wagtailadmin/scss/fonts/wagtail.ttf b/wagtail/wagtailadmin/static/wagtailadmin/scss/fonts/wagtail.ttf index c4161bea849d4ddb060928acbc08627d98cbaa78..38d2e1789c3dbff85017292ac2372a17f1b970bb 100755 GIT binary patch delta 50 xcmeA<#n^L-aY7(-#&_0@AwG#R246g?;`wd9GH^37fWY}Bw^d;D<~@l4%mB<)5nccQ delta 50 ycmeA<#n^L-aY7)o-?rq9AwG#Rh8idL#q-;IW#DFF0D<${i2(%8FS)G(qc_`FtYHEG*xM1g delta 47 vcmaD+`l56~FSFma{i2(%8Pv3PJMsK#USi=MW;jI$5 From c7921f2cda3afeaba695e46e61317e8d7d6d8598 Mon Sep 17 00:00:00 2001 From: Dave Cranwell Date: Fri, 23 May 2014 12:07:21 +0100 Subject: [PATCH 017/141] updated green colour for messages --- .../static/wagtailadmin/scss/components/messages.scss | 2 +- wagtail/wagtailadmin/static/wagtailadmin/scss/variables.scss | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/wagtail/wagtailadmin/static/wagtailadmin/scss/components/messages.scss b/wagtail/wagtailadmin/static/wagtailadmin/scss/components/messages.scss index e5e2454f6..ff01dc248 100644 --- a/wagtail/wagtailadmin/static/wagtailadmin/scss/components/messages.scss +++ b/wagtail/wagtailadmin/static/wagtailadmin/scss/components/messages.scss @@ -40,7 +40,7 @@ } } .success{ - background-color:$color-teal-dark; + background-color:$color-green; &:before{ font-family:wagtail; diff --git a/wagtail/wagtailadmin/static/wagtailadmin/scss/variables.scss b/wagtail/wagtailadmin/static/wagtailadmin/scss/variables.scss index 4c06efec8..0f6567989 100644 --- a/wagtail/wagtailadmin/static/wagtailadmin/scss/variables.scss +++ b/wagtail/wagtailadmin/static/wagtailadmin/scss/variables.scss @@ -29,7 +29,7 @@ $color-teal-darker: darken($color-teal, 10%); $color-teal-dark: #246060; $color-red: #f7474e; $color-orange:#e9b04d; -$color-green: #00FF00; +$color-green: #189370; /* darker to lighter */ $color-grey-1: #333333; From 217438ca37cee81ff2a27398db4ce1cb69c9829d Mon Sep 17 00:00:00 2001 From: Karl Hobley Date: Tue, 27 May 2014 14:29:45 +0100 Subject: [PATCH 018/141] Removed more section of wagtailadmin menu. Fixes #228 --- .../wagtailadmin/static/wagtailadmin/js/core.js | 11 ----------- .../static/wagtailadmin/scss/core.scss | 17 ----------------- .../templates/wagtailadmin/shared/main_nav.html | 14 -------------- .../templatetags/wagtailadmin_tags.py | 11 ----------- 4 files changed, 53 deletions(-) diff --git a/wagtail/wagtailadmin/static/wagtailadmin/js/core.js b/wagtail/wagtailadmin/static/wagtailadmin/js/core.js index 380c3d179..85c4ca31e 100644 --- a/wagtail/wagtailadmin/static/wagtailadmin/js/core.js +++ b/wagtail/wagtailadmin/static/wagtailadmin/js/core.js @@ -93,17 +93,6 @@ $(function(){ }); }); - $(".nav-main .more > a").bind('click keydown', function(){ - var currentAlt = $(this).data('altstate'); - var newAlt = $(this).html(); - - $(this).html(currentAlt); - $(this).data('altstate', newAlt); - $(this).toggleClass('icon-arrow-up icon-arrow-down'); - $(this).parent().find('ul').toggle('fast'); - return false; - }); - $('#menu-search input').bind('focus', function(){ $('#menu-search').addClass('focussed'); }).bind('blur', function(){ diff --git a/wagtail/wagtailadmin/static/wagtailadmin/scss/core.scss b/wagtail/wagtailadmin/static/wagtailadmin/scss/core.scss index e622680bd..08dbf11ca 100644 --- a/wagtail/wagtailadmin/static/wagtailadmin/scss/core.scss +++ b/wagtail/wagtailadmin/static/wagtailadmin/scss/core.scss @@ -226,19 +226,6 @@ img{ } } - .more{ - border:0; - - > a{ - &:before{ - margin-right:0.4em; - } - font-size:0.8em; - padding:0.2em 1.2em; - background-color:$color-grey-1-1; - } - } - .avatar{ display:none; } @@ -312,10 +299,6 @@ img{ } } - .js .nav-main .more ul{ - display:none; - } - .explorer{ position:absolute; margin-top:70px; diff --git a/wagtail/wagtailadmin/templates/wagtailadmin/shared/main_nav.html b/wagtail/wagtailadmin/templates/wagtailadmin/shared/main_nav.html index f7eb6528a..ce06d895c 100644 --- a/wagtail/wagtailadmin/templates/wagtailadmin/shared/main_nav.html +++ b/wagtail/wagtailadmin/templates/wagtailadmin/shared/main_nav.html @@ -10,19 +10,5 @@ {% trans "Log out" %}
    • - {% if request.user.is_superuser %} {# for now, 'More' links will be superuser-only #} -
    • - {% trans 'More' %} - -
    • - {% endif %} -
    diff --git a/wagtail/wagtailadmin/templatetags/wagtailadmin_tags.py b/wagtail/wagtailadmin/templatetags/wagtailadmin_tags.py index 311163ca3..2d85c355e 100644 --- a/wagtail/wagtailadmin/templatetags/wagtailadmin_tags.py +++ b/wagtail/wagtailadmin/templatetags/wagtailadmin_tags.py @@ -26,17 +26,6 @@ def explorer_subnav(nodes): } -@register.assignment_tag -def get_wagtailadmin_tab_urls(): - resolver = urlresolvers.get_resolver(None) - return [ - (key, value[2].get("title", key)) - for key, value - in resolver.reverse_dict.items() - if isinstance(key, basestring) and key.startswith('wagtailadmin_tab_') - ] - - @register.inclusion_tag('wagtailadmin/shared/main_nav.html', takes_context=True) def main_nav(context): menu_items = [ From 280bbff9d92e83530aa8c702fbf149f7b41e4cfd Mon Sep 17 00:00:00 2001 From: Karl Hobley Date: Tue, 27 May 2014 14:37:11 +0100 Subject: [PATCH 019/141] Added search and redirects links to menu using hooks --- wagtail/wagtailredirects/wagtail_hooks.py | 13 +++++++++++++ wagtail/wagtailsearch/wagtail_hooks.py | 13 +++++++++++++ 2 files changed, 26 insertions(+) diff --git a/wagtail/wagtailredirects/wagtail_hooks.py b/wagtail/wagtailredirects/wagtail_hooks.py index 22ae97320..4dbe1a028 100644 --- a/wagtail/wagtailredirects/wagtail_hooks.py +++ b/wagtail/wagtailredirects/wagtail_hooks.py @@ -1,11 +1,24 @@ +from django.core import urlresolvers from django.conf.urls import include, url +from django.utils.translation import ugettext_lazy as _ from wagtail.wagtailadmin import hooks from wagtail.wagtailredirects import urls +from wagtail.wagtailadmin.menu import MenuItem + def register_admin_urls(): return [ url(r'^redirects/', include(urls)), ] hooks.register('register_admin_urls', register_admin_urls) + + +def construct_main_menu(request, menu_items): + # TEMPORARY: Only show if the user is a superuser + if request.user.is_superuser: + menu_items.append( + MenuItem(_('Redirects'), urlresolvers.reverse('wagtailredirects_index'), classnames='icon icon-redirect', order=800) + ) +hooks.register('construct_main_menu', construct_main_menu) diff --git a/wagtail/wagtailsearch/wagtail_hooks.py b/wagtail/wagtailsearch/wagtail_hooks.py index b8bbd2c06..1a656c0ef 100644 --- a/wagtail/wagtailsearch/wagtail_hooks.py +++ b/wagtail/wagtailsearch/wagtail_hooks.py @@ -1,11 +1,24 @@ +from django.core import urlresolvers from django.conf.urls import include, url +from django.utils.translation import ugettext_lazy as _ from wagtail.wagtailadmin import hooks from wagtail.wagtailsearch.urls import admin as admin_urls +from wagtail.wagtailadmin.menu import MenuItem + def register_admin_urls(): return [ url(r'^search/', include(admin_urls)), ] hooks.register('register_admin_urls', register_admin_urls) + + +def construct_main_menu(request, menu_items): + # TEMPORARY: Only show if the user is a superuser + if request.user.is_superuser: + menu_items.append( + MenuItem(_('Editors picks'), urlresolvers.reverse('wagtailsearch_editorspicks_index'), classnames='icon icon-pick', order=900) + ) +hooks.register('construct_main_menu', construct_main_menu) From 24320332b0a55f8f06a06a7e92075b1e89f35bd5 Mon Sep 17 00:00:00 2001 From: Tom Talbot Date: Thu, 29 May 2014 15:02:56 +0100 Subject: [PATCH 020/141] Fix #94. Panels are now hidden on page load if they are marked as deleted after a form validation failure. --- .../static/wagtailadmin/js/page-editor.js | 11 +++++++++++ wagtail/wagtailadmin/views/pages.py | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/wagtail/wagtailadmin/static/wagtailadmin/js/page-editor.js b/wagtail/wagtailadmin/static/wagtailadmin/js/page-editor.js index cbff2c8af..4e8e1b02d 100644 --- a/wagtail/wagtailadmin/static/wagtailadmin/js/page-editor.js +++ b/wagtail/wagtailadmin/static/wagtailadmin/js/page-editor.js @@ -181,6 +181,17 @@ function InlinePanel(opts) { self.updateMoveButtonDisabledStates(); }); } + + /* Hide container on page load if it is marked as deleted. Remove the error + message so that it doesn't count towards the number of errors on the tab at the + top of the page. */ + if ( $('#' + deleteInputId).val() === "1" ) { + $('#' + childId).hide(0, function() { + self.updateMoveButtonDisabledStates(); + self.setHasContent(); + }); + $('#' + childId).find(".error-message").remove(); + } }; self.formsUl = $('#' + opts.formsetPrefix + '-FORMS'); diff --git a/wagtail/wagtailadmin/views/pages.py b/wagtail/wagtailadmin/views/pages.py index 308f6fdd4..809497d83 100644 --- a/wagtail/wagtailadmin/views/pages.py +++ b/wagtail/wagtailadmin/views/pages.py @@ -5,7 +5,7 @@ from django.contrib import messages from django.contrib.contenttypes.models import ContentType from django.contrib.auth.decorators import permission_required from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger -from django.utils.translation import ugettext as _ +from django.utils.translation import ugettext as _ from django.views.decorators.vary import vary_on_headers from wagtail.wagtailadmin.edit_handlers import TabbedInterface, ObjectList From 4887bb7cf7df9d47153bc79be6eb22d44feb3e36 Mon Sep 17 00:00:00 2001 From: Tom Talbot Date: Fri, 30 May 2014 17:13:07 +0100 Subject: [PATCH 021/141] Added tests for snippets edit_handlers.py --- wagtail/wagtailsnippets/tests.py | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/wagtail/wagtailsnippets/tests.py b/wagtail/wagtailsnippets/tests.py index fd283f7f5..727e5e52d 100644 --- a/wagtail/wagtailsnippets/tests.py +++ b/wagtail/wagtailsnippets/tests.py @@ -5,6 +5,8 @@ from django.contrib.auth.models import User from wagtail.tests.utils import login, unittest from wagtail.tests.models import Advert +from wagtail.wagtailsnippets.views.snippets import get_content_type_from_url_params, get_snippet_edit_handler +from wagtail.wagtailsnippets.edit_handlers import SnippetChooserPanel class TestSnippetIndexView(TestCase): def setUp(self): @@ -137,3 +139,32 @@ class TestSnippetDelete(TestCase): # Check that the page is gone self.assertEqual(Advert.objects.filter(text='test_advert').count(), 0) + + +class TestSnippetChooserPanel(TestCase): + def setUp(self): + content_type = get_content_type_from_url_params('tests', + 'advert') + + test_snippet = Advert() + test_snippet.text = 'test_advert' + test_snippet.url = 'http://www.example.com/' + test_snippet.save() + + edit_handler_class = get_snippet_edit_handler(Advert) + form_class = edit_handler_class.get_form_class(Advert) + form = form_class(instance=test_snippet) + + self.snippet_chooser_panel_class = SnippetChooserPanel('text', content_type) + self.snippet_chooser_panel = self.snippet_chooser_panel_class(instance=test_snippet, + form=form) + + def test_create_snippet_chooser_panel_class(self): + self.assertEqual(self.snippet_chooser_panel_class.__name__, '_SnippetChooserPanel') + + def test_render_as_field(self): + self.assertTrue('test_advert' in self.snippet_chooser_panel.render_as_field()) + + def test_render_js(self): + self.assertTrue("createSnippetChooser(fixPrefix('id_text'), 'contenttypes/contenttype');" + in self.snippet_chooser_panel.render_js()) From d88a5e596bf2cd6cdf10600c70d23750d86840c4 Mon Sep 17 00:00:00 2001 From: Karl Hobley Date: Mon, 2 Jun 2014 09:36:06 +0100 Subject: [PATCH 022/141] Cleanup wagtailimages backends code --- wagtail/wagtailimages/backends/base.py | 21 +++++++-------------- wagtail/wagtailimages/backends/pillow.py | 7 +++++-- wagtail/wagtailimages/backends/wand.py | 2 +- 3 files changed, 13 insertions(+), 17 deletions(-) diff --git a/wagtail/wagtailimages/backends/base.py b/wagtail/wagtailimages/backends/base.py index 25b7e882d..43ea977c9 100644 --- a/wagtail/wagtailimages/backends/base.py +++ b/wagtail/wagtailimages/backends/base.py @@ -1,6 +1,7 @@ from django.conf import settings from django.core.exceptions import ImproperlyConfigured + class InvalidImageBackendError(ImproperlyConfigured): pass @@ -8,23 +9,22 @@ class InvalidImageBackendError(ImproperlyConfigured): class BaseImageBackend(object): def __init__(self, params): self.quality = getattr(settings, 'IMAGE_COMPRESSION_QUALITY', 85) - + def open_image(self, input_file): """ - Open an image and return the backend specific image object to pass - to other methods. The object return has to have a size attribute + Open an image and return the backend specific image object to pass + to other methods. The object return has to have a size attribute which is a tuple with the width and height of the image and a format attribute with the format of the image. """ raise NotImplementedError('subclasses of BaseImageBackend must provide an open_image() method') - - + def save_image(self, image, output): """ Save the image to the output """ raise NotImplementedError('subclasses of BaseImageBackend must provide a save_image() method') - + def resize(self, image, size): """ resize image to the requested size, using highest quality settings @@ -32,11 +32,9 @@ class BaseImageBackend(object): """ raise NotImplementedError('subclasses of BaseImageBackend must provide an resize() method') - def crop_to_centre(self, image, size): raise NotImplementedError('subclasses of BaseImageBackend must provide a crop_to_centre() method') - def resize_to_max(self, image, size): """ Resize image down to fit within the given dimensions, preserving aspect ratio. @@ -58,10 +56,8 @@ class BaseImageBackend(object): final_size = (target_width, int(original_height * horz_scale)) else: final_size = (int(original_width * vert_scale), target_height) - - return self.resize(image, final_size) - + return self.resize(image, final_size) def resize_to_min(self, image, size): """ @@ -87,7 +83,6 @@ class BaseImageBackend(object): return self.resize(image, final_size) - def resize_to_width(self, image, target_width): """ Resize image down to the given width, preserving aspect ratio. @@ -104,7 +99,6 @@ class BaseImageBackend(object): return self.resize(image, final_size) - def resize_to_height(self, image, target_height): """ Resize image down to the given height, preserving aspect ratio. @@ -121,7 +115,6 @@ class BaseImageBackend(object): return self.resize(image, final_size) - def resize_to_fill(self, image, size): """ Resize down and crop image to fill the given dimensions. Most suitable for thumbnails. diff --git a/wagtail/wagtailimages/backends/pillow.py b/wagtail/wagtailimages/backends/pillow.py index 05d12d291..96976c277 100644 --- a/wagtail/wagtailimages/backends/pillow.py +++ b/wagtail/wagtailimages/backends/pillow.py @@ -1,6 +1,9 @@ -from base import BaseImageBackend +from __future__ import absolute_import + +from .base import BaseImageBackend import PIL.Image + class PillowBackend(BaseImageBackend): def __init__(self, params): super(PillowBackend, self).__init__(params) @@ -32,4 +35,4 @@ class PillowBackend(BaseImageBackend): top = (original_height - final_height) / 2 return image.crop( (left, top, left + final_width, top + final_height) - ) \ No newline at end of file + ) diff --git a/wagtail/wagtailimages/backends/wand.py b/wagtail/wagtailimages/backends/wand.py index 36e352715..0c493eb52 100644 --- a/wagtail/wagtailimages/backends/wand.py +++ b/wagtail/wagtailimages/backends/wand.py @@ -1,9 +1,9 @@ from __future__ import absolute_import from .base import BaseImageBackend - from wand.image import Image + class WandBackend(BaseImageBackend): def __init__(self, params): super(WandBackend, self).__init__(params) From 351b74c94b547b70902bab4a0e6e028738021349 Mon Sep 17 00:00:00 2001 From: Karl Hobley Date: Mon, 2 Jun 2014 09:52:33 +0100 Subject: [PATCH 023/141] Wand image backend: Always clone images before performing oprations on them --- wagtail/wagtailimages/backends/wand.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/wagtail/wagtailimages/backends/wand.py b/wagtail/wagtailimages/backends/wand.py index 0c493eb52..d1a877436 100644 --- a/wagtail/wagtailimages/backends/wand.py +++ b/wagtail/wagtailimages/backends/wand.py @@ -18,8 +18,9 @@ class WandBackend(BaseImageBackend): image.save(file=output) def resize(self, image, size): - image.resize(size[0], size[1]) - return image + new_image = image.clone() + new_image.resize(size[0], size[1]) + return new_image def crop_to_centre(self, image, size): (original_width, original_height) = image.size @@ -34,7 +35,9 @@ class WandBackend(BaseImageBackend): left = (original_width - final_width) / 2 top = (original_height - final_height) / 2 - image.crop( + + new_image = image.clone() + new_image.crop( left=left, top=top, right=left + final_width, bottom=top + final_height ) - return image + return new_image From e438a6d99b9d936c2a7ea730a3d09da102dc9d85 Mon Sep 17 00:00:00 2001 From: Karl Hobley Date: Mon, 2 Jun 2014 10:51:47 +0100 Subject: [PATCH 024/141] Minor wagtailimages cleanup --- wagtail/wagtailimages/models.py | 11 ++++------- wagtail/wagtailimages/tests.py | 16 ++++++++-------- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/wagtail/wagtailimages/models.py b/wagtail/wagtailimages/models.py index 24fd1f0bf..a2be29486 100644 --- a/wagtail/wagtailimages/models.py +++ b/wagtail/wagtailimages/models.py @@ -180,27 +180,25 @@ class Filter(models.Model): generate an output image with this filter applied, returning it as another django.core.files.File object """ - backend = get_image_backend(backend_name) - + if not self.method: self._parse_spec_string() - + # If file is closed, open it input_file.open('rb') image = backend.open_image(input_file) file_format = image.format - + method = getattr(backend, self.method_name) image = method(image, self.method_arg) output = StringIO.StringIO() backend.save_image(image, output, file_format) - + # and then close the input file input_file.close() - # generate new filename derived from old one, inserting the filter spec string before the extension input_filename_parts = os.path.basename(input_file.name).split('.') @@ -210,7 +208,6 @@ class Filter(models.Model): output_filename = '.'.join(output_filename_parts) output_file = File(output, name=output_filename) - return output_file diff --git a/wagtail/wagtailimages/tests.py b/wagtail/wagtailimages/tests.py index 00d1245e6..1bc2acc93 100644 --- a/wagtail/wagtailimages/tests.py +++ b/wagtail/wagtailimages/tests.py @@ -84,10 +84,10 @@ class TestRenditions(TestCase): # default backend should be pillow backend = get_image_backend() self.assertTrue(isinstance(backend, PillowBackend)) - + def test_minification(self): rendition = self.image.get_rendition('width-400') - + # Check size self.assertEqual(rendition.width, 400) self.assertEqual(rendition.height, 300) @@ -114,7 +114,7 @@ class TestRenditions(TestCase): # Check that they are the same object self.assertEqual(first_rendition, second_rendition) - + class TestRenditionsWand(TestCase): def setUp(self): @@ -134,18 +134,18 @@ class TestRenditionsWand(TestCase): def test_minification(self): rendition = self.image.get_rendition('width-400') - + # Check size self.assertEqual(rendition.width, 400) self.assertEqual(rendition.height, 300) - + def test_resize_to_max(self): rendition = self.image.get_rendition('max-100x100') - + # Check size self.assertEqual(rendition.width, 100) self.assertEqual(rendition.height, 75) - + def test_resize_to_min(self): rendition = self.image.get_rendition('min-120x120') @@ -160,7 +160,7 @@ class TestRenditionsWand(TestCase): # Check that they are the same object self.assertEqual(first_rendition, second_rendition) - + class TestImageTag(TestCase): def setUp(self): From b5586102ed5ae4bb3f56c33f2dc9de56628fdd2b Mon Sep 17 00:00:00 2001 From: Karl Hobley Date: Mon, 2 Jun 2014 10:52:34 +0100 Subject: [PATCH 025/141] Cleanup Filter.process_image a bit --- wagtail/wagtailimages/models.py | 37 ++++++++++++++++----------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/wagtail/wagtailimages/models.py b/wagtail/wagtailimages/models.py index a2be29486..ddde18d29 100644 --- a/wagtail/wagtailimages/models.py +++ b/wagtail/wagtailimages/models.py @@ -161,15 +161,17 @@ class Filter(models.Model): # and save the results to self.method_name and self.method_arg try: (method_name_simple, method_arg_string) = self.spec.split('-') - self.method_name = Filter.OPERATION_NAMES[method_name_simple] + method_name = Filter.OPERATION_NAMES[method_name_simple] if method_name_simple in ('max', 'min', 'fill'): # method_arg_string is in the form 640x480 (width, height) = [int(i) for i in method_arg_string.split('x')] - self.method_arg = (width, height) + method_arg = (width, height) else: # method_arg_string is a single number - self.method_arg = int(method_arg_string) + method_arg = int(method_arg_string) + + return method_name, method_arg except (ValueError, KeyError): raise ValueError("Invalid image filter spec: %r" % self.spec) @@ -180,36 +182,33 @@ class Filter(models.Model): generate an output image with this filter applied, returning it as another django.core.files.File object """ + # Get image backend backend = get_image_backend(backend_name) - if not self.method: - self._parse_spec_string() - - # If file is closed, open it + # Open image file input_file.open('rb') image = backend.open_image(input_file) file_format = image.format - method = getattr(backend, self.method_name) + # Parse filter spec string + method_name, method_arg = self._parse_spec_string() - image = method(image, self.method_arg) + # Run filter + method_f = getattr(backend, method_name) + image = method_f(image, method_arg) + # Save output = StringIO.StringIO() backend.save_image(image, output, file_format) - # and then close the input file + # Close input file input_file.close() - # generate new filename derived from old one, inserting the filter spec string before the extension - input_filename_parts = os.path.basename(input_file.name).split('.') - filename_without_extension = '.'.join(input_filename_parts[:-1]) - filename_without_extension = filename_without_extension[:60] # trim filename base so that we're well under 100 chars - output_filename_parts = [filename_without_extension, self.spec] + input_filename_parts[-1:] - output_filename = '.'.join(output_filename_parts) + # Generate new filename derived from old one, inserting the filter spec string before the extension + filename_noext, ext = os.path.splitext(input_file.name) + output_filename = '.'.join([filename_noext[:60], self.spec]) + ext - output_file = File(output, name=output_filename) - - return output_file + return File(output, name=output_filename) class AbstractRendition(models.Model): From 3f9cb2da6fcd614c3206631d6132d4286b6f1fbc Mon Sep 17 00:00:00 2001 From: Karl Hobley Date: Mon, 2 Jun 2014 13:27:39 +0100 Subject: [PATCH 026/141] Made login view redirect already logged in users to dashboard. Fixes #25 --- .../account/password_reset/complete.html | 2 +- .../templates/wagtailadmin/login.html | 2 +- .../tests/test_account_management.py | 1 - wagtail/wagtailadmin/urls.py | 10 ++------- wagtail/wagtailadmin/views/account.py | 22 ++++++++++++++++++- 5 files changed, 25 insertions(+), 12 deletions(-) diff --git a/wagtail/wagtailadmin/templates/wagtailadmin/account/password_reset/complete.html b/wagtail/wagtailadmin/templates/wagtailadmin/account/password_reset/complete.html index c0cf872e2..3dc8272b0 100644 --- a/wagtail/wagtailadmin/templates/wagtailadmin/account/password_reset/complete.html +++ b/wagtail/wagtailadmin/templates/wagtailadmin/account/password_reset/complete.html @@ -13,6 +13,6 @@ {% block furniture %}

    {% trans "Password change successful" %}

    -

    {% trans "Login" %}

    +

    {% trans "Login" %}

    {% endblock %} \ No newline at end of file diff --git a/wagtail/wagtailadmin/templates/wagtailadmin/login.html b/wagtail/wagtailadmin/templates/wagtailadmin/login.html index 012dd32f8..22682500f 100644 --- a/wagtail/wagtailadmin/templates/wagtailadmin/login.html +++ b/wagtail/wagtailadmin/templates/wagtailadmin/login.html @@ -20,7 +20,7 @@
    {% endif %} -
    + {% csrf_token %}

    {% trans "Sign in to Wagtail" %}

    diff --git a/wagtail/wagtailadmin/tests/test_account_management.py b/wagtail/wagtailadmin/tests/test_account_management.py index 95d54d7d9..63c70779b 100644 --- a/wagtail/wagtailadmin/tests/test_account_management.py +++ b/wagtail/wagtailadmin/tests/test_account_management.py @@ -49,7 +49,6 @@ class TestAuthentication(TestCase): self.assertTrue('_auth_user_id' in self.client.session) self.assertEqual(self.client.session['_auth_user_id'], User.objects.get(username='test').id) - @unittest.expectedFailure # See: https://github.com/torchbox/wagtail/issues/25 def test_already_logged_in_redirect(self): """ This tests that a user who is already logged in is automatically diff --git a/wagtail/wagtailadmin/urls.py b/wagtail/wagtailadmin/urls.py index 8fbf2f6e7..806240c5c 100644 --- a/wagtail/wagtailadmin/urls.py +++ b/wagtail/wagtailadmin/urls.py @@ -5,15 +5,8 @@ from wagtail.wagtailadmin.forms import LoginForm, PasswordResetForm from wagtail.wagtailadmin.views import account, chooser, home, pages, tags, userbar from wagtail.wagtailadmin import hooks -urlpatterns = [ - url( - r'^login/$', 'django.contrib.auth.views.login', { - 'template_name': 'wagtailadmin/login.html', - 'authentication_form': LoginForm, - 'extra_context': {'show_password_reset': getattr(settings, 'WAGTAIL_PASSWORD_MANAGEMENT_ENABLED', True)}, - }, name='wagtailadmin_login' - ), +urlpatterns = [ # Password reset url( r'^password_reset/$', 'django.contrib.auth.views.password_reset', { @@ -81,6 +74,7 @@ urlpatterns += [ url(r'^tag-autocomplete/$', tags.autocomplete, name='wagtailadmin_tag_autocomplete'), + url(r'^login/$', account.login, name='wagtailadmin_login'), url(r'^account/$', account.account, name='wagtailadmin_account'), url(r'^account/change_password/$', account.change_password, name='wagtailadmin_account_change_password'), url(r'^logout/$', account.logout, name='wagtailadmin_logout'), diff --git a/wagtail/wagtailadmin/views/account.py b/wagtail/wagtailadmin/views/account.py index 8479ea6b0..c5e461f55 100644 --- a/wagtail/wagtailadmin/views/account.py +++ b/wagtail/wagtailadmin/views/account.py @@ -3,8 +3,13 @@ from django.shortcuts import render, redirect from django.contrib import messages from django.contrib.auth.forms import SetPasswordForm from django.contrib.auth.decorators import permission_required -from django.contrib.auth.views import logout as auth_logout +from django.contrib.auth.views import logout as auth_logout, login as auth_login from django.utils.translation import ugettext as _ +from django.views.decorators.debug import sensitive_post_parameters +from django.views.decorators.cache import never_cache + +from wagtail.wagtailadmin import forms + @permission_required('wagtailadmin.access_admin') def account(request): @@ -37,6 +42,21 @@ def change_password(request): }) +@sensitive_post_parameters() +@never_cache +def login(request): + if request.user.is_authenticated(): + return redirect('wagtailadmin_home') + else: + return auth_login(request, + template_name='wagtailadmin/login.html', + authentication_form=forms.LoginForm, + extra_context={ + 'show_password_reset': getattr(settings, 'WAGTAIL_PASSWORD_MANAGEMENT_ENABLED', True), + }, + ) + + def logout(request): response = auth_logout(request, next_page = 'wagtailadmin_login') From 7ba7ded7c6cf2183f7ba4dbee80c86ede90d00cb Mon Sep 17 00:00:00 2001 From: Karl Hobley Date: Mon, 2 Jun 2014 13:40:34 +0100 Subject: [PATCH 027/141] Added WagtailTestCase class with a couple of useful methods --- wagtail/tests/utils.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/wagtail/tests/utils.py b/wagtail/tests/utils.py index 6590e6dcc..8e18c661d 100644 --- a/wagtail/tests/utils.py +++ b/wagtail/tests/utils.py @@ -1,4 +1,6 @@ +from django.test import TestCase from django.contrib.auth.models import User +from django.utils.six.moves.urllib.parse import urlparse, ParseResult # We need to make sure that we're using the same unittest library that Django uses internally # Otherwise, we get issues with the "SkipTest" and "ExpectedFailure" exceptions being recognised as errors @@ -20,3 +22,26 @@ def login(client): client.login(username='test', password='password') return user + + +class WagtailTestCase(TestCase): + def login(self): + login(self.client) + + # From: https://github.com/django/django/blob/255449c1ee61c14778658caae8c430fa4d76afd6/django/contrib/auth/tests/test_views.py#L70-L85 + def assertURLEqual(self, url, expected, parse_qs=False): + """ + Given two URLs, make sure all their components (the ones given by + urlparse) are equal, only comparing components that are present in both + URLs. + If `parse_qs` is True, then the querystrings are parsed with QueryDict. + This is useful if you don't want the order of parameters to matter. + Otherwise, the query strings are compared as-is. + """ + fields = ParseResult._fields + + for attr, x, y in zip(fields, urlparse(url), urlparse(expected)): + if parse_qs and attr == 'query': + x, y = QueryDict(x), QueryDict(y) + if x and y and x != y: + self.fail("%r != %r (%s doesn't match)" % (url, expected, attr)) From 7e7910ba3b68e524683f4bafda08983805f11708 Mon Sep 17 00:00:00 2001 From: Karl Hobley Date: Mon, 2 Jun 2014 13:41:00 +0100 Subject: [PATCH 028/141] Added LOGIN_REDIRECT_URL to runtests.py settings --- runtests.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/runtests.py b/runtests.py index 6fd37ebeb..346729653 100755 --- a/runtests.py +++ b/runtests.py @@ -101,7 +101,8 @@ if not settings.configured: ), COMPRESS_ENABLED=False, # disable compression so that we can run tests on the content of the compress tag WAGTAILSEARCH_BACKENDS=WAGTAILSEARCH_BACKENDS, - WAGTAIL_SITE_NAME='Test Site' + WAGTAIL_SITE_NAME='Test Site', + LOGIN_REDIRECT_URL = 'wagtailadmin_home', ) From 765f90746a6fac9e3a0caff025e0d668aed23a5d Mon Sep 17 00:00:00 2001 From: Karl Hobley Date: Mon, 2 Jun 2014 13:41:28 +0100 Subject: [PATCH 029/141] Use new WagtailTestCase class for checking redirect URLs in account management tests --- .../tests/test_account_management.py | 25 +++++++++++-------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/wagtail/wagtailadmin/tests/test_account_management.py b/wagtail/wagtailadmin/tests/test_account_management.py index 95d54d7d9..0b71d55fb 100644 --- a/wagtail/wagtailadmin/tests/test_account_management.py +++ b/wagtail/wagtailadmin/tests/test_account_management.py @@ -1,17 +1,16 @@ -from django.test import TestCase -from wagtail.tests.utils import login, unittest +from wagtail.tests.utils import unittest, WagtailTestCase from django.core.urlresolvers import reverse from django.contrib.auth.models import User from django.contrib.auth.tokens import PasswordResetTokenGenerator from django.core import mail -class TestAuthentication(TestCase): +class TestAuthentication(WagtailTestCase): """ This tests that users can login and logout of the admin interface """ def setUp(self): - login(self.client) + self.login() def test_login_view(self): """ @@ -44,6 +43,7 @@ class TestAuthentication(TestCase): # Check that the user was redirected to the dashboard self.assertEqual(response.status_code, 302) + self.assertURLEqual(response.url, reverse('wagtailadmin_home')) # Check that the user was logged in self.assertTrue('_auth_user_id' in self.client.session) @@ -61,6 +61,7 @@ class TestAuthentication(TestCase): # Check that the user was redirected to the dashboard self.assertEqual(response.status_code, 302) + self.assertURLEqual(response.url, reverse('wagtailadmin_home')) def test_logout(self): """ @@ -71,17 +72,18 @@ class TestAuthentication(TestCase): # Check that the user was redirected to the login page self.assertEqual(response.status_code, 302) + self.assertURLEqual(response.url, reverse('wagtailadmin_login')) # Check that the user was logged out self.assertFalse('_auth_user_id' in self.client.session) -class TestAccountSection(TestCase): +class TestAccountSection(WagtailTestCase): """ This tests that the accounts section is working """ def setUp(self): - login(self.client) + self.login() def test_account_view(self): """ @@ -117,8 +119,9 @@ class TestAccountSection(TestCase): } response = self.client.post(reverse('wagtailadmin_account_change_password'), post_data) - # Check that the user was redirected + # Check that the user was redirected to the account page self.assertEqual(response.status_code, 302) + self.assertURLEqual(response.url, reverse('wagtailadmin_account')) # Check that the password was changed self.assertTrue(User.objects.get(username='test').check_password('newpassword')) @@ -146,7 +149,7 @@ class TestAccountSection(TestCase): self.assertTrue(User.objects.get(username='test').check_password('password')) -class TestPasswordReset(TestCase): +class TestPasswordReset(WagtailTestCase): """ This tests that the password reset is working """ @@ -176,8 +179,9 @@ class TestPasswordReset(TestCase): } response = self.client.post(reverse('password_reset'), post_data) - # Check that the user was redirected + # Check that the user was redirected to the done page self.assertEqual(response.status_code, 302) + self.assertURLEqual(response.url, reverse('password_reset_done')) # Check that a password reset email was sent to the user self.assertEqual(len(mail.outbox), 1) @@ -267,8 +271,9 @@ class TestPasswordReset(TestCase): } response = self.client.post(reverse('password_reset_confirm', kwargs=self.url_kwargs), post_data) - # Check that the user was redirected + # Check that the user was redirected to the complete page self.assertEqual(response.status_code, 302) + self.assertURLEqual(response.url, reverse('password_reset_complete')) # Check that the password was changed self.assertTrue(User.objects.get(username='test').check_password('newpassword')) From a8ca4f14daefd980b402d987cd6fb7c496d991c4 Mon Sep 17 00:00:00 2001 From: Karl Hobley Date: Mon, 2 Jun 2014 13:56:19 +0100 Subject: [PATCH 030/141] Return user object from login method --- wagtail/tests/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wagtail/tests/utils.py b/wagtail/tests/utils.py index 8e18c661d..44e612555 100644 --- a/wagtail/tests/utils.py +++ b/wagtail/tests/utils.py @@ -26,7 +26,7 @@ def login(client): class WagtailTestCase(TestCase): def login(self): - login(self.client) + return login(self.client) # From: https://github.com/django/django/blob/255449c1ee61c14778658caae8c430fa4d76afd6/django/contrib/auth/tests/test_views.py#L70-L85 def assertURLEqual(self, url, expected, parse_qs=False): From 00a06856a8fba6ef838ac41e4a261d9e03d4698a Mon Sep 17 00:00:00 2001 From: Karl Hobley Date: Mon, 2 Jun 2014 13:56:54 +0100 Subject: [PATCH 031/141] Use WagtailTestCase class in admin page views tests --- .../wagtailadmin/tests/test_pages_views.py | 59 +++++++++++-------- 1 file changed, 34 insertions(+), 25 deletions(-) diff --git a/wagtail/wagtailadmin/tests/test_pages_views.py b/wagtail/wagtailadmin/tests/test_pages_views.py index ccaa67dae..f97c26581 100644 --- a/wagtail/wagtailadmin/tests/test_pages_views.py +++ b/wagtail/wagtailadmin/tests/test_pages_views.py @@ -1,13 +1,12 @@ -from django.test import TestCase from wagtail.tests.models import SimplePage, EventPage -from wagtail.tests.utils import login, unittest +from wagtail.tests.utils import unittest, WagtailTestCase from wagtail.wagtailcore.models import Page, PageRevision from django.core.urlresolvers import reverse from django.contrib.auth.models import User, Permission from django.core import mail -class TestPageExplorer(TestCase): +class TestPageExplorer(WagtailTestCase): def setUp(self): # Find root page self.root_page = Page.objects.get(id=2) @@ -19,7 +18,7 @@ class TestPageExplorer(TestCase): self.root_page.add_child(instance=self.child_page) # Login - login(self.client) + self.login() def test_explore(self): response = self.client.get(reverse('wagtailadmin_explore', args=(self.root_page.id, ))) @@ -28,13 +27,13 @@ class TestPageExplorer(TestCase): self.assertTrue(response.context['pages'].filter(id=self.child_page.id).exists()) -class TestPageCreation(TestCase): +class TestPageCreation(WagtailTestCase): def setUp(self): # Find root page self.root_page = Page.objects.get(id=2) # Login - self.user = login(self.client) + self.user = self.login() def test_add_subpage(self): response = self.client.get(reverse('wagtailadmin_pages_add_subpage', args=(self.root_page.id, ))) @@ -86,6 +85,7 @@ class TestPageCreation(TestCase): # Should be redirected to explorer page self.assertEqual(response.status_code, 302) + self.assertURLEqual(response.url, reverse('wagtailadmin_explore', args=(self.root_page.id, ))) # Find the page and check it page = Page.objects.get(path__startswith=self.root_page.path, slug='hello-world').specific @@ -104,6 +104,7 @@ class TestPageCreation(TestCase): # Should be redirected to explorer page self.assertEqual(response.status_code, 302) + self.assertURLEqual(response.url, reverse('wagtailadmin_explore', args=(self.root_page.id, ))) # Find the page and check it page = Page.objects.get(path__startswith=self.root_page.path, slug='hello-world').specific @@ -126,6 +127,7 @@ class TestPageCreation(TestCase): # Should be redirected to explorer page self.assertEqual(response.status_code, 302) + self.assertURLEqual(response.url, reverse('wagtailadmin_explore', args=(self.root_page.id, ))) # Find the page and check it page = Page.objects.get(path__startswith=self.root_page.path, slug='hello-world').specific @@ -186,7 +188,7 @@ class TestPageCreation(TestCase): self.assertContains(response, "New page!") -class TestPageEdit(TestCase): +class TestPageEdit(WagtailTestCase): def setUp(self): # Find root page self.root_page = Page.objects.get(id=2) @@ -206,7 +208,7 @@ class TestPageEdit(TestCase): self.root_page.add_child(instance=self.event_page) # Login - self.user = login(self.client) + self.user = self.login() def test_page_edit(self): # Tests that the edit page loads @@ -238,6 +240,7 @@ class TestPageEdit(TestCase): # Should be redirected to explorer page self.assertEqual(response.status_code, 302) + self.assertURLEqual(response.url, reverse('wagtailadmin_explore', args=(self.root_page.id, ))) # The page should have "has_unpublished_changes" flag set child_page_new = SimplePage.objects.get(id=self.child_page.id) @@ -255,6 +258,7 @@ class TestPageEdit(TestCase): # Should be redirected to explorer page self.assertEqual(response.status_code, 302) + self.assertURLEqual(response.url, reverse('wagtailadmin_explore', args=(self.root_page.id, ))) # Check that the page was edited child_page_new = SimplePage.objects.get(id=self.child_page.id) @@ -278,6 +282,7 @@ class TestPageEdit(TestCase): # Should be redirected to explorer page self.assertEqual(response.status_code, 302) + self.assertURLEqual(response.url, reverse('wagtailadmin_explore', args=(self.root_page.id, ))) # The page should have "has_unpublished_changes" flag set child_page_new = SimplePage.objects.get(id=self.child_page.id) @@ -306,7 +311,7 @@ class TestPageEdit(TestCase): self.assertContains(response, "I've been edited!") -class TestPageDelete(TestCase): +class TestPageDelete(WagtailTestCase): def setUp(self): # Find root page self.root_page = Page.objects.get(id=2) @@ -318,7 +323,7 @@ class TestPageDelete(TestCase): self.root_page.add_child(instance=self.child_page) # Login - self.user = login(self.client) + self.user = self.login() def test_page_delete(self): response = self.client.get(reverse('wagtailadmin_pages_delete', args=(self.child_page.id, ))) @@ -344,15 +349,16 @@ class TestPageDelete(TestCase): # Should be redirected to explorer page self.assertEqual(response.status_code, 302) + self.assertURLEqual(response.url, reverse('wagtailadmin_explore', args=(self.root_page.id, ))) # Check that the page is gone self.assertEqual(Page.objects.filter(path__startswith=self.root_page.path, slug='hello-world').count(), 0) -class TestPageSearch(TestCase): +class TestPageSearch(WagtailTestCase): def setUp(self): # Login - login(self.client) + self.login() def get(self, params=None, **extra): return self.client.get(reverse('wagtailadmin_pages_search'), params or {}, **extra) @@ -390,7 +396,7 @@ class TestPageSearch(TestCase): self.assertTrue(any([r.slug == 'root' for r in results])) -class TestPageMove(TestCase): +class TestPageMove(WagtailTestCase): def setUp(self): # Find root page self.root_page = Page.objects.get(id=2) @@ -413,7 +419,7 @@ class TestPageMove(TestCase): self.section_a.add_child(instance=self.test_page) # Login - self.user = login(self.client) + self.user = self.login() def test_page_move(self): response = self.client.get(reverse('wagtailadmin_pages_move', args=(self.test_page.id, ))) @@ -442,18 +448,18 @@ class TestPageMove(TestCase): self.assertEqual(response.status_code, 200) -class TestPageUnpublish(TestCase): +class TestPageUnpublish(WagtailTestCase): def setUp(self): - self.user = login(self.client) + self.user = self.login() # Create a page to unpublish - root_page = Page.objects.get(id=2) + self.root_page = Page.objects.get(id=2) self.page = SimplePage( title="Hello world!", slug='hello-world', live=True, ) - root_page.add_child(instance=self.page) + self.root_page.add_child(instance=self.page) def test_unpublish_view(self): """ @@ -502,14 +508,15 @@ class TestPageUnpublish(TestCase): 'foo': "Must post something or the view won't see this as a POST request", }) - # Check that the user was redirected + # Check that the user was redirected to the explore page self.assertEqual(response.status_code, 302) + self.assertURLEqual(response.url, reverse('wagtailadmin_explore', args=(self.root_page.id, ))) # Check that the page was unpublished self.assertFalse(SimplePage.objects.get(id=self.page.id).live) -class TestApproveRejectModeration(TestCase): +class TestApproveRejectModeration(WagtailTestCase): def setUp(self): self.submitter = User.objects.create_superuser( username='submitter', @@ -517,7 +524,7 @@ class TestApproveRejectModeration(TestCase): password='password', ) - self.user = login(self.client) + self.user = self.login() # Create a page and submit it for moderation root_page = Page.objects.get(id=2) @@ -540,8 +547,9 @@ class TestApproveRejectModeration(TestCase): 'foo': "Must post something or the view won't see this as a POST request", }) - # Check that the user was redirected + # Check that the user was redirected to the dashboard self.assertEqual(response.status_code, 302) + self.assertURLEqual(response.url, reverse('wagtailadmin_home')) # Page must be live self.assertTrue(Page.objects.get(id=self.page.id).live) @@ -591,8 +599,9 @@ class TestApproveRejectModeration(TestCase): 'foo': "Must post something or the view won't see this as a POST request", }) - # Check that the user was redirected + # Check that the user was redirected to the dashboard self.assertEqual(response.status_code, 302) + self.assertURLEqual(response.url, reverse('wagtailadmin_home')) # Page must not be live self.assertFalse(Page.objects.get(id=self.page.id).live) @@ -645,11 +654,11 @@ class TestApproveRejectModeration(TestCase): self.assertContains(response, "Hello world!") -class TestContentTypeUse(TestCase): +class TestContentTypeUse(WagtailTestCase): fixtures = ['test.json'] def setUp(self): - self.user = login(self.client) + self.user = self.login() def test_content_type_use(self): # Get use of event page From 301fd6ec3c5e37b8f9b092fade08e49c7bde949c Mon Sep 17 00:00:00 2001 From: Karl Hobley Date: Mon, 2 Jun 2014 13:59:06 +0100 Subject: [PATCH 032/141] Made WagtailTestCase a mixin and renamed to WagtailTestUtils. --- wagtail/tests/utils.py | 2 +- .../tests/test_account_management.py | 9 ++++---- .../wagtailadmin/tests/test_pages_views.py | 21 ++++++++++--------- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/wagtail/tests/utils.py b/wagtail/tests/utils.py index 44e612555..4b22b000c 100644 --- a/wagtail/tests/utils.py +++ b/wagtail/tests/utils.py @@ -24,7 +24,7 @@ def login(client): return user -class WagtailTestCase(TestCase): +class WagtailTestUtils(object): def login(self): return login(self.client) diff --git a/wagtail/wagtailadmin/tests/test_account_management.py b/wagtail/wagtailadmin/tests/test_account_management.py index 0b71d55fb..499cd9554 100644 --- a/wagtail/wagtailadmin/tests/test_account_management.py +++ b/wagtail/wagtailadmin/tests/test_account_management.py @@ -1,11 +1,12 @@ -from wagtail.tests.utils import unittest, WagtailTestCase +from django.test import TestCase +from wagtail.tests.utils import unittest, WagtailTestUtils from django.core.urlresolvers import reverse from django.contrib.auth.models import User from django.contrib.auth.tokens import PasswordResetTokenGenerator from django.core import mail -class TestAuthentication(WagtailTestCase): +class TestAuthentication(TestCase, WagtailTestUtils): """ This tests that users can login and logout of the admin interface """ @@ -78,7 +79,7 @@ class TestAuthentication(WagtailTestCase): self.assertFalse('_auth_user_id' in self.client.session) -class TestAccountSection(WagtailTestCase): +class TestAccountSection(TestCase, WagtailTestUtils): """ This tests that the accounts section is working """ @@ -149,7 +150,7 @@ class TestAccountSection(WagtailTestCase): self.assertTrue(User.objects.get(username='test').check_password('password')) -class TestPasswordReset(WagtailTestCase): +class TestPasswordReset(TestCase, WagtailTestUtils): """ This tests that the password reset is working """ diff --git a/wagtail/wagtailadmin/tests/test_pages_views.py b/wagtail/wagtailadmin/tests/test_pages_views.py index f97c26581..a34b29fd8 100644 --- a/wagtail/wagtailadmin/tests/test_pages_views.py +++ b/wagtail/wagtailadmin/tests/test_pages_views.py @@ -1,12 +1,13 @@ +from django.test import TestCase from wagtail.tests.models import SimplePage, EventPage -from wagtail.tests.utils import unittest, WagtailTestCase +from wagtail.tests.utils import unittest, WagtailTestUtils from wagtail.wagtailcore.models import Page, PageRevision from django.core.urlresolvers import reverse from django.contrib.auth.models import User, Permission from django.core import mail -class TestPageExplorer(WagtailTestCase): +class TestPageExplorer(TestCase, WagtailTestUtils): def setUp(self): # Find root page self.root_page = Page.objects.get(id=2) @@ -27,7 +28,7 @@ class TestPageExplorer(WagtailTestCase): self.assertTrue(response.context['pages'].filter(id=self.child_page.id).exists()) -class TestPageCreation(WagtailTestCase): +class TestPageCreation(TestCase, WagtailTestUtils): def setUp(self): # Find root page self.root_page = Page.objects.get(id=2) @@ -188,7 +189,7 @@ class TestPageCreation(WagtailTestCase): self.assertContains(response, "New page!") -class TestPageEdit(WagtailTestCase): +class TestPageEdit(TestCase, WagtailTestUtils): def setUp(self): # Find root page self.root_page = Page.objects.get(id=2) @@ -311,7 +312,7 @@ class TestPageEdit(WagtailTestCase): self.assertContains(response, "I've been edited!") -class TestPageDelete(WagtailTestCase): +class TestPageDelete(TestCase, WagtailTestUtils): def setUp(self): # Find root page self.root_page = Page.objects.get(id=2) @@ -355,7 +356,7 @@ class TestPageDelete(WagtailTestCase): self.assertEqual(Page.objects.filter(path__startswith=self.root_page.path, slug='hello-world').count(), 0) -class TestPageSearch(WagtailTestCase): +class TestPageSearch(TestCase, WagtailTestUtils): def setUp(self): # Login self.login() @@ -396,7 +397,7 @@ class TestPageSearch(WagtailTestCase): self.assertTrue(any([r.slug == 'root' for r in results])) -class TestPageMove(WagtailTestCase): +class TestPageMove(TestCase, WagtailTestUtils): def setUp(self): # Find root page self.root_page = Page.objects.get(id=2) @@ -448,7 +449,7 @@ class TestPageMove(WagtailTestCase): self.assertEqual(response.status_code, 200) -class TestPageUnpublish(WagtailTestCase): +class TestPageUnpublish(TestCase, WagtailTestUtils): def setUp(self): self.user = self.login() @@ -516,7 +517,7 @@ class TestPageUnpublish(WagtailTestCase): self.assertFalse(SimplePage.objects.get(id=self.page.id).live) -class TestApproveRejectModeration(WagtailTestCase): +class TestApproveRejectModeration(TestCase, WagtailTestUtils): def setUp(self): self.submitter = User.objects.create_superuser( username='submitter', @@ -654,7 +655,7 @@ class TestApproveRejectModeration(WagtailTestCase): self.assertContains(response, "Hello world!") -class TestContentTypeUse(WagtailTestCase): +class TestContentTypeUse(TestCase, WagtailTestUtils): fixtures = ['test.json'] def setUp(self): From d9825e9531c3067c3261bdc7ac04042c50e92148 Mon Sep 17 00:00:00 2001 From: Karl Hobley Date: Mon, 2 Jun 2014 14:03:02 +0100 Subject: [PATCH 033/141] Fixed missing import --- wagtail/tests/utils.py | 1 + 1 file changed, 1 insertion(+) diff --git a/wagtail/tests/utils.py b/wagtail/tests/utils.py index 4b22b000c..0497b239a 100644 --- a/wagtail/tests/utils.py +++ b/wagtail/tests/utils.py @@ -1,6 +1,7 @@ from django.test import TestCase from django.contrib.auth.models import User from django.utils.six.moves.urllib.parse import urlparse, ParseResult +from django.http import QueryDict # We need to make sure that we're using the same unittest library that Django uses internally # Otherwise, we get issues with the "SkipTest" and "ExpectedFailure" exceptions being recognised as errors From 106b27a5a5699fe369f841141bbf3cc219da6864 Mon Sep 17 00:00:00 2001 From: Karl Hobley Date: Mon, 2 Jun 2014 15:23:32 +0100 Subject: [PATCH 034/141] Added template used assertions into many tests --- wagtail/wagtailadmin/tests/tests.py | 2 +- wagtail/wagtaildocs/tests.py | 54 ++++++++++++++----- wagtail/wagtailimages/tests.py | 48 ++++++++++++----- wagtail/wagtailredirects/tests.py | 24 ++++++--- .../wagtailsearch/tests/test_editorspicks.py | 24 ++++++--- wagtail/wagtailsearch/tests/test_frontend.py | 12 +++-- wagtail/wagtailsearch/tests/test_queries.py | 7 ++- wagtail/wagtailsnippets/tests.py | 24 ++++++--- wagtail/wagtailusers/tests.py | 18 ++++--- 9 files changed, 148 insertions(+), 65 deletions(-) diff --git a/wagtail/wagtailadmin/tests/tests.py b/wagtail/wagtailadmin/tests/tests.py index 12aa28a0b..b0c0896e2 100644 --- a/wagtail/wagtailadmin/tests/tests.py +++ b/wagtail/wagtailadmin/tests/tests.py @@ -12,7 +12,7 @@ class TestHome(TestCase): # Login login(self.client) - def test_status_code(self): + def test_simple(self): response = self.client.get(reverse('wagtailadmin_home')) self.assertEqual(response.status_code, 200) diff --git a/wagtail/wagtaildocs/tests.py b/wagtail/wagtaildocs/tests.py index d068f9a27..33da3e33a 100644 --- a/wagtail/wagtaildocs/tests.py +++ b/wagtail/wagtaildocs/tests.py @@ -46,8 +46,10 @@ class TestDocumentIndexView(TestCase): def get(self, params={}): return self.client.get(reverse('wagtaildocs_index'), params) - def test_status_code(self): - self.assertEqual(self.get().status_code, 200) + def test_simple(self): + response = self.get() + self.assertEqual(response.status_code, 200) + self.assertTemplateUsed(response, 'wagtaildocs/documents/index.html') def test_search(self): response = self.get({'q': "Hello"}) @@ -74,8 +76,12 @@ class TestDocumentAddView(TestCase): def get(self, params={}): return self.client.get(reverse('wagtaildocs_add_document'), params) - def test_status_code(self): - self.assertEqual(self.get().status_code, 200) + def test_simple(self): + response = self.get() + self.assertEqual(response.status_code, 200) + self.assertTemplateUsed(response, 'wagtaildocs/documents/add.html') + + # TODO: Test posting class TestDocumentEditView(TestCase): @@ -88,8 +94,12 @@ class TestDocumentEditView(TestCase): def get(self, params={}): return self.client.get(reverse('wagtaildocs_edit_document', args=(self.document.id,)), params) - def test_status_code(self): - self.assertEqual(self.get().status_code, 200) + def test_simple(self): + response = self.get() + self.assertEqual(response.status_code, 200) + self.assertTemplateUsed(response, 'wagtaildocs/documents/edit.html') + + # TODO: Test posting class TestDocumentDeleteView(TestCase): @@ -102,8 +112,12 @@ class TestDocumentDeleteView(TestCase): def get(self, params={}): return self.client.get(reverse('wagtaildocs_delete_document', args=(self.document.id,)), params) - def test_status_code(self): - self.assertEqual(self.get().status_code, 200) + def test_simple(self): + response = self.get() + self.assertEqual(response.status_code, 200) + self.assertTemplateUsed(response, 'wagtaildocs/documents/confirm_delete.html') + + # TODO: Test posting class TestDocumentChooserView(TestCase): @@ -113,8 +127,11 @@ class TestDocumentChooserView(TestCase): def get(self, params={}): return self.client.get(reverse('wagtaildocs_chooser'), params) - def test_status_code(self): - self.assertEqual(self.get().status_code, 200) + def test_simple(self): + response = self.get() + self.assertEqual(response.status_code, 200) + self.assertTemplateUsed(response, 'wagtaildocs/chooser/chooser.html') + self.assertTemplateUsed(response, 'wagtaildocs/chooser/chooser.js') def test_search(self): response = self.get({'q': "Hello"}) @@ -138,8 +155,12 @@ class TestDocumentChooserChosenView(TestCase): def get(self, params={}): return self.client.get(reverse('wagtaildocs_document_chosen', args=(self.document.id,)), params) - def test_status_code(self): - self.assertEqual(self.get().status_code, 200) + def test_simple(self): + response = self.get() + self.assertEqual(response.status_code, 200) + self.assertTemplateUsed(response, 'wagtaildocs/chooser/document_chosen.js') + + # TODO: Test posting class TestDocumentChooserUploadView(TestCase): @@ -149,8 +170,13 @@ class TestDocumentChooserUploadView(TestCase): def get(self, params={}): return self.client.get(reverse('wagtaildocs_chooser_upload'), params) - def test_status_code(self): - self.assertEqual(self.get().status_code, 200) + def test_simple(self): + response = self.get() + self.assertEqual(response.status_code, 200) + self.assertTemplateUsed(response, 'wagtaildocs/chooser/chooser.html') + self.assertTemplateUsed(response, 'wagtaildocs/chooser/chooser.js') + + # TODO: Test document upload with chooser class TestDocumentFilenameProperties(TestCase): diff --git a/wagtail/wagtailimages/tests.py b/wagtail/wagtailimages/tests.py index 00d1245e6..fdadc3704 100644 --- a/wagtail/wagtailimages/tests.py +++ b/wagtail/wagtailimages/tests.py @@ -194,8 +194,10 @@ class TestImageIndexView(TestCase): def get(self, params={}): return self.client.get(reverse('wagtailimages_index'), params) - def test_status_code(self): - self.assertEqual(self.get().status_code, 200) + def test_simple(self): + response = self.get() + self.assertEqual(response.status_code, 200) + self.assertTemplateUsed(response, 'wagtailimages/images/index.html') def test_search(self): response = self.get({'q': "Hello"}) @@ -225,8 +227,10 @@ class TestImageAddView(TestCase): def post(self, post_data={}): return self.client.post(reverse('wagtailimages_add_image'), post_data) - def test_status_code(self): - self.assertEqual(self.get().status_code, 200) + def test_simple(self): + response = self.get() + self.assertEqual(response.status_code, 200) + self.assertTemplateUsed(response, 'wagtailimages/images/add.html') def test_add(self): response = self.post({ @@ -263,8 +267,10 @@ class TestImageEditView(TestCase): def post(self, post_data={}): return self.client.post(reverse('wagtailimages_edit_image', args=(self.image.id,)), post_data) - def test_status_code(self): - self.assertEqual(self.get().status_code, 200) + def test_simple(self): + response = self.get() + self.assertEqual(response.status_code, 200) + self.assertTemplateUsed(response, 'wagtailimages/images/edit.html') def test_edit(self): response = self.post({ @@ -295,8 +301,10 @@ class TestImageDeleteView(TestCase): def post(self, post_data={}): return self.client.post(reverse('wagtailimages_delete_image', args=(self.image.id,)), post_data) - def test_status_code(self): - self.assertEqual(self.get().status_code, 200) + def test_simple(self): + response = self.get() + self.assertEqual(response.status_code, 200) + self.assertTemplateUsed(response, 'wagtailimages/images/confirm_delete.html') def test_delete(self): response = self.post({ @@ -318,8 +326,11 @@ class TestImageChooserView(TestCase): def get(self, params={}): return self.client.get(reverse('wagtailimages_chooser'), params) - def test_status_code(self): - self.assertEqual(self.get().status_code, 200) + def test_simple(self): + response = self.get() + self.assertEqual(response.status_code, 200) + self.assertTemplateUsed(response, 'wagtailimages/chooser/chooser.html') + self.assertTemplateUsed(response, 'wagtailimages/chooser/chooser.js') def test_search(self): response = self.get({'q': "Hello"}) @@ -346,8 +357,12 @@ class TestImageChooserChosenView(TestCase): def get(self, params={}): return self.client.get(reverse('wagtailimages_image_chosen', args=(self.image.id,)), params) - def test_status_code(self): - self.assertEqual(self.get().status_code, 200) + def test_simple(self): + response = self.get() + self.assertEqual(response.status_code, 200) + self.assertTemplateUsed(response, 'wagtailimages/chooser/image_chosen.js') + + # TODO: Test posting class TestImageChooserUploadView(TestCase): @@ -357,5 +372,10 @@ class TestImageChooserUploadView(TestCase): def get(self, params={}): return self.client.get(reverse('wagtailimages_chooser_upload'), params) - def test_status_code(self): - self.assertEqual(self.get().status_code, 200) + def test_simple(self): + response = self.get() + self.assertEqual(response.status_code, 200) + self.assertTemplateUsed(response, 'wagtailimages/chooser/chooser.html') + self.assertTemplateUsed(response, 'wagtailimages/chooser/chooser.js') + + # TODO: Test uploading through chooser diff --git a/wagtail/wagtailredirects/tests.py b/wagtail/wagtailredirects/tests.py index a14a853fa..f23ea63c9 100644 --- a/wagtail/wagtailredirects/tests.py +++ b/wagtail/wagtailredirects/tests.py @@ -73,8 +73,10 @@ class TestRedirectsIndexView(TestCase): def get(self, params={}): return self.client.get(reverse('wagtailredirects_index'), params) - def test_status_code(self): - self.assertEqual(self.get().status_code, 200) + def test_simple(self): + response = self.get() + self.assertEqual(response.status_code, 200) + self.assertTemplateUsed(response, 'wagtailredirects/index.html') def test_search(self): response = self.get({'q': "Hello"}) @@ -98,8 +100,10 @@ class TestRedirectsAddView(TestCase): def post(self, post_data={}): return self.client.post(reverse('wagtailredirects_add_redirect'), post_data) - def test_status_code(self): - self.assertEqual(self.get().status_code, 200) + def test_simple(self): + response = self.get() + self.assertEqual(response.status_code, 200) + self.assertTemplateUsed(response, 'wagtailredirects/add.html') def test_add(self): response = self.post({ @@ -142,8 +146,10 @@ class TestRedirectsEditView(TestCase): def post(self, post_data={}, redirect_id=None): return self.client.post(reverse('wagtailredirects_edit_redirect', args=(redirect_id or self.redirect.id, )), post_data) - def test_status_code(self): - self.assertEqual(self.get().status_code, 200) + def test_simple(self): + response = self.get() + self.assertEqual(response.status_code, 200) + self.assertTemplateUsed(response, 'wagtailredirects/edit.html') def test_nonexistant_redirect(self): self.assertEqual(self.get(redirect_id=100000).status_code, 404) @@ -188,8 +194,10 @@ class TestRedirectsDeleteView(TestCase): def post(self, post_data={}, redirect_id=None): return self.client.post(reverse('wagtailredirects_delete_redirect', args=(redirect_id or self.redirect.id, )), post_data) - def test_status_code(self): - self.assertEqual(self.get().status_code, 200) + def test_simple(self): + response = self.get() + self.assertEqual(response.status_code, 200) + self.assertTemplateUsed(response, 'wagtailredirects/confirm_delete.html') def test_nonexistant_redirect(self): self.assertEqual(self.get(redirect_id=100000).status_code, 404) diff --git a/wagtail/wagtailsearch/tests/test_editorspicks.py b/wagtail/wagtailsearch/tests/test_editorspicks.py index e0b49153f..2af0df625 100644 --- a/wagtail/wagtailsearch/tests/test_editorspicks.py +++ b/wagtail/wagtailsearch/tests/test_editorspicks.py @@ -52,8 +52,10 @@ class TestEditorsPicksIndexView(TestCase): def get(self, params={}): return self.client.get('/admin/search/editorspicks/', params) - def test_status_code(self): - self.assertEqual(self.get().status_code, 200) + def test_simple(self): + response = self.get() + self.assertEqual(response.status_code, 200) + self.assertTemplateUsed(response, 'wagtailsearch/editorspicks/index.html') def test_search(self): response = self.get({'q': "Hello"}) @@ -74,8 +76,10 @@ class TestEditorsPicksAddView(TestCase): def get(self, params={}): return self.client.get('/admin/search/editorspicks/add/', params) - def test_status_code(self): - self.assertEqual(self.get().status_code, 200) + def test_simple(self): + response = self.get() + self.assertEqual(response.status_code, 200) + self.assertTemplateUsed(response, 'wagtailsearch/editorspicks/add.html') class TestEditorsPicksEditView(TestCase): @@ -89,8 +93,10 @@ class TestEditorsPicksEditView(TestCase): def get(self, params={}): return self.client.get('/admin/search/editorspicks/' + str(self.query.id) + '/', params) - def test_status_code(self): - self.assertEqual(self.get().status_code, 200) + def test_simple(self): + response = self.get() + self.assertEqual(response.status_code, 200) + self.assertTemplateUsed(response, 'wagtailsearch/editorspicks/edit.html') class TestEditorsPicksDeleteView(TestCase): @@ -104,5 +110,7 @@ class TestEditorsPicksDeleteView(TestCase): def get(self, params={}): return self.client.get('/admin/search/editorspicks/' + str(self.query.id) + '/delete/', params) - def test_status_code(self): - self.assertEqual(self.get().status_code, 200) + def test_simple(self): + response = self.get() + self.assertEqual(response.status_code, 200) + self.assertTemplateUsed(response, 'wagtailsearch/editorspicks/confirm_delete.html') diff --git a/wagtail/wagtailsearch/tests/test_frontend.py b/wagtail/wagtailsearch/tests/test_frontend.py index 82189cfc9..8081c968d 100644 --- a/wagtail/wagtailsearch/tests/test_frontend.py +++ b/wagtail/wagtailsearch/tests/test_frontend.py @@ -5,8 +5,10 @@ class TestSearchView(TestCase): def get(self, params={}): return self.client.get('/search/', params) - def test_status_code(self): - self.assertEqual(self.get().status_code, 200) + def test_simple(self): + response = self.get() + self.assertEqual(response.status_code, 200) + self.assertTemplateUsed(response, 'wagtailsearch/search_results.html') def test_search(self): response = self.get({'q': "Hello"}) @@ -24,8 +26,10 @@ class TestSuggestionsView(TestCase): def get(self, params={}): return self.client.get('/search/suggest/', params) - def test_status_code(self): - self.assertEqual(self.get().status_code, 200) + def test_simple(self): + response = self.get() + self.assertEqual(response.status_code, 200) + # TODO: Check that a valid JSON document was returned def test_search(self): response = self.get({'q': "Hello"}) diff --git a/wagtail/wagtailsearch/tests/test_queries.py b/wagtail/wagtailsearch/tests/test_queries.py index 7086d46f4..67325104d 100644 --- a/wagtail/wagtailsearch/tests/test_queries.py +++ b/wagtail/wagtailsearch/tests/test_queries.py @@ -146,8 +146,11 @@ class TestQueryChooserView(TestCase): def get(self, params={}): return self.client.get('/admin/search/queries/chooser/', params) - def test_status_code(self): - self.assertEqual(self.get().status_code, 200) + def test_simple(self): + response = self.get() + self.assertEqual(response.status_code, 200) + self.assertTemplateUsed(response, 'wagtailsearch/queries/chooser/chooser.html') + self.assertTemplateUsed(response, 'wagtailsearch/queries/chooser/chooser.js') def test_search(self): response = self.get({'q': "Hello"}) diff --git a/wagtail/wagtailsnippets/tests.py b/wagtail/wagtailsnippets/tests.py index fd283f7f5..f68062319 100644 --- a/wagtail/wagtailsnippets/tests.py +++ b/wagtail/wagtailsnippets/tests.py @@ -13,8 +13,10 @@ class TestSnippetIndexView(TestCase): def get(self, params={}): return self.client.get(reverse('wagtailsnippets_index'), params) - def test_status_code(self): - self.assertEqual(self.get().status_code, 200) + def test_simple(self): + response = self.get() + self.assertEqual(response.status_code, 200) + self.assertTemplateUsed(response, 'wagtailsnippets/snippets/index.html') def test_displays_snippet(self): self.assertContains(self.get(), "Adverts") @@ -29,8 +31,10 @@ class TestSnippetListView(TestCase): args=('tests', 'advert')), params) - def test_status_code(self): - self.assertEqual(self.get().status_code, 200) + def test_simple(self): + response = self.get() + self.assertEqual(response.status_code, 200) + self.assertTemplateUsed(response, 'wagtailsnippets/snippets/type_index.html') def test_displays_add_button(self): self.assertContains(self.get(), "Add advert") @@ -50,8 +54,10 @@ class TestSnippetCreateView(TestCase): args=('tests', 'advert')), post_data) - def test_status_code(self): - self.assertEqual(self.get().status_code, 200) + def test_simple(self): + response = self.get() + self.assertEqual(response.status_code, 200) + self.assertTemplateUsed(response, 'wagtailsnippets/snippets/create.html') def test_create_invalid(self): response = self.post(post_data={'foo': 'bar'}) @@ -87,8 +93,10 @@ class TestSnippetEditView(TestCase): args=('tests', 'advert', self.test_snippet.id)), post_data) - def test_status_code(self): - self.assertEqual(self.get().status_code, 200) + def test_simple(self): + response = self.get() + self.assertEqual(response.status_code, 200) + self.assertTemplateUsed(response, 'wagtailsnippets/snippets/edit.html') def test_non_existant_model(self): response = self.client.get(reverse('wagtailsnippets_edit', diff --git a/wagtail/wagtailusers/tests.py b/wagtail/wagtailusers/tests.py index bfe0fe4ef..d60d33d47 100644 --- a/wagtail/wagtailusers/tests.py +++ b/wagtail/wagtailusers/tests.py @@ -11,8 +11,10 @@ class TestUserIndexView(TestCase): def get(self, params={}): return self.client.get(reverse('wagtailusers_index'), params) - def test_status_code(self): - self.assertEqual(self.get().status_code, 200) + def test_simple(self): + response = self.get() + self.assertEqual(response.status_code, 200) + self.assertTemplateUsed(response, 'wagtailusers/index.html') def test_search(self): response = self.get({'q': "Hello"}) @@ -36,8 +38,10 @@ class TestUserCreateView(TestCase): def post(self, post_data={}): return self.client.post(reverse('wagtailusers_create'), post_data) - def test_status_code(self): - self.assertEqual(self.get().status_code, 200) + def test_simple(self): + response = self.get() + self.assertEqual(response.status_code, 200) + self.assertTemplateUsed(response, 'wagtailusers/create.html') def test_create(self): response = self.post({ @@ -72,8 +76,10 @@ class TestUserEditView(TestCase): def post(self, post_data={}, user_id=None): return self.client.post(reverse('wagtailusers_edit', args=(user_id or self.test_user.id, )), post_data) - def test_status_code(self): - self.assertEqual(self.get().status_code, 200) + def test_simple(self): + response = self.get() + self.assertEqual(response.status_code, 200) + self.assertTemplateUsed(response, 'wagtailusers/edit.html') def test_nonexistant_redirect(self): self.assertEqual(self.get(user_id=100000).status_code, 404) From f4ee926ffaa17f318cca5ec226a4685866811be7 Mon Sep 17 00:00:00 2001 From: Karl Hobley Date: Mon, 2 Jun 2014 15:56:03 +0100 Subject: [PATCH 035/141] Added URL assertions to tests which test redirecting --- wagtail/wagtailimages/tests.py | 11 +++++++---- wagtail/wagtailredirects/tests.py | 11 +++++++---- wagtail/wagtailsnippets/tests.py | 11 +++++++---- wagtail/wagtailusers/tests.py | 8 +++++--- 4 files changed, 26 insertions(+), 15 deletions(-) diff --git a/wagtail/wagtailimages/tests.py b/wagtail/wagtailimages/tests.py index fdadc3704..c8f0194c0 100644 --- a/wagtail/wagtailimages/tests.py +++ b/wagtail/wagtailimages/tests.py @@ -4,7 +4,7 @@ from django.contrib.auth.models import User, Group, Permission from django.core.urlresolvers import reverse from django.core.files.uploadedfile import SimpleUploadedFile -from wagtail.tests.utils import login, unittest +from wagtail.tests.utils import login, unittest, WagtailTestUtils from wagtail.wagtailimages.models import get_image_model from wagtail.wagtailimages.templatetags import image_tags @@ -217,7 +217,7 @@ class TestImageIndexView(TestCase): self.assertEqual(response.status_code, 200) -class TestImageAddView(TestCase): +class TestImageAddView(TestCase, WagtailTestUtils): def setUp(self): login(self.client) @@ -240,6 +240,7 @@ class TestImageAddView(TestCase): # Should redirect back to index self.assertEqual(response.status_code, 302) + self.assertURLEqual(response.url, reverse('wagtailimages_index')) # Check that the image was created images = Image.objects.filter(title="Test image") @@ -251,7 +252,7 @@ class TestImageAddView(TestCase): self.assertEqual(image.height, 480) -class TestImageEditView(TestCase): +class TestImageEditView(TestCase, WagtailTestUtils): def setUp(self): login(self.client) @@ -279,13 +280,14 @@ class TestImageEditView(TestCase): # Should redirect back to index self.assertEqual(response.status_code, 302) + self.assertURLEqual(response.url, reverse('wagtailimages_index')) # Check that the image was edited image = Image.objects.get(id=self.image.id) self.assertEqual(image.title, "Edited") -class TestImageDeleteView(TestCase): +class TestImageDeleteView(TestCase, WagtailTestUtils): def setUp(self): login(self.client) @@ -313,6 +315,7 @@ class TestImageDeleteView(TestCase): # Should redirect back to index self.assertEqual(response.status_code, 302) + self.assertURLEqual(response.url, reverse('wagtailimages_index')) # Check that the image was deleted images = Image.objects.filter(title="Test image") diff --git a/wagtail/wagtailredirects/tests.py b/wagtail/wagtailredirects/tests.py index f23ea63c9..543a8dd70 100644 --- a/wagtail/wagtailredirects/tests.py +++ b/wagtail/wagtailredirects/tests.py @@ -1,7 +1,7 @@ from django.test import TestCase from django.test.client import Client from wagtail.wagtailredirects import models -from wagtail.tests.utils import login +from wagtail.tests.utils import login, WagtailTestUtils from django.core.urlresolvers import reverse @@ -90,7 +90,7 @@ class TestRedirectsIndexView(TestCase): self.assertEqual(response.status_code, 200) -class TestRedirectsAddView(TestCase): +class TestRedirectsAddView(TestCase, WagtailTestUtils): def setUp(self): login(self.client) @@ -114,6 +114,7 @@ class TestRedirectsAddView(TestCase): # Should redirect back to index self.assertEqual(response.status_code, 302) + self.assertURLEqual(response.url, reverse('wagtailredirects_index')) # Check that the redirect was created redirects = models.Redirect.objects.filter(old_path='/test') @@ -131,7 +132,7 @@ class TestRedirectsAddView(TestCase): self.assertEqual(response.status_code, 200) -class TestRedirectsEditView(TestCase): +class TestRedirectsEditView(TestCase, WagtailTestUtils): def setUp(self): # Create a redirect to edit self.redirect = models.Redirect(old_path='/test', redirect_link='http://www.test.com/') @@ -163,6 +164,7 @@ class TestRedirectsEditView(TestCase): # Should redirect back to index self.assertEqual(response.status_code, 302) + self.assertURLEqual(response.url, reverse('wagtailredirects_index')) # Check that the redirect was edited redirects = models.Redirect.objects.filter(old_path='/test') @@ -179,7 +181,7 @@ class TestRedirectsEditView(TestCase): # Should not redirect to index self.assertEqual(response.status_code, 200) -class TestRedirectsDeleteView(TestCase): +class TestRedirectsDeleteView(TestCase, WagtailTestUtils): def setUp(self): # Create a redirect to edit self.redirect = models.Redirect(old_path='/test', redirect_link='http://www.test.com/') @@ -209,6 +211,7 @@ class TestRedirectsDeleteView(TestCase): # Should redirect back to index self.assertEqual(response.status_code, 302) + self.assertURLEqual(response.url, reverse('wagtailredirects_index')) # Check that the redirect was deleted redirects = models.Redirect.objects.filter(old_path='/test') diff --git a/wagtail/wagtailsnippets/tests.py b/wagtail/wagtailsnippets/tests.py index f68062319..3adaf5a3b 100644 --- a/wagtail/wagtailsnippets/tests.py +++ b/wagtail/wagtailsnippets/tests.py @@ -2,7 +2,7 @@ from django.test import TestCase from django.core.urlresolvers import reverse from django.contrib.auth.models import User -from wagtail.tests.utils import login, unittest +from wagtail.tests.utils import login, unittest, WagtailTestUtils from wagtail.tests.models import Advert @@ -40,7 +40,7 @@ class TestSnippetListView(TestCase): self.assertContains(self.get(), "Add advert") -class TestSnippetCreateView(TestCase): +class TestSnippetCreateView(TestCase, WagtailTestUtils): def setUp(self): login(self.client) @@ -68,13 +68,14 @@ class TestSnippetCreateView(TestCase): response = self.post(post_data={'text': 'test_advert', 'url': 'http://www.example.com/'}) self.assertEqual(response.status_code, 302) + self.assertURLEqual(response.url, reverse('wagtailsnippets_list', args=('tests', 'advert'))) snippets = Advert.objects.filter(text='test_advert') self.assertEqual(snippets.count(), 1) self.assertEqual(snippets.first().url, 'http://www.example.com/') -class TestSnippetEditView(TestCase): +class TestSnippetEditView(TestCase, WagtailTestUtils): def setUp(self): self.test_snippet = Advert() self.test_snippet.text = 'test_advert' @@ -117,13 +118,14 @@ class TestSnippetEditView(TestCase): response = self.post(post_data={'text': 'edited_test_advert', 'url': 'http://www.example.com/edited'}) self.assertEqual(response.status_code, 302) + self.assertURLEqual(response.url, reverse('wagtailsnippets_list', args=('tests', 'advert'))) snippets = Advert.objects.filter(text='edited_test_advert') self.assertEqual(snippets.count(), 1) self.assertEqual(snippets.first().url, 'http://www.example.com/edited') -class TestSnippetDelete(TestCase): +class TestSnippetDelete(TestCase, WagtailTestUtils): def setUp(self): self.test_snippet = Advert() self.test_snippet.text = 'test_advert' @@ -142,6 +144,7 @@ class TestSnippetDelete(TestCase): # Should be redirected to explorer page self.assertEqual(response.status_code, 302) + self.assertURLEqual(response.url, reverse('wagtailsnippets_list', args=('tests', 'advert'))) # Check that the page is gone self.assertEqual(Advert.objects.filter(text='test_advert').count(), 0) diff --git a/wagtail/wagtailusers/tests.py b/wagtail/wagtailusers/tests.py index d60d33d47..c9105e3c0 100644 --- a/wagtail/wagtailusers/tests.py +++ b/wagtail/wagtailusers/tests.py @@ -1,7 +1,7 @@ from django.test import TestCase from django.core.urlresolvers import reverse from django.contrib.auth.models import User -from wagtail.tests.utils import login +from wagtail.tests.utils import login, WagtailTestUtils class TestUserIndexView(TestCase): @@ -28,7 +28,7 @@ class TestUserIndexView(TestCase): self.assertEqual(response.status_code, 200) -class TestUserCreateView(TestCase): +class TestUserCreateView(TestCase, WagtailTestUtils): def setUp(self): login(self.client) @@ -55,6 +55,7 @@ class TestUserCreateView(TestCase): # Should redirect back to index self.assertEqual(response.status_code, 302) + self.assertURLEqual(response.url, reverse('wagtailusers_index')) # Check that the user was created users = User.objects.filter(username='testuser') @@ -62,7 +63,7 @@ class TestUserCreateView(TestCase): self.assertEqual(users.first().email, 'test@user.com') -class TestUserEditView(TestCase): +class TestUserEditView(TestCase, WagtailTestUtils): def setUp(self): # Create a user to edit self.test_user = User.objects.create_user(username='testuser', email='testuser@email.com', password='password') @@ -96,6 +97,7 @@ class TestUserEditView(TestCase): # Should redirect back to index self.assertEqual(response.status_code, 302) + self.assertURLEqual(response.url, reverse('wagtailusers_index')) # Check that the user was edited user = User.objects.get(id=self.test_user.id) From eddc3fc917791c80c3bad250721bbb30ace9238e Mon Sep 17 00:00:00 2001 From: Karl Hobley Date: Mon, 2 Jun 2014 16:07:31 +0100 Subject: [PATCH 036/141] Always use login method from WagtailTestUtils --- wagtail/tests/utils.py | 18 +++++------ wagtail/wagtailadmin/tests/tests.py | 10 +++---- wagtail/wagtaildocs/tests.py | 30 +++++++++---------- wagtail/wagtailembeds/tests.py | 6 ++-- wagtail/wagtailimages/tests.py | 24 +++++++-------- wagtail/wagtailredirects/tests.py | 12 ++++---- .../wagtailsearch/tests/test_editorspicks.py | 24 +++++++++------ wagtail/wagtailsearch/tests/test_queries.py | 6 ++-- wagtail/wagtailsnippets/tests.py | 16 +++++----- wagtail/wagtailusers/tests.py | 10 +++---- 10 files changed, 79 insertions(+), 77 deletions(-) diff --git a/wagtail/tests/utils.py b/wagtail/tests/utils.py index 0497b239a..0b13e5932 100644 --- a/wagtail/tests/utils.py +++ b/wagtail/tests/utils.py @@ -15,19 +15,15 @@ except ImportError: import unittest -def login(client): - # Create a user - user = User.objects.create_superuser(username='test', email='test@email.com', password='password') - - # Login - client.login(username='test', password='password') - - return user - - class WagtailTestUtils(object): def login(self): - return login(self.client) + # Create a user + user = User.objects.create_superuser(username='test', email='test@email.com', password='password') + + # Login + self.client.login(username='test', password='password') + + return user # From: https://github.com/django/django/blob/255449c1ee61c14778658caae8c430fa4d76afd6/django/contrib/auth/tests/test_views.py#L70-L85 def assertURLEqual(self, url, expected, parse_qs=False): diff --git a/wagtail/wagtailadmin/tests/tests.py b/wagtail/wagtailadmin/tests/tests.py index b0c0896e2..f014c026d 100644 --- a/wagtail/wagtailadmin/tests/tests.py +++ b/wagtail/wagtailadmin/tests/tests.py @@ -1,26 +1,26 @@ from django.test import TestCase from wagtail.tests.models import SimplePage, EventPage -from wagtail.tests.utils import login, unittest +from wagtail.tests.utils import unittest, WagtailTestUtils from wagtail.wagtailcore.models import Page from wagtail.wagtailadmin.tasks import send_email_task from django.core.urlresolvers import reverse from django.core import mail -class TestHome(TestCase): +class TestHome(TestCase, WagtailTestUtils): def setUp(self): # Login - login(self.client) + self.login() def test_simple(self): response = self.client.get(reverse('wagtailadmin_home')) self.assertEqual(response.status_code, 200) -class TestEditorHooks(TestCase): +class TestEditorHooks(TestCase, WagtailTestUtils): def setUp(self): self.homepage = Page.objects.get(id=2) - login(self.client) + self.login() def test_editor_css_and_js_hooks_on_add(self): response = self.client.get(reverse('wagtailadmin_pages_create', args=('tests', 'simplepage', self.homepage.id))) diff --git a/wagtail/wagtaildocs/tests.py b/wagtail/wagtaildocs/tests.py index 33da3e33a..3353ce39e 100644 --- a/wagtail/wagtaildocs/tests.py +++ b/wagtail/wagtaildocs/tests.py @@ -1,6 +1,6 @@ from django.test import TestCase from wagtail.wagtaildocs import models -from wagtail.tests.utils import login +from wagtail.tests.utils import WagtailTestUtils from django.contrib.auth.models import User, Group, Permission from django.core.urlresolvers import reverse from django.core.files.base import ContentFile @@ -39,9 +39,9 @@ class TestDocumentPermissions(TestCase): ## ===== ADMIN VIEWS ===== -class TestDocumentIndexView(TestCase): +class TestDocumentIndexView(TestCase, WagtailTestUtils): def setUp(self): - login(self.client) + self.login() def get(self, params={}): return self.client.get(reverse('wagtaildocs_index'), params) @@ -69,9 +69,9 @@ class TestDocumentIndexView(TestCase): self.assertEqual(response.status_code, 200) -class TestDocumentAddView(TestCase): +class TestDocumentAddView(TestCase, WagtailTestUtils): def setUp(self): - login(self.client) + self.login() def get(self, params={}): return self.client.get(reverse('wagtaildocs_add_document'), params) @@ -84,9 +84,9 @@ class TestDocumentAddView(TestCase): # TODO: Test posting -class TestDocumentEditView(TestCase): +class TestDocumentEditView(TestCase, WagtailTestUtils): def setUp(self): - login(self.client) + self.login() # Create a document to edit self.document = models.Document.objects.create(title="Test document") @@ -102,9 +102,9 @@ class TestDocumentEditView(TestCase): # TODO: Test posting -class TestDocumentDeleteView(TestCase): +class TestDocumentDeleteView(TestCase, WagtailTestUtils): def setUp(self): - login(self.client) + self.login() # Create a document to delete self.document = models.Document.objects.create(title="Test document") @@ -120,9 +120,9 @@ class TestDocumentDeleteView(TestCase): # TODO: Test posting -class TestDocumentChooserView(TestCase): +class TestDocumentChooserView(TestCase, WagtailTestUtils): def setUp(self): - login(self.client) + self.login() def get(self, params={}): return self.client.get(reverse('wagtaildocs_chooser'), params) @@ -145,9 +145,9 @@ class TestDocumentChooserView(TestCase): self.assertEqual(response.status_code, 200) -class TestDocumentChooserChosenView(TestCase): +class TestDocumentChooserChosenView(TestCase, WagtailTestUtils): def setUp(self): - login(self.client) + self.login() # Create a document to choose self.document = models.Document.objects.create(title="Test document") @@ -163,9 +163,9 @@ class TestDocumentChooserChosenView(TestCase): # TODO: Test posting -class TestDocumentChooserUploadView(TestCase): +class TestDocumentChooserUploadView(TestCase, WagtailTestUtils): def setUp(self): - login(self.client) + self.login() def get(self, params={}): return self.client.get(reverse('wagtaildocs_chooser_upload'), params) diff --git a/wagtail/wagtailembeds/tests.py b/wagtail/wagtailembeds/tests.py index b1eefdb17..b1268729e 100644 --- a/wagtail/wagtailembeds/tests.py +++ b/wagtail/wagtailembeds/tests.py @@ -1,7 +1,7 @@ from django.test import TestCase from django.test.client import Client -from wagtail.tests.utils import login from wagtail.wagtailembeds import get_embed +from wagtail.tests.utils import WagtailTestUtils class TestEmbeds(TestCase): @@ -63,10 +63,10 @@ class TestEmbeds(TestCase): self.assertEqual(embed.width, None) -class TestChooser(TestCase): +class TestChooser(TestCase, WagtailTestUtils): def setUp(self): # login - login(self.client) + self.login() def test_chooser(self): r = self.client.get('/admin/embeds/chooser/') diff --git a/wagtail/wagtailimages/tests.py b/wagtail/wagtailimages/tests.py index c8f0194c0..d01535eda 100644 --- a/wagtail/wagtailimages/tests.py +++ b/wagtail/wagtailimages/tests.py @@ -4,7 +4,7 @@ from django.contrib.auth.models import User, Group, Permission from django.core.urlresolvers import reverse from django.core.files.uploadedfile import SimpleUploadedFile -from wagtail.tests.utils import login, unittest, WagtailTestUtils +from wagtail.tests.utils import unittest, WagtailTestUtils from wagtail.wagtailimages.models import get_image_model from wagtail.wagtailimages.templatetags import image_tags @@ -187,9 +187,9 @@ class TestImageTag(TestCase): ## ===== ADMIN VIEWS ===== -class TestImageIndexView(TestCase): +class TestImageIndexView(TestCase, WagtailTestUtils): def setUp(self): - login(self.client) + self.login() def get(self, params={}): return self.client.get(reverse('wagtailimages_index'), params) @@ -219,7 +219,7 @@ class TestImageIndexView(TestCase): class TestImageAddView(TestCase, WagtailTestUtils): def setUp(self): - login(self.client) + self.login() def get(self, params={}): return self.client.get(reverse('wagtailimages_add_image'), params) @@ -254,7 +254,7 @@ class TestImageAddView(TestCase, WagtailTestUtils): class TestImageEditView(TestCase, WagtailTestUtils): def setUp(self): - login(self.client) + self.login() # Create an image to edit self.image = Image.objects.create( @@ -289,7 +289,7 @@ class TestImageEditView(TestCase, WagtailTestUtils): class TestImageDeleteView(TestCase, WagtailTestUtils): def setUp(self): - login(self.client) + self.login() # Create an image to edit self.image = Image.objects.create( @@ -322,9 +322,9 @@ class TestImageDeleteView(TestCase, WagtailTestUtils): self.assertEqual(images.count(), 0) -class TestImageChooserView(TestCase): +class TestImageChooserView(TestCase, WagtailTestUtils): def setUp(self): - login(self.client) + self.login() def get(self, params={}): return self.client.get(reverse('wagtailimages_chooser'), params) @@ -347,9 +347,9 @@ class TestImageChooserView(TestCase): self.assertEqual(response.status_code, 200) -class TestImageChooserChosenView(TestCase): +class TestImageChooserChosenView(TestCase, WagtailTestUtils): def setUp(self): - login(self.client) + self.login() # Create an image to edit self.image = Image.objects.create( @@ -368,9 +368,9 @@ class TestImageChooserChosenView(TestCase): # TODO: Test posting -class TestImageChooserUploadView(TestCase): +class TestImageChooserUploadView(TestCase, WagtailTestUtils): def setUp(self): - login(self.client) + self.login() def get(self, params={}): return self.client.get(reverse('wagtailimages_chooser_upload'), params) diff --git a/wagtail/wagtailredirects/tests.py b/wagtail/wagtailredirects/tests.py index 543a8dd70..29ad7ec0b 100644 --- a/wagtail/wagtailredirects/tests.py +++ b/wagtail/wagtailredirects/tests.py @@ -1,7 +1,7 @@ from django.test import TestCase from django.test.client import Client from wagtail.wagtailredirects import models -from wagtail.tests.utils import login, WagtailTestUtils +from wagtail.tests.utils import WagtailTestUtils from django.core.urlresolvers import reverse @@ -66,9 +66,9 @@ class TestRedirects(TestCase): self.assertTrue(r.has_header('Location')) -class TestRedirectsIndexView(TestCase): +class TestRedirectsIndexView(TestCase, WagtailTestUtils): def setUp(self): - login(self.client) + self.login() def get(self, params={}): return self.client.get(reverse('wagtailredirects_index'), params) @@ -92,7 +92,7 @@ class TestRedirectsIndexView(TestCase): class TestRedirectsAddView(TestCase, WagtailTestUtils): def setUp(self): - login(self.client) + self.login() def get(self, params={}): return self.client.get(reverse('wagtailredirects_add_redirect'), params) @@ -139,7 +139,7 @@ class TestRedirectsEditView(TestCase, WagtailTestUtils): self.redirect.save() # Login - login(self.client) + self.login() def get(self, params={}, redirect_id=None): return self.client.get(reverse('wagtailredirects_edit_redirect', args=(redirect_id or self.redirect.id, )), params) @@ -188,7 +188,7 @@ class TestRedirectsDeleteView(TestCase, WagtailTestUtils): self.redirect.save() # Login - login(self.client) + self.login() def get(self, params={}, redirect_id=None): return self.client.get(reverse('wagtailredirects_delete_redirect', args=(redirect_id or self.redirect.id, )), params) diff --git a/wagtail/wagtailsearch/tests/test_editorspicks.py b/wagtail/wagtailsearch/tests/test_editorspicks.py index 2af0df625..7ee974fd0 100644 --- a/wagtail/wagtailsearch/tests/test_editorspicks.py +++ b/wagtail/wagtailsearch/tests/test_editorspicks.py @@ -1,5 +1,5 @@ from django.test import TestCase -from wagtail.tests.utils import login +from wagtail.tests.utils import unittest, WagtailTestUtils from wagtail.wagtailsearch import models @@ -45,9 +45,9 @@ class TestEditorsPicks(TestCase): self.assertEqual(models.Query.get("root page").editors_picks.last().description, "Last editors pick") -class TestEditorsPicksIndexView(TestCase): +class TestEditorsPicksIndexView(TestCase, WagtailTestUtils): def setUp(self): - login(self.client) + self.login() def get(self, params={}): return self.client.get('/admin/search/editorspicks/', params) @@ -69,9 +69,9 @@ class TestEditorsPicksIndexView(TestCase): self.assertEqual(response.status_code, 200) -class TestEditorsPicksAddView(TestCase): +class TestEditorsPicksAddView(TestCase, WagtailTestUtils): def setUp(self): - login(self.client) + self.login() def get(self, params={}): return self.client.get('/admin/search/editorspicks/add/', params) @@ -81,10 +81,12 @@ class TestEditorsPicksAddView(TestCase): self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, 'wagtailsearch/editorspicks/add.html') + # TODO: Test posting -class TestEditorsPicksEditView(TestCase): + +class TestEditorsPicksEditView(TestCase, WagtailTestUtils): def setUp(self): - login(self.client) + self.login() # Create an editors pick to edit self.query = models.Query.get("Hello") @@ -98,10 +100,12 @@ class TestEditorsPicksEditView(TestCase): self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, 'wagtailsearch/editorspicks/edit.html') + # TODO: Test posting -class TestEditorsPicksDeleteView(TestCase): + +class TestEditorsPicksDeleteView(TestCase, WagtailTestUtils): def setUp(self): - login(self.client) + self.login() # Create an editors pick to delete self.query = models.Query.get("Hello") @@ -114,3 +118,5 @@ class TestEditorsPicksDeleteView(TestCase): response = self.get() self.assertEqual(response.status_code, 200) self.assertTemplateUsed(response, 'wagtailsearch/editorspicks/confirm_delete.html') + + # TODO: Test posting diff --git a/wagtail/wagtailsearch/tests/test_queries.py b/wagtail/wagtailsearch/tests/test_queries.py index 67325104d..ee5382db4 100644 --- a/wagtail/wagtailsearch/tests/test_queries.py +++ b/wagtail/wagtailsearch/tests/test_queries.py @@ -1,7 +1,7 @@ from django.test import TestCase from django.core import management from wagtail.wagtailsearch import models -from wagtail.tests.utils import login, unittest +from wagtail.tests.utils import unittest, WagtailTestUtils from StringIO import StringIO @@ -139,9 +139,9 @@ class TestGarbageCollectCommand(TestCase): # TODO: Test that this command is acctually doing its job -class TestQueryChooserView(TestCase): +class TestQueryChooserView(TestCase, WagtailTestUtils): def setUp(self): - login(self.client) + self.login() def get(self, params={}): return self.client.get('/admin/search/queries/chooser/', params) diff --git a/wagtail/wagtailsnippets/tests.py b/wagtail/wagtailsnippets/tests.py index 3adaf5a3b..bf9d62731 100644 --- a/wagtail/wagtailsnippets/tests.py +++ b/wagtail/wagtailsnippets/tests.py @@ -2,13 +2,13 @@ from django.test import TestCase from django.core.urlresolvers import reverse from django.contrib.auth.models import User -from wagtail.tests.utils import login, unittest, WagtailTestUtils +from wagtail.tests.utils import unittest, WagtailTestUtils from wagtail.tests.models import Advert -class TestSnippetIndexView(TestCase): +class TestSnippetIndexView(TestCase, WagtailTestUtils): def setUp(self): - login(self.client) + self.login() def get(self, params={}): return self.client.get(reverse('wagtailsnippets_index'), params) @@ -22,9 +22,9 @@ class TestSnippetIndexView(TestCase): self.assertContains(self.get(), "Adverts") -class TestSnippetListView(TestCase): +class TestSnippetListView(TestCase, WagtailTestUtils): def setUp(self): - login(self.client) + self.login() def get(self, params={}): return self.client.get(reverse('wagtailsnippets_list', @@ -42,7 +42,7 @@ class TestSnippetListView(TestCase): class TestSnippetCreateView(TestCase, WagtailTestUtils): def setUp(self): - login(self.client) + self.login() def get(self, params={}): return self.client.get(reverse('wagtailsnippets_create', @@ -82,7 +82,7 @@ class TestSnippetEditView(TestCase, WagtailTestUtils): self.test_snippet.url = 'http://www.example.com/' self.test_snippet.save() - login(self.client) + self.login() def get(self, params={}): return self.client.get(reverse('wagtailsnippets_edit', @@ -132,7 +132,7 @@ class TestSnippetDelete(TestCase, WagtailTestUtils): self.test_snippet.url = 'http://www.example.com/' self.test_snippet.save() - login(self.client) + self.login() def test_delete_get(self): response = self.client.get(reverse('wagtailsnippets_delete', args=('tests', 'advert', self.test_snippet.id, ))) diff --git a/wagtail/wagtailusers/tests.py b/wagtail/wagtailusers/tests.py index c9105e3c0..6de97f202 100644 --- a/wagtail/wagtailusers/tests.py +++ b/wagtail/wagtailusers/tests.py @@ -1,12 +1,12 @@ from django.test import TestCase from django.core.urlresolvers import reverse from django.contrib.auth.models import User -from wagtail.tests.utils import login, WagtailTestUtils +from wagtail.tests.utils import WagtailTestUtils -class TestUserIndexView(TestCase): +class TestUserIndexView(TestCase, WagtailTestUtils): def setUp(self): - login(self.client) + self.login() def get(self, params={}): return self.client.get(reverse('wagtailusers_index'), params) @@ -30,7 +30,7 @@ class TestUserIndexView(TestCase): class TestUserCreateView(TestCase, WagtailTestUtils): def setUp(self): - login(self.client) + self.login() def get(self, params={}): return self.client.get(reverse('wagtailusers_create'), params) @@ -69,7 +69,7 @@ class TestUserEditView(TestCase, WagtailTestUtils): self.test_user = User.objects.create_user(username='testuser', email='testuser@email.com', password='password') # Login - login(self.client) + self.login() def get(self, params={}, user_id=None): return self.client.get(reverse('wagtailusers_edit', args=(user_id or self.test_user.id, )), params) From 94f14ab12a191db6d188c88f3c6947f974bf4011 Mon Sep 17 00:00:00 2001 From: Karl Hobley Date: Mon, 2 Jun 2014 16:17:40 +0100 Subject: [PATCH 037/141] Added changelog entry for #280 --- CHANGELOG.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 0a6024bd1..d2914194b 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,6 +1,8 @@ Changelog ========= + * When logged in user visits login page, they are now redirected to the dashboard + 0.3 (28.05.2014) ~~~~~~~~~~~~~~~~ * Added toolbar to allow logged-in users to add and edit pages from the site front-end From 12b81cb8570db762c9891bcd3380e8115e5555ed Mon Sep 17 00:00:00 2001 From: Karl Hobley Date: Mon, 2 Jun 2014 17:06:18 +0100 Subject: [PATCH 038/141] Added page pagination --- .../templates/wagtailadmin/pages/list.html | 22 ++++++++++++++++++- wagtail/wagtailadmin/views/pages.py | 10 +++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/wagtail/wagtailadmin/templates/wagtailadmin/pages/list.html b/wagtail/wagtailadmin/templates/wagtailadmin/pages/list.html index 7078834ae..0c8f16467 100644 --- a/wagtail/wagtailadmin/templates/wagtailadmin/pages/list.html +++ b/wagtail/wagtailadmin/templates/wagtailadmin/pages/list.html @@ -229,4 +229,24 @@

    {% trans "No pages have been created." %}{% if parent_page and parent_page_perms.can_add_subpage %} {% blocktrans %}Why not add one?{% endblocktrans %}{% endif %} {% endif %} - \ No newline at end of file + + +{% if parent_page and pages and pages.paginator %} +

    +{% endif %} \ No newline at end of file diff --git a/wagtail/wagtailadmin/views/pages.py b/wagtail/wagtailadmin/views/pages.py index 308f6fdd4..64c612a7b 100644 --- a/wagtail/wagtailadmin/views/pages.py +++ b/wagtail/wagtailadmin/views/pages.py @@ -33,6 +33,16 @@ def index(request, parent_page_id=None): else: ordering = 'title' + # Pagination + p = request.GET.get('p', 1) + paginator = Paginator(pages, 50) + try: + pages = paginator.page(p) + except PageNotAnInteger: + pages = paginator.page(1) + except EmptyPage: + pages = paginator.page(paginator.num_pages) + return render(request, 'wagtailadmin/pages/index.html', { 'parent_page': parent_page, 'ordering': ordering, From 8b1db37b4474f32802d372f7f42ec6fda0476d31 Mon Sep 17 00:00:00 2001 From: Karl Hobley Date: Mon, 2 Jun 2014 17:10:11 +0100 Subject: [PATCH 039/141] Keep ordering when paginating pages --- wagtail/wagtailadmin/templates/wagtailadmin/pages/list.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wagtail/wagtailadmin/templates/wagtailadmin/pages/list.html b/wagtail/wagtailadmin/templates/wagtailadmin/pages/list.html index 0c8f16467..7258c5429 100644 --- a/wagtail/wagtailadmin/templates/wagtailadmin/pages/list.html +++ b/wagtail/wagtailadmin/templates/wagtailadmin/pages/list.html @@ -239,12 +239,12 @@ From 414b3684b98da784c8b486ffc081f360921ebe1a Mon Sep 17 00:00:00 2001 From: Karl Hobley Date: Mon, 2 Jun 2014 17:15:28 +0100 Subject: [PATCH 040/141] Don't paginate if the user is reordering --- wagtail/wagtailadmin/views/pages.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/wagtail/wagtailadmin/views/pages.py b/wagtail/wagtailadmin/views/pages.py index 64c612a7b..b5779a6ad 100644 --- a/wagtail/wagtailadmin/views/pages.py +++ b/wagtail/wagtailadmin/views/pages.py @@ -34,14 +34,15 @@ def index(request, parent_page_id=None): ordering = 'title' # Pagination - p = request.GET.get('p', 1) - paginator = Paginator(pages, 50) - try: - pages = paginator.page(p) - except PageNotAnInteger: - pages = paginator.page(1) - except EmptyPage: - pages = paginator.page(paginator.num_pages) + if ordering != 'ord': + p = request.GET.get('p', 1) + paginator = Paginator(pages, 50) + try: + pages = paginator.page(p) + except PageNotAnInteger: + pages = paginator.page(1) + except EmptyPage: + pages = paginator.page(paginator.num_pages) return render(request, 'wagtailadmin/pages/index.html', { 'parent_page': parent_page, From 1be56484b410cca6f50b5534b48fba400272f46e Mon Sep 17 00:00:00 2001 From: Jeffrey Hearn Date: Mon, 2 Jun 2014 13:47:30 -0400 Subject: [PATCH 041/141] Updated hallo.js library to 1.0.4 from unknown version --- .../static/wagtailadmin/js/vendor/hallo.js | 3975 +++++++++-------- 1 file changed, 2116 insertions(+), 1859 deletions(-) diff --git a/wagtail/wagtailadmin/static/wagtailadmin/js/vendor/hallo.js b/wagtail/wagtailadmin/static/wagtailadmin/js/vendor/hallo.js index 7ba3ff2c0..af5950fdb 100644 --- a/wagtail/wagtailadmin/static/wagtailadmin/js/vendor/hallo.js +++ b/wagtail/wagtailadmin/static/wagtailadmin/js/vendor/hallo.js @@ -1,671 +1,607 @@ -// Generated by CoffeeScript 1.3.3 -(function() { - - $.widget("ncri.hallohtml", { - options: { - editable: null, +/* Hallo 1.0.4 - rich text editor for jQuery UI +* by Henri Bergius and contributors. Available under the MIT license. +* See http://hallojs.org for more information +*/(function() { + (function(jQuery) { + return jQuery.widget('IKS.hallo', { toolbar: null, - uuid: "", - lang: 'en', - dialogOpts: { - autoOpen: false, - width: 600, - height: 'auto', - modal: false, - resizable: true, - draggable: true, - dialogClass: 'htmledit-dialog' + bound: false, + originalContent: '', + previousContent: '', + uuid: '', + selection: null, + _keepActivated: false, + originalHref: null, + options: { + editable: true, + plugins: {}, + toolbar: 'halloToolbarContextual', + parentElement: 'body', + buttonCssClass: null, + toolbarCssClass: null, + toolbarPositionAbove: false, + toolbarOptions: {}, + placeholder: '', + forceStructured: true, + checkTouch: true, + touchScreen: null }, - dialog: null, - buttonCssClass: null - }, - translations: { - en: { - title: 'Edit HTML', - update: 'Update' + _create: function() { + var options, plugin, _ref, + _this = this; + this.id = this._generateUUID(); + if (this.options.checkTouch && this.options.touchScreen === null) { + this.checkTouch(); + } + _ref = this.options.plugins; + for (plugin in _ref) { + options = _ref[plugin]; + if (!jQuery.isPlainObject(options)) { + options = {}; + } + jQuery.extend(options, { + editable: this, + uuid: this.id, + buttonCssClass: this.options.buttonCssClass + }); + jQuery(this.element)[plugin](options); + } + this.element.one('halloactivated', function() { + return _this._prepareToolbar(); + }); + return this.originalContent = this.getContents(); }, - de: { - title: 'HTML bearbeiten', - update: 'Aktualisieren' - } - }, - texts: null, - populateToolbar: function($toolbar) { - var $buttonHolder, $buttonset, id, widget; - widget = this; - this.texts = this.translations[this.options.lang]; - this.options.toolbar = $toolbar; - this.options.dialog = $("
    ").attr('id', "" + this.options.uuid + "-htmledit-dialog"); - $buttonset = $("").addClass(widget.widgetName); - id = "" + this.options.uuid + "-htmledit"; - $buttonHolder = $(''); - $buttonHolder.hallobutton({ - label: this.texts.title, - icon: 'icon-list-alt', - editable: this.options.editable, - command: null, - queryState: false, - uuid: this.options.uuid, - cssClass: this.options.buttonCssClass - }); - $buttonset.append($buttonHolder); - this.button = $buttonHolder; - this.button.click(function() { - if (widget.options.dialog.dialog("isOpen")) { - widget._closeDialog(); + _init: function() { + if (this.options.editable) { + return this.enable(); } else { - widget._openDialog(); + return this.disable(); + } + }, + destroy: function() { + var options, plugin, _ref; + this.disable(); + if (this.toolbar) { + this.toolbar.remove(); + this.element[this.options.toolbar]('destroy'); + } + _ref = this.options.plugins; + for (plugin in _ref) { + options = _ref[plugin]; + jQuery(this.element)[plugin]('destroy'); + } + return jQuery.Widget.prototype.destroy.call(this); + }, + disable: function() { + var _this = this; + this.element.attr("contentEditable", false); + this.element.off("focus", this._activated); + this.element.off("blur", this._deactivated); + this.element.off("keyup paste change", this._checkModified); + this.element.off("keyup", this._keys); + this.element.off("keyup mouseup", this._checkSelection); + this.bound = false; + jQuery(this.element).removeClass('isModified'); + jQuery(this.element).removeClass('inEditMode'); + this.element.parents('a').addBack().each(function(idx, elem) { + var element; + element = jQuery(elem); + if (!element.is('a')) { + return; + } + if (!_this.originalHref) { + return; + } + return element.attr('href', _this.originalHref); + }); + return this._trigger("disabled", null); + }, + enable: function() { + var _this = this; + this.element.parents('a[href]').addBack().each(function(idx, elem) { + var element; + element = jQuery(elem); + if (!element.is('a[href]')) { + return; + } + _this.originalHref = element.attr('href'); + return element.removeAttr('href'); + }); + this.element.attr("contentEditable", true); + if (!jQuery.parseHTML(this.element.html())) { + this.element.html(this.options.placeholder); + jQuery(this.element).addClass('inPlaceholderMode'); + this.element.css({ + 'min-width': this.element.innerWidth(), + 'min-height': this.element.innerHeight() + }); + } + if (!this.bound) { + this.element.on("focus", this, this._activated); + this.element.on("blur", this, this._deactivated); + this.element.on("keyup paste change", this, this._checkModified); + this.element.on("keyup", this, this._keys); + this.element.on("keyup mouseup", this, this._checkSelection); + this.bound = true; + } + if (this.options.forceStructured) { + this._forceStructured(); + } + return this._trigger("enabled", null); + }, + activate: function() { + return this.element.focus(); + }, + containsSelection: function() { + var range; + range = this.getSelection(); + return this.element.has(range.startContainer).length > 0; + }, + getSelection: function() { + var range, sel; + sel = rangy.getSelection(); + range = null; + if (sel.rangeCount > 0) { + range = sel.getRangeAt(0); + } else { + range = rangy.createRange(); + } + return range; + }, + restoreSelection: function(range) { + var sel; + sel = rangy.getSelection(); + return sel.setSingleRange(range); + }, + replaceSelection: function(cb) { + var newTextNode, r, range, sel, t; + if (navigator.appName === 'Microsoft Internet Explorer') { + t = document.selection.createRange().text; + r = document.selection.createRange(); + return r.pasteHTML(cb(t)); + } else { + sel = window.getSelection(); + range = sel.getRangeAt(0); + newTextNode = document.createTextNode(cb(range.extractContents())); + range.insertNode(newTextNode); + range.setStartAfter(newTextNode); + sel.removeAllRanges(); + return sel.addRange(range); + } + }, + removeAllSelections: function() { + if (navigator.appName === 'Microsoft Internet Explorer') { + return range.empty(); + } else { + return window.getSelection().removeAllRanges(); + } + }, + getPluginInstance: function(plugin) { + var instance; + instance = jQuery(this.element).data("IKS-" + plugin); + if (instance) { + return instance; + } + instance = jQuery(this.element).data(plugin); + if (instance) { + return instance; + } + throw new Error("Plugin " + plugin + " not found"); + }, + getContents: function() { + var cleanup, instance, plugin; + for (plugin in this.options.plugins) { + instance = this.getPluginInstance(plugin); + if (!instance) { + continue; + } + cleanup = instance.cleanupContentClone; + if (!jQuery.isFunction(cleanup)) { + continue; + } + jQuery(this.element)[plugin]('cleanupContentClone', this.element); + } + return this.element.html(); + }, + setContents: function(contents) { + return this.element.html(contents); + }, + isModified: function() { + if (!this.previousContent) { + this.previousContent = this.originalContent; + } + return this.previousContent !== this.getContents(); + }, + setUnmodified: function() { + jQuery(this.element).removeClass('isModified'); + return this.previousContent = this.getContents(); + }, + setModified: function() { + jQuery(this.element).addClass('isModified'); + return this._trigger('modified', null, { + editable: this, + content: this.getContents() + }); + }, + restoreOriginalContent: function() { + return this.element.html(this.originalContent); + }, + execute: function(command, value) { + if (document.execCommand(command, false, value)) { + return this.element.trigger("change"); + } + }, + protectFocusFrom: function(el) { + var _this = this; + return el.on("mousedown", function(event) { + event.preventDefault(); + _this._protectToolbarFocus = true; + return setTimeout(function() { + return _this._protectToolbarFocus = false; + }, 300); + }); + }, + keepActivated: function(_keepActivated) { + this._keepActivated = _keepActivated; + }, + _generateUUID: function() { + var S4; + S4 = function() { + return ((1 + Math.random()) * 0x10000 | 0).toString(16).substring(1); + }; + return "" + (S4()) + (S4()) + "-" + (S4()) + "-" + (S4()) + "-" + (S4()) + "-" + (S4()) + (S4()) + (S4()); + }, + _prepareToolbar: function() { + var defaults, instance, plugin, populate, toolbarOptions; + this.toolbar = jQuery('
    ').hide(); + if (this.options.toolbarCssClass) { + this.toolbar.addClass(this.options.toolbarCssClass); + } + defaults = { + editable: this, + parentElement: this.options.parentElement, + toolbar: this.toolbar, + positionAbove: this.options.toolbarPositionAbove + }; + toolbarOptions = jQuery.extend({}, defaults, this.options.toolbarOptions); + this.element[this.options.toolbar](toolbarOptions); + for (plugin in this.options.plugins) { + instance = this.getPluginInstance(plugin); + if (!instance) { + continue; + } + populate = instance.populateToolbar; + if (!jQuery.isFunction(populate)) { + continue; + } + this.element[plugin]('populateToolbar', this.toolbar); + } + this.element[this.options.toolbar]('setPosition'); + return this.protectFocusFrom(this.toolbar); + }, + changeToolbar: function(element, toolbar, hide) { + var originalToolbar; + if (hide == null) { + hide = false; + } + originalToolbar = this.options.toolbar; + this.options.parentElement = element; + if (toolbar) { + this.options.toolbar = toolbar; + } + if (!this.toolbar) { + return; + } + this.element[originalToolbar]('destroy'); + this.toolbar.remove(); + this._prepareToolbar(); + if (hide) { + return this.toolbar.hide(); + } + }, + _checkModified: function(event) { + var widget; + widget = event.data; + if (widget.isModified()) { + return widget.setModified(); + } + }, + _keys: function(event) { + var old, widget; + widget = event.data; + if (event.keyCode === 27) { + old = widget.getContents(); + widget.restoreOriginalContent(event); + widget._trigger("restored", null, { + editable: widget, + content: widget.getContents(), + thrown: old + }); + return widget.turnOff(); + } + }, + _rangesEqual: function(r1, r2) { + if (r1.startContainer !== r2.startContainer) { + return false; + } + if (r1.startOffset !== r2.startOffset) { + return false; + } + if (r1.endContainer !== r2.endContainer) { + return false; + } + if (r1.endOffset !== r2.endOffset) { + return false; + } + return true; + }, + _checkSelection: function(event) { + var widget; + if (event.keyCode === 27) { + return; + } + widget = event.data; + return setTimeout(function() { + var sel; + sel = widget.getSelection(); + if (widget._isEmptySelection(sel) || widget._isEmptyRange(sel)) { + if (widget.selection) { + widget.selection = null; + widget._trigger("unselected", null, { + editable: widget, + originalEvent: event + }); + } + return; + } + if (!widget.selection || !widget._rangesEqual(sel, widget.selection)) { + widget.selection = sel.cloneRange(); + return widget._trigger("selected", null, { + editable: widget, + selection: widget.selection, + ranges: [widget.selection], + originalEvent: event + }); + } + }, 0); + }, + _isEmptySelection: function(selection) { + if (selection.type === "Caret") { + return true; } return false; - }); - this.options.editable.element.on("hallodeactivated", function() { - return widget._closeDialog(); - }); - $toolbar.append($buttonset); - this.options.dialog.dialog(this.options.dialogOpts); - return this.options.dialog.dialog("option", "title", this.texts.title); - }, - _openDialog: function() { - var $editableEl, html, widget, xposition, yposition, - _this = this; - widget = this; - $editableEl = $(this.options.editable.element); - xposition = $editableEl.offset().left + $editableEl.outerWidth() + 10; - yposition = this.options.toolbar.offset().top - $(document).scrollTop(); - this.options.dialog.dialog("option", "position", [xposition, yposition]); - this.options.editable.keepActivated(true); - this.options.dialog.dialog("open"); - this.options.dialog.on('dialogclose', function() { - $('label', _this.button).removeClass('ui-state-active'); - _this.options.editable.element.focus(); - return _this.options.editable.keepActivated(false); - }); - this.options.dialog.html($("