diff --git a/src/postorius/doc/_build/doctrees/development.doctree b/src/postorius/doc/_build/doctrees/development.doctree new file mode 100644 index 0000000..9a2b220 --- /dev/null +++ b/src/postorius/doc/_build/doctrees/development.doctree Binary files differ diff --git a/src/postorius/doc/_build/doctrees/environment.pickle b/src/postorius/doc/_build/doctrees/environment.pickle index f91fb9a..46cb22a 100644 --- a/src/postorius/doc/_build/doctrees/environment.pickle +++ b/src/postorius/doc/_build/doctrees/environment.pickle Binary files differ diff --git a/src/postorius/doc/_build/doctrees/index.doctree b/src/postorius/doc/_build/doctrees/index.doctree index 26e23ff..6d5cf98 100644 --- a/src/postorius/doc/_build/doctrees/index.doctree +++ b/src/postorius/doc/_build/doctrees/index.doctree Binary files differ diff --git a/src/postorius/doc/_build/doctrees/news.doctree b/src/postorius/doc/_build/doctrees/news.doctree index 8f07463..ab3c398 100644 --- a/src/postorius/doc/_build/doctrees/news.doctree +++ b/src/postorius/doc/_build/doctrees/news.doctree Binary files differ diff --git a/src/postorius/doc/_build/doctrees/setup.doctree b/src/postorius/doc/_build/doctrees/setup.doctree index 5bba5e4..f7cfe80 100644 --- a/src/postorius/doc/_build/doctrees/setup.doctree +++ b/src/postorius/doc/_build/doctrees/setup.doctree Binary files differ diff --git a/src/postorius/doc/_build/doctrees/testing.doctree b/src/postorius/doc/_build/doctrees/testing.doctree new file mode 100644 index 0000000..c3dc290 --- /dev/null +++ b/src/postorius/doc/_build/doctrees/testing.doctree Binary files differ diff --git a/src/postorius/doc/_build/doctrees/using.doctree b/src/postorius/doc/_build/doctrees/using.doctree index 76c1ffc..4c70903 100644 --- a/src/postorius/doc/_build/doctrees/using.doctree +++ b/src/postorius/doc/_build/doctrees/using.doctree Binary files differ diff --git a/src/postorius/doc/_build/html/_sources/development.txt b/src/postorius/doc/_build/html/_sources/development.txt new file mode 100644 index 0000000..45efe00 --- /dev/null +++ b/src/postorius/doc/_build/html/_sources/development.txt @@ -0,0 +1,89 @@ +=========== +Development +=========== + + +Testing +======= + +All test modules reside in the ``postorius/src/postorius/tests`` directory +and this is where you should put your own tests, too. To make the django test +runner find your tests, make sure to add them to the folder's ``__init__.py``: + +:: + + from postorius.tests import test_utils + from postorius.tests.test_list_members import ListMembersViewTest + from postorius.tests.test_list_settings import ListSettingsViewTest + from postorius.tests.my_own_tests import MyOwnUnitTest + + __test__ = { + "Test Utils": test_utils, + "List Members": ListMembersViewTest, + "List Settings": ListSettingsViewTest, + "My Own Test": MyOwnUnitTest, + } + + +``postorius.*`` imports in test modules +--------------------------------------- + +When writing unittests make sure that any ``postorius.*`` imports are made +at the test method level and not at the module level. Here's why: + +The Postorius documentation (the one you are reading right now) imports some +doctest modules from the test package using Sphinx's autodoc extension. This is +a very nice feature, but in this scenario it has the nasty side effect of +breaking the build process if application code is imported as well (it will +fail to find an environment variable that Django needs to run). This can be +easily prevented by avoiding module level imports of postorius code in the test +modules. + +Good: + +:: + + from django.utils import unittest + from mock import patch + + + class SomeTest(unittest.TestCase): + + def test_some_method(self): + from postorius.views import SomeViewClass + foo = 'bar' + +Bad: + +:: + + from django.utils import unittest + from mock import patch + from postorius.views import SomeViewClass + + + class SomeTest(unittest.TestCase): + + def test_some_method(self): + foo = 'bar' + + + +Mocking +------- + +Postorius uses Michael Foord's ``mock`` library for mocking. There are some +shortcuts you can use to quickly create mock objects that behave a little bit like +objects retreived from mailman.client, like: + +- Domains +- Mailing Lists +- Users +- Memberships +- Addresses + + +Mocking mailman.client objects +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. automodule:: postorius.tests.test_utils diff --git a/src/postorius/doc/_build/html/_sources/index.txt b/src/postorius/doc/_build/html/_sources/index.txt index b6027ff..da81de8 100644 --- a/src/postorius/doc/_build/html/_sources/index.txt +++ b/src/postorius/doc/_build/html/_sources/index.txt @@ -8,5 +8,5 @@ news.rst setup.rst - using.rst + development.rst diff --git a/src/postorius/doc/_build/html/_sources/news.txt b/src/postorius/doc/_build/html/_sources/news.txt index f717c70..358c245 100644 --- a/src/postorius/doc/_build/html/_sources/news.txt +++ b/src/postorius/doc/_build/html/_sources/news.txt @@ -2,22 +2,22 @@ News / Changelog ================ -Copyright (C) 1998-2012 by the Free Software Foundation, Inc. +Copyright (C) 2012 by the Free Software Foundation, Inc. -The postorius Django app provides a web user interface to +The Postorius Django app provides a web user interface to access GNU Mailman. -postorius is free software: you can redistribute it and/or +Postorius is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, version 3 of the License. -postorius is distributed in the hope that it will be useful, +Postorius is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License -along with postorius. If not, see . +along with Postorius. If not, see . 1.0 alpha 2 @@ -29,6 +29,7 @@ * moderation: fixed typo in success message call * installation documentation for Apache/mod_wsgi * moved project files to separate branch +* show error message if connection to Mailman API fails 1.0 alpha 1 -- "Space Farm" diff --git a/src/postorius/doc/_build/html/_sources/setup.txt b/src/postorius/doc/_build/html/_sources/setup.txt index d1e74fc..0d05d1f 100644 --- a/src/postorius/doc/_build/html/_sources/setup.txt +++ b/src/postorius/doc/_build/html/_sources/setup.txt @@ -50,7 +50,7 @@ Latest dev version ------------------ -If you want to keep up to date with the latest development version, you +If you want to always be up to date with the latest development version, you should install Postorius using bazaar: :: @@ -68,6 +68,14 @@ $ bzr pull $ cd .. +Make sure to keep mailman.client up to date as well: + +:: + + $ cd mailman.client + $ bzr pull lp:mailman.client + $ cd .. + Setup your django project ========================= @@ -86,7 +94,7 @@ in line 48 to the correct location. .. note:: - Detailed information on how to use different databse engines can be found + Detailed information on how to use different database engines can be found in the `Django documentation`_. .. _Django documentation: https://docs.djangoproject.com/en/1.4/ref/settings/#databases @@ -115,7 +123,7 @@ Running the development server ============================== -The quickest way to run postorius is to just start the development server: +The quickest way to run Postorius is to just start the development server: :: diff --git a/src/postorius/doc/_build/html/_sources/testing.txt b/src/postorius/doc/_build/html/_sources/testing.txt new file mode 100644 index 0000000..7ee9b95 --- /dev/null +++ b/src/postorius/doc/_build/html/_sources/testing.txt @@ -0,0 +1,6 @@ +============= +Writing tests +============= + + +.. automodule:: postorius.tests.test_utils diff --git a/src/postorius/doc/_build/html/_static/basic.css b/src/postorius/doc/_build/html/_static/basic.css index 43e8baf..f0379f3 100644 --- a/src/postorius/doc/_build/html/_static/basic.css +++ b/src/postorius/doc/_build/html/_static/basic.css @@ -79,11 +79,11 @@ font-size: 1em; } -div.sphinxsidebar #searchbox input[type="text"] { +div.sphinxsidebar input[type="text"] { width: 170px; } -div.sphinxsidebar #searchbox input[type="submit"] { +div.sphinxsidebar input[type="submit"] { width: 30px; } diff --git a/src/postorius/doc/_build/html/development.html b/src/postorius/doc/_build/html/development.html new file mode 100644 index 0000000..9177fbb --- /dev/null +++ b/src/postorius/doc/_build/html/development.html @@ -0,0 +1,256 @@ + + + + + + + + + + Development — Postorius 1.0a2 documentation + + + + + + + + + + + + + + +
+
+
+
+ +
+

Development

+
+

Testing

+

All test modules reside in the postorius/src/postorius/tests directory +and this is where you should put your own tests, too. To make the django test +runner find your tests, make sure to add them to the folder’s __init__.py:

+
from postorius.tests import test_utils
+from postorius.tests.test_list_members import ListMembersViewTest
+from postorius.tests.test_list_settings import ListSettingsViewTest
+from postorius.tests.my_own_tests import MyOwnUnitTest
+
+__test__ = {
+    "Test Utils": test_utils,
+    "List Members": ListMembersViewTest,
+    "List Settings": ListSettingsViewTest,
+    "My Own Test": MyOwnUnitTest,
+}
+
+
+
+

postorius.* imports in test modules

+

When writing unittests make sure that any postorius.* imports are made +at the test method level and not at the module level. Here’s why:

+

The Postorius documentation (the one you are reading right now) imports some +doctest modules from the test package using Sphinx’s autodoc extension. This is +a very nice feature, but in this scenario it has the nasty side effect of +breaking the build process if application code is imported as well (it will +fail to find an environment variable that Django needs to run). This can be +easily prevented by avoiding module level imports of postorius code in the test +modules.

+

Good:

+
from django.utils import unittest
+from mock import patch
+
+
+class SomeTest(unittest.TestCase):
+
+    def test_some_method(self):
+        from postorius.views import SomeViewClass
+        foo = 'bar'
+
+
+

Bad:

+
from django.utils import unittest
+from mock import patch
+from postorius.views import SomeViewClass
+
+
+class SomeTest(unittest.TestCase):
+
+    def test_some_method(self):
+        foo = 'bar'
+
+
+
+
+

Mocking

+

Postorius uses Michael Foord’s mock library for mocking. There are some +shortcuts you can use to quickly create mock objects that behave a little bit like +objects retreived from mailman.client, like:

+
    +
  • Domains
  • +
  • Mailing Lists
  • +
  • Users
  • +
  • Memberships
  • +
  • Addresses
  • +
+
+

Mocking mailman.client objects

+
+
Domains
+

postorius.tests.utils.create_mock_list creates a mock domain object:

+
>>> properties = dict(contact_address='postmaster@example.org',
+...                   description='Example dot Org',
+...                   mail_host='example.org',
+...                   url_host='www.example.org')
+>>> mock_domain = create_mock_domain(properties)
+>>> print mock_domain
+<MagicMock name='Domain' id='...'>
+>>> print mock_domain.contact_address
+postmaster@example.org
+>>> print mock_domain.description
+Example dot Org
+>>> print mock_domain.mail_host
+example.org
+>>> print mock_domain.url_host
+www.example.org
+
+
+
+
+
Mailing Lists
+

postorius.tests.utils.create_mock_list creates a mock list object:

+
>>> properties = dict(fqdn_listname='testlist@example.org',
+...                   mail_host='example.org',
+...                   list_name='testlist',
+...                   display_name='Test List')
+>>> mock_list = create_mock_list(properties)
+>>> print mock_list
+<MagicMock name='List' id='...'>
+>>> print mock_list.fqdn_listname
+testlist@example.org
+>>> print mock_list.mail_host
+example.org
+>>> print mock_list.list_name
+testlist
+>>> print mock_list.display_name
+Test List
+
+
+
+
+
Memberships
+

postorius.tests.utils.create_mock_list creates a mock list object:

+
>>> properties = dict(fqdn_listname='testlist@example.org',
+...                   address='les@example.org',)
+>>> mock_member = create_mock_member(properties)
+>>> print mock_member
+<MagicMock name='Member' id='...'>
+>>> print mock_member.fqdn_listname
+testlist@example.org
+>>> print mock_member.address
+les@example.org
+
+
+
+
+
+
+
+ + +
+
+
+
+
+

Table Of Contents

+ + +

Previous topic

+

Installation

+

This Page

+ + + +
+
+
+
+ + + + \ No newline at end of file diff --git a/src/postorius/doc/_build/html/genindex.html b/src/postorius/doc/_build/html/genindex.html index 1b31d0c..cf95631 100644 --- a/src/postorius/doc/_build/html/genindex.html +++ b/src/postorius/doc/_build/html/genindex.html @@ -52,9 +52,20 @@

Index

- T + P + | T
+

P

+ + +
+ +
postorius.tests.test_utils (module) +
+ +
+

T

@@ -106,7 +117,7 @@ \ No newline at end of file diff --git a/src/postorius/doc/_build/html/index.html b/src/postorius/doc/_build/html/index.html index 1be05ed..aa21bde 100644 --- a/src/postorius/doc/_build/html/index.html +++ b/src/postorius/doc/_build/html/index.html @@ -57,7 +57,7 @@ @@ -110,7 +110,7 @@ \ No newline at end of file diff --git a/src/postorius/doc/_build/html/news.html b/src/postorius/doc/_build/html/news.html index 4439491..9268387 100644 --- a/src/postorius/doc/_build/html/news.html +++ b/src/postorius/doc/_build/html/news.html @@ -56,18 +56,18 @@

News / Changelog

-

Copyright (C) 1998-2012 by the Free Software Foundation, Inc.

-

The postorius Django app provides a web user interface to +

Copyright (C) 2012 by the Free Software Foundation, Inc.

+

The Postorius Django app provides a web user interface to access GNU Mailman.

-

postorius is free software: you can redistribute it and/or +

Postorius is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, version 3 of the License.

-

postorius is distributed in the hope that it will be useful, +

Postorius is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License -along with postorius. If not, see <http://www.gnu.org/licenses/>.

+along with Postorius. If not, see <http://www.gnu.org/licenses/>.

1.0 alpha 2

(2012-XX-XX)

@@ -77,6 +77,7 @@
  • moderation: fixed typo in success message call
  • installation documentation for Apache/mod_wsgi
  • moved project files to separate branch
  • +
  • show error message if connection to Mailman API fails
  • @@ -166,7 +167,7 @@
    \ No newline at end of file diff --git a/src/postorius/doc/_build/html/objects.inv b/src/postorius/doc/_build/html/objects.inv index 0fcc642..0c1d872 100644 --- a/src/postorius/doc/_build/html/objects.inv +++ b/src/postorius/doc/_build/html/objects.inv Binary files differ diff --git a/src/postorius/doc/_build/html/py-modindex.html b/src/postorius/doc/_build/html/py-modindex.html index 263f6f3..aa9ec3a 100644 --- a/src/postorius/doc/_build/html/py-modindex.html +++ b/src/postorius/doc/_build/html/py-modindex.html @@ -53,22 +53,37 @@

    Python Module Index

    + p | t
    - + + + + + + + + +
     
    - t
    + p
    - tests + postorius
        + postorius.tests.test_utils +
     
    + t
    + tests +
        tests.tests
    @@ -110,7 +125,7 @@
    \ No newline at end of file diff --git a/src/postorius/doc/_build/html/search.html b/src/postorius/doc/_build/html/search.html index dfe5cd1..fd1824c 100644 --- a/src/postorius/doc/_build/html/search.html +++ b/src/postorius/doc/_build/html/search.html @@ -99,7 +99,7 @@ \ No newline at end of file diff --git a/src/postorius/doc/_build/html/searchindex.js b/src/postorius/doc/_build/html/searchindex.js index 54502b7..fa71fd9 100644 --- a/src/postorius/doc/_build/html/searchindex.js +++ b/src/postorius/doc/_build/html/searchindex.js @@ -1 +1 @@ -Search.setIndex({objects:{tests:{tests:[3,0,1,""]}},terms:{all:[3,1,2],code:[3,2],forget:3,prefil:3,four:[],ackownledg:[],runserv:1,dirnam:[],follow:[3,1],profil:2,decid:[],depend:[2,1],authoris:[],mailman_them:[],descript:3,send:[],granci:2,under:2,introduc:[],merchant:2,sourc:[],everi:[],string:3,far:[],authbackend:[],none:3,offlin:[],util:3,context_processor:[],mechan:3,exact:3,contenttyp:[],administr:3,level:[],did:3,button:3,list:[3,2],"try":3,item:3,adjust:[],anna:2,quick:[],setup:[3,1,2],dir:[],pleas:3,modelbackend:[],impli:2,core:[],cfg:[],seper:[],request:3,past:[],second:1,download:1,further:[],click:3,compat:[],index:3,what:[],name_of_permiss:[],appear:[],richard:2,sum:[],abl:[3,1],current:3,delet:3,new_list1:3,postoriu:[0,1,2],franziska:[],"new":[0,2,3],net:[],"public":2,superus:1,publicli:1,gener:2,never:1,remeb:[],here:[],themself:[],ubuntu:[],path:1,along:2,modifi:[3,2],sinc:1,valu:3,search:[],mailinglist:[],vertifi:[],anymor:[],errorlog:[],host:[],jame:3,doctest:3,action:3,chang:1,mailman_media:[],contactpag:[],via:[],appli:[],app:[0,2,3],sponser:[],foundat:2,put:[],api:[],sponsel:[],instal:[0,1,2,3],middlewar:[],from:[3,1],describ:3,would:[],commun:[],doubl:3,two:[],perm:[],next:[],websit:[],few:[],call:2,typo:2,descrip:[],type:3,web_host:3,mailman_django:[],abspath:[],relat:3,ital:[],list_own:3,warn:[3,1],trail:[],berlio:[],stick:[],particular:2,hold:[],unpack:[],easiest:3,customlog:[],account:[2,1],join:[],alia:1,prepar:1,work:[],uniqu:[],dev:[2,1],archiv:3,can:[3,1,2],purpos:2,control:[],defer:2,sqlite:1,prompt:1,login_requir:3,tar:[],process:2,sudo:1,accept:2,topic:[],want:[3,1],contribut:2,alwai:1,cours:[],multipl:[],anoth:3,faulti:[],georg:3,write:[],how:1,reject:2,instead:3,simpl:[],css:1,updat:3,product:1,resourc:[0,3],farm:2,stop:3,earlier:[],usabl:[],befor:3,membership:3,date:1,end:[],hardcopi:[],third:1,postfix:[],bind:[],bootstrap:[],credenti:[],django:[0,1,2,3],alias:2,environ:1,adverrtis:3,jain:2,enter:3,fallback:[],automaticli:[],egg:[],order:1,listnam:3,help:[],move:2,becaus:3,has_perm:[],left:[],style:[],directli:3,fit:2,fix:2,browserid:2,better:[],requir:3,onc:[],mail:[3,2],hidden:[],main:[],might:[],guarente:[],them:1,"return":[],thei:3,python:[3,1],databs:1,auth:[],unfortuneatli:[],mention:3,front:3,now:[3,1],term:2,benst:[],somewher:1,name:3,anyth:[],edit:[3,2],config:[],postorius_error:[],authent:[],separ:[3,2],easili:[],senarclen:2,each:3,debug:3,found:[3,1],went:3,mailman_test_bindir:[],recommend:[],domain:[3,2],replac:[],idea:[],procedur:[],realli:3,line:[3,1],redistribut:2,meta:3,"static":1,connect:[],our:3,todo:[],dependeci:[],out:2,shown:3,space:2,miss:2,robert:1,develop:[0,1,2,3],publish:2,your:1,content:[0,3],daniel:2,rest_serv:[],got:[],correct:1,after:[3,1],insid:[],free:[3,2],standalon:[],reason:[],base:[],mailmanweb:[],lists_of_domain:[],releas:1,org:[2,1],"40mail":3,launch:[],could:[],wrong:3,keep:1,filter:[],thing:3,place:[],isn:[],root_urlconf:[],requireti:[],view:3,first:[3,1],softwar:2,rang:[],woun:[],render:[],feel:3,media_root:[],system:[],restrict:3,mai:[],instruct:[3,1],alreadi:3,done:3,least:3,authentif:3,owner:3,stabl:3,installed_app:[],open:3,gpl:[],differ:1,rrze:[],benedict:2,data:3,licens:2,natti:[],messag:[3,2],licenc:[],fullfil:[],"final":3,store:[],shell:3,option:3,real_nam:3,copi:2,specifi:3,gsoc:[],part:3,pars:3,priveledg:[],serv:1,enjoi:3,provid:[3,1,2],remov:[3,2],new_domain:[],project:[2,1],postorius_standalon:1,were:3,posit:3,minut:[],fqdn_listnam:3,pre:[],ani:2,postorius_access:[],packag:1,gui:3,have:[3,1,2],tabl:1,need:[3,1],element:[],wsgiscriptalia:1,engin:1,inform:1,florian:[],destroi:[],client:[3,1],note:[3,1],also:1,exampl:3,take:[],indic:3,combin:[],singl:3,even:2,sure:3,kati:3,allow:[3,1],shall:3,usernam:[],object:3,most:3,plan:[],letter:3,watt:3,alpha:2,choos:3,"class":[],icon:[],collectstat:1,don:3,bzr:1,url:3,doc:[],later:[],cover:1,temporili:3,doe:3,deni:1,mm_membership:3,usual:[],dev_setup:[],wsgi:1,show:[3,2],text:3,liza:3,session:3,permiss:3,corner:[],fine:[],find:[],redirect:3,absolut:[],onli:[3,1],submit:3,locat:1,launchpad:1,copyright:2,explain:3,configur:[],apach:[2,1],should:[3,1,2],version:[2,1],suppos:[],templat:2,folder:1,local:[3,1],hope:2,media_url:[],nearli:[],get:[3,1],"__file__":[],pypi:1,obviou:[],csrf:2,awai:[],restart:[],template_dir:[],reload:1,common:[],restadmin:[],where:[],summari:3,wiki:[],set:[3,1,2],see:[3,1,2],domain_admin:[],result:[],respons:3,fail:3,wonder:[],awar:3,statu:3,error:[],correctli:[],databas:[3,1],someth:3,yet:[],behind:[],quickest:1,between:3,"import":3,subscript:3,email:3,realnam:[],correclti:[],advertis:3,subfold:[],thank:2,both:[],last:3,plugin:[],admin:1,howev:[],etc:1,instanc:3,context:[],delete_list:3,logout:[],login:[3,2],com:3,load:3,simpli:3,point:[],instanti:[],overview:3,address:3,header:[],non:[],linux:3,guid:[3,1],assum:1,backend:[],quit:[],trunk:[],mailman:[0,1,2,3],coupl:3,"0a7":[],been:3,compon:[],much:[],unsubscrib:[3,2],modif:[],addit:[],upcom:[],imag:1,xxx:[],togeth:3,rememb:[],i18n:[],ngeorg:3,niederreit:1,those:3,"case":3,creativecommon:[],therefor:[],look:[],gnu:[2,1],plain:[],align:[],lesser:2,"while":1,dashboard:3,abov:3,mail_host:3,everyon:[],authentication_backend:[],new_list:[],almost:1,demo:[],metric:2,site:[3,1],itself:[],revis:[],decor:3,let:3,welcom:[],author:[],receiv:2,media:[],make:[3,1],belong:3,same:3,handl:[],html:[],split:[],document:[2,1],mod_wsgi:[2,1],finish:3,http:[3,1,2],webserv:1,upon:[],coder:1,moment:[],http_host:3,initi:2,mani:2,implement:2,expand:[],appropri:[],moder:2,framework:[],api_pass:3,well:[3,1],membership_set:[],without:[3,2],command:[],thi:[3,1,2],english:3,everyth:3,latest:1,summer:2,just:1,rest:3,mailman3:3,webui:[],restbackend:[],languag:3,web:[0,1,2],easi:[],project_path:[],had:[],list_summari:3,apache2:[],add:[3,2],valid:3,lawrenc:[],save:[],modul:3,futur:[],bin:[],applic:1,which:[3,1],stein:2,unter:[],prefer:1,writabl:1,know:1,gsoc_mailman:[],press:3,cooki:[],password:[],tweak:[],mailmanwebgsoc2011:[],template_context_processor:[],resid:1,like:[],success:[3,2],changelog:[0,2],restpass:[],server:[2,1],collect:1,href:[],setup_mm:3,either:3,page:3,www:2,right:[],acknowledg:[],creation:3,some:3,back:[],proper:2,home:[],funcit:[],distribut:2,basic:2,buildout:1,djangoproject:[],confirm:3,httpredirectobject:3,token:2,select:[],slash:[],necessari:1,testobject:3,localhost:3,refer:3,machin:3,httpresponseredirect:3,who:[],run:[3,1],bold:[],symlink:[],step:[],repositori:[],post:3,bazaar:1,mm_new_domain:[],stage:[],about:[],central:[],usa:3,mass_subscrib:3,rohan:2,acl:[],permission_requir:[],srv:1,act:1,fals:3,discard:2,processor:[],block:3,own:3,addus:[],status_cod:3,pythonpath:1,within:3,easy_instal:1,warranti:2,creativ:[],empti:3,contrib:[],api_us:3,manag:[3,1],choosen:3,span:3,log:3,wai:[3,1],"40exampl":3,execut:3,print:3,"long":[],custom:[],avail:[3,1],start:[3,1],reli:[],interfac:[2,1],includ:3,suit:3,"var":[],systers_django:[],"function":3,head:[],form:[3,2],offer:3,subscrib:[3,2],link:3,translat:3,teardown_mm:3,eas:[],"true":3,info:2,pull:1,succe:3,made:3,render_mailman_them:[],possibl:1,whether:3,access:[3,2],displai:3,below:3,memebership:[],otherwis:[],more:2,extend_ajax:[],proud:[],creat:[3,1],hardcod:[],dure:[3,2],doesn:[],exist:[],file:[2,1],syncdb:1,pip:1,wackerbarth:2,check:[3,2],inc:2,again:[],readi:1,successfulli:[],googl:2,titl:[],user:[3,1,2],when:[],detail:[2,1],gettext:3,"default":[],mizyrycki:2,other:3,special:[],branch:[2,1],test:3,you:[3,1,2],servernam:[],nice:3,why:3,prequir:[],consid:[],stai:[],outdat:[0,3],bullet:[],directori:[3,1],bottom:[],virtualhost:1,mailman3a7:[],mass:[3,2],came:[],time:[3,1],escap:3},objtypes:{"0":"py:module"},titles:["Postorius - The New Mailman Web UI","Installation","News / Changelog","Using the Django App - Developers Resource (outdated)"],objnames:{"0":["py","module","Python module"]},filenames:["index","setup","news","using"]}) \ No newline at end of file +Search.setIndex({objects:{tests:{tests:[3,0,1,""]},"postorius.tests":{test_utils:[0,0,1,""]}},terms:{all:[0,4,2,3],code:[0,4,3],forget:3,prefil:3,test_list_set:0,four:[],ackownledg:[],runserv:2,dirnam:[],follow:[3,2],profil:4,decid:[],depend:[4,2],authoris:[],mailman_them:[],descript:[0,3],send:[],granci:4,under:4,introduc:[],merchant:4,sourc:[],everi:[],string:3,far:[],authbackend:[],none:3,offlin:[],util:[0,3],context_processor:[],mechan:3,veri:0,exact:3,foo:0,contenttyp:[],administr:3,level:0,did:3,button:3,list:[0,4,3],contact_address:0,"try":3,item:3,adjust:[],anna:4,quick:[],setup:[4,2,3],dir:[],pleas:3,modelbackend:[],impli:4,core:[],cfg:[],seper:[],request:3,past:[],second:2,download:2,further:[],click:3,compat:[],index:3,what:[],name_of_permiss:[],appear:[],richard:4,sum:[],abl:[3,2],current:3,delet:3,new_list1:3,postoriu:[0,1,2,4],franziska:[],"new":[1,3,4],net:[],method:0,superus:2,publicli:2,gener:4,never:2,remeb:[],here:0,themself:[],ubuntu:[],path:2,along:4,modifi:[4,3],sinc:2,valu:3,search:[],mailinglist:[],vertifi:[],anymor:[],errorlog:[],host:[],later:[],jame:3,doctest:[0,3],action:3,chang:2,mailman_media:[],element:[],contactpag:[],via:[],appli:[],app:[4,3],sponser:[],foundat:4,put:0,api:4,sponsel:[],instal:[1,2,3,4],myownunittest:0,middlewar:[],from:[0,3,2],describ:3,would:[],commun:[],doubl:3,two:[],perm:[],next:[],websit:[],few:[],call:4,typo:4,recommend:[],suppos:[],type:3,web_host:3,create_mock_list:0,mailman_django:[],abspath:[],relat:3,ital:[],list_own:3,warn:[3,2],trail:[],berlio:[],stick:[],autodoc:0,particular:4,dooo:[],hold:[],unpack:[],easiest:3,correctli:[],customlog:[],account:[4,2],join:[],alia:2,prepar:2,work:[],uniqu:[],dev:[4,2],mock_list2:[],archiv:3,can:[0,4,2,3],purpos:4,def:0,control:[],defer:4,sqlite:2,prompt:2,login_requir:3,tar:[],process:[0,4],sudo:2,accept:4,topic:[],want:[3,2],create_mock_memb:0,yet:[],create_mock_domain:0,contribut:4,alwai:2,cours:[],multipl:[],permission_requir:[],anoth:3,faulti:[],georg:3,write:0,how:2,list_nam:0,reject:4,instead:3,simpl:[],"__file__":[],css:2,updat:3,product:2,resourc:3,farm:4,stop:3,earlier:[],usabl:[],befor:3,membership:[0,3],date:2,end:[],hardcopi:[],third:2,postfix:[],bind:[],bootstrap:[],credenti:[],django:[0,4,2,3],alias:4,environ:[0,2],adverrtis:3,jain:4,enter:3,fallback:[],automaticli:[],egg:[],order:2,listnam:3,help:[],move:4,becaus:3,has_perm:[],own:[0,3],left:[],style:[],directli:3,fit:4,fix:4,browserid:4,unicode_liter:[],better:[],requir:3,onc:[],mail:[0,4,3],hidden:[],main:[],might:[],guarente:[],them:[0,2],good:0,"return":[],thei:3,python:[3,2],databs:[],auth:[],unfortuneatli:[],"break":0,mention:3,front:3,bar:0,now:[0,3,2],term:4,benst:[],somewher:2,name:[0,3],anyth:[],edit:[4,3],config:[],postorius_error:[],authent:[],separ:[4,3],easili:0,senarclen:4,each:3,debug:3,found:[3,2],went:3,mailman_test_bindir:[],everyth:3,domain:[0,4,3],replac:[],idea:[],procedur:[],realli:3,line:[3,2],redistribut:4,meta:3,"static":2,connect:4,our:3,todo:[],dependeci:[],out:4,variabl:0,shown:3,space:4,miss:4,robert:2,develop:[0,1,2,3,4],publish:4,your:[0,2],content:[1,3],daniel:4,rest_serv:[],got:[],correct:2,after:[3,2],insid:[],free:[4,3],standalon:[],reason:[],base:[],mailmanweb:[],lists_of_domain:[],releas:2,org:[0,4,2],"40mail":3,launch:[],could:[],wrong:3,keep:2,filter:[],thing:3,place:[],isn:[],root_urlconf:[],requireti:[],view:[0,3],first:[3,2],softwar:4,rang:[],woun:[],render:[],prevent:0,feel:3,media_root:[],system:[],restrict:3,mai:[],instruct:[3,2],alreadi:3,done:3,least:3,authentif:3,owner:3,stabl:3,installed_app:[],open:3,gpl:[],differ:2,rrze:[],my_own_test:0,benedict:4,data:3,licens:4,natti:[],messag:[4,3],url_host:0,too:0,licenc:[],fullfil:[],"final":3,store:[],shell:3,option:3,real_nam:3,"public":4,copi:4,specifi:3,gsoc:[],part:3,"__test__":0,exactli:[],priveledg:[],serv:2,test_some_method:0,provid:[4,2,3],remov:[4,3],new_domain:[],project:[4,2],postorius_standalon:2,were:3,posit:3,minut:[],fqdn_listnam:[0,3],pre:[],descrip:[],sai:[],runner:0,ani:[0,4],postorius_access:[],packag:[0,2],gui:3,have:[4,2,3],tabl:2,need:[0,3,2],foord:0,wsgiscriptalia:2,engin:2,inform:2,florian:[],destroi:[],self:0,client:[0,3,2],note:[3,2],also:2,exampl:[0,3],take:[],indic:3,combin:[],mock_memb:0,singl:3,even:4,sure:[0,3,2],kati:3,allow:[3,2],httpredirectobject:3,usernam:[],object:[0,3],asdasd:[],most:3,plan:[],letter:3,watt:3,alpha:4,choos:3,"class":0,icon:[],collectstat:2,don:3,bzr:2,url:3,doc:[],proud:[],cover:2,temporili:3,doe:3,deni:2,pars:3,usual:[],dev_setup:[],wsgi:2,show:[4,3],text:3,liza:3,session:3,permiss:3,corner:[],fine:[],find:0,redirect:3,absolut:[],onli:[3,2],submit:3,locat:2,launchpad:2,copyright:4,explain:3,configur:[],apach:[4,2],should:[0,4,2,3],version:[4,2],dict:0,templat:4,folder:[0,2],local:[3,2],hope:4,media_url:[],hit:[],nearli:[],get:[3,2],nasti:0,pypi:2,obviou:[],rest:3,csrf:4,awai:[],restart:[],retreiv:0,template_dir:[],patch:0,reload:2,bad:0,common:[],restadmin:[],mm_membership:3,where:0,summari:3,wiki:[],set:[0,4,2,3],sometest:0,see:[4,2,3],domain_admin:[],result:[],respons:3,testcas:0,wonder:[],awar:3,statu:3,error:4,magicmock:0,databas:[3,2],someth:3,test_list_memb:0,behind:[],quickest:2,between:3,"import":[0,3],subscript:3,email:3,realnam:[],coder:2,extens:0,correclti:[],advertis:3,subfold:[],thank:4,both:[],last:3,plugin:[],admin:2,howev:[],etc:2,instanc:3,context:[],delete_list:3,logout:[],login:[4,3],com:3,load:3,simpli:3,point:[],instanti:[],overview:3,unittest:0,address:[0,3],mock_list:0,header:[],non:[],littl:0,linux:3,guid:[3,2],assum:2,backend:[],quit:[],trunk:[],mailman:[0,1,2,3,4],coupl:3,"0a7":[],been:3,compon:[],much:[],unsubscrib:[4,3],modif:[],futur:[],addit:[],quickli:0,upcom:[],imag:2,xxx:[],togeth:3,rememb:[],i18n:[],ngeorg:3,niederreit:2,those:3,"case":3,creativecommon:[],therefor:[],look:[],gnu:[4,2],plain:[],align:[],properti:0,lesser:4,"while":2,dashboard:3,abov:3,mail_host:[0,3],everyon:[],authentication_backend:[],new_list:[],almost:2,demo:[],metric:4,site:[3,2],itself:[],revis:[],"__init__":0,decor:3,let:3,welcom:[],author:[],receiv:4,media:[],make:[0,3,2],belong:3,same:3,member:0,handl:[],html:[],split:[],document:[0,4,2],mod_wsgi:[4,2],behav:0,finish:3,http:[4,2,3],webserv:2,upon:[],effect:0,moment:[],http_host:3,initi:4,mani:4,implement:4,expand:[],appropri:[],moder:4,scenario:0,framework:[],api_pass:3,well:[0,3,2],membership_set:[],without:[4,3],command:[],thi:[0,4,2,3],english:3,fail:[0,4,3],latest:2,summer:4,just:2,absolute_import:[],mailman3:3,webui:[],test_util:0,restbackend:[],languag:3,web:[1,2,4],display_nam:0,easi:[],project_path:[],had:[],list_summari:3,shortcut:0,apache2:[],add:[0,4,3],valid:3,lawrenc:[],save:[],modul:[0,3],build:0,bin:[],applic:[0,2],which:[3,2],stein:4,unter:[],read:0,prefer:2,testlist:0,writabl:2,know:2,gsoc_mailman:[],press:3,cooki:[],bit:0,password:[],tweak:[],mailmanwebgsoc2011:[],template_context_processor:[],resid:[0,2],like:0,success:[4,3],changelog:[1,4],restpass:[],server:[4,2],collect:2,href:[],setup_mm:3,either:3,page:3,www:[0,4],right:0,acknowledg:[],creation:3,some:[0,3],back:[],proper:4,create_list:[],funcit:[],librari:0,distribut:4,basic:4,buildout:2,djangoproject:[],confirm:3,avoid:0,shall:3,token:4,servernam:[],select:[],slash:[],necessari:2,testobject:3,localhost:3,refer:3,machin:3,httpresponseredirect:3,who:[],run:[0,3,2],bold:[],symlink:[],step:[],repositori:[],post:3,bazaar:2,mm_new_domain:[],stage:[],src:0,about:[],central:[],usa:3,mass_subscrib:3,rohan:4,side:0,listmembersviewtest:0,srv:2,act:2,fals:3,discard:4,processor:[],block:3,"__future__":[],addus:[],status_cod:3,pythonpath:2,xyz:[],within:3,someviewclass:0,easy_instal:2,warranti:4,creativ:[],empti:3,contrib:[],api_us:3,manag:[3,2],choosen:3,span:3,log:3,wai:[3,2],"40exampl":3,execut:3,print:[0,3],"long":[],custom:[],avail:[3,2],start:[3,2],reli:[],interfac:[4,2],includ:3,suit:3,"var":[],systers_django:[],"function":3,head:[],form:[4,3],offer:3,subscrib:[4,3],requestfactori:[],link:3,translat:3,teardown_mm:3,eas:[],"true":3,info:4,pull:2,succe:3,made:[0,3],render_mailman_them:[],mock_domain:0,possibl:2,whether:3,access:[4,3],displai:3,directori:[0,3,2],below:3,memebership:[],otherwis:[],more:4,postmast:0,extend_ajax:[],featur:0,creat:[0,3,2],hardcod:[],dure:[4,3],doesn:[],listsettingsviewtest:0,exist:[],file:[4,2],syncdb:2,pip:2,wackerbarth:4,check:[4,3],acl:[],again:[],readi:2,successfulli:[],googl:4,titl:[],user:[0,4,2,3],when:0,detail:[4,2],gettext:3,"default":[],mizyrycki:4,other:3,special:[],branch:[4,2],test:[0,3],you:[0,4,2,3],mock:0,nice:[0,3],michael:0,why:[0,3],prequir:[],consid:[],stai:[],outdat:3,sphinx:0,bullet:[],home:[],came:[],enjoi:3,bottom:[],virtualhost:2,rule:[],mailman3a7:[],mass:[4,3],dot:0,time:[3,2],escap:3,inc:4},objtypes:{"0":"py:module"},titles:["Development","Postorius - The New Mailman Web UI","Installation","Using the Django App - Developers Resource (outdated)","News / Changelog"],objnames:{"0":["py","module","Python module"]},filenames:["development","index","setup","using","news"]}) \ No newline at end of file diff --git a/src/postorius/doc/_build/html/setup.html b/src/postorius/doc/_build/html/setup.html index 824b56a..cd9a55b 100644 --- a/src/postorius/doc/_build/html/setup.html +++ b/src/postorius/doc/_build/html/setup.html @@ -26,7 +26,7 @@ - + @@ -40,7 +40,7 @@ modules |
  • - next |
  • Latest dev version

    -

    If you want to keep up to date with the latest development version, you +

    If you want to always be up to date with the latest development version, you should install Postorius using bazaar:

    $ bzr branch lp:postorius
     $ cd postorius
    @@ -99,6 +99,11 @@
     $ bzr pull
     $ cd ..
    +

    Make sure to keep mailman.client up to date as well:

    +
    $ cd mailman.client
    +$ bzr pull lp:mailman.client
    +$ cd ..
    +
    @@ -113,7 +118,7 @@ in line 48 to the correct location.

    Note

    -

    Detailed information on how to use different databse engines can be found +

    Detailed information on how to use different database engines can be found in the Django documentation.

    Third, prepare the database:

    @@ -132,7 +137,7 @@

    Running the development server

    -

    The quickest way to run postorius is to just start the development server:

    +

    The quickest way to run Postorius is to just start the development server:

    $ cd postorius_standalone
     $ python manage.py runserver
    @@ -203,8 +208,8 @@

    News / Changelog

    Next topic

    -

    Using the Django App - Developers Resource (outdated)

    +

    Development

    This Page

    • modules |
    • - next |
    • \ No newline at end of file diff --git a/src/postorius/doc/_build/html/testing.html b/src/postorius/doc/_build/html/testing.html new file mode 100644 index 0000000..4c72b19 --- /dev/null +++ b/src/postorius/doc/_build/html/testing.html @@ -0,0 +1,155 @@ + + + + + + + + + + Writing tests — Postorius 1.0a2 documentation + + + + + + + + + + + + + + + +
      +
      +
      +
      + +
      +

      Writing tests

      +
      +

      Mocking mailman.client objects

      +
      +

      Mailing Lists

      +
      >>> from postorius.tests.utils import *
      +
      +
      +
      >>> properties = dict(fqdn_listname='testlist@example.org',
      +...                   mail_host='example.org',
      +...                   list_name='testlist',
      +...                   display_name='Test List')
      +>>> mock_list = create_mock_list(properties)
      +>>> print mock_list.fqdn_listname
      +testlist@example.org
      +>>> print mock_list.mail_host
      +example.org
      +>>> print mock_list.list_name
      +testlist
      +>>> print mock_list.display_name
      +Test List
      +>>> print mock_list
      +<MagicMock name='List' id='...'>
      +
      +
      +
      +
      +
      + + +
      +
      +
      +
      +
      +

      Table Of Contents

      + + +

      Previous topic

      +

      Installation

      +

      Next topic

      +

      Using the Django App - Developers Resource (outdated)

      +

      This Page

      + + + +
      +
      +
      +
      + + + + \ No newline at end of file diff --git a/src/postorius/doc/_build/html/using.html b/src/postorius/doc/_build/html/using.html index 33caf5e..ce027e5 100644 --- a/src/postorius/doc/_build/html/using.html +++ b/src/postorius/doc/_build/html/using.html @@ -406,7 +406,7 @@
    \ No newline at end of file diff --git a/src/postorius/doc/development.rst b/src/postorius/doc/development.rst new file mode 100644 index 0000000..45efe00 --- /dev/null +++ b/src/postorius/doc/development.rst @@ -0,0 +1,89 @@ +=========== +Development +=========== + + +Testing +======= + +All test modules reside in the ``postorius/src/postorius/tests`` directory +and this is where you should put your own tests, too. To make the django test +runner find your tests, make sure to add them to the folder's ``__init__.py``: + +:: + + from postorius.tests import test_utils + from postorius.tests.test_list_members import ListMembersViewTest + from postorius.tests.test_list_settings import ListSettingsViewTest + from postorius.tests.my_own_tests import MyOwnUnitTest + + __test__ = { + "Test Utils": test_utils, + "List Members": ListMembersViewTest, + "List Settings": ListSettingsViewTest, + "My Own Test": MyOwnUnitTest, + } + + +``postorius.*`` imports in test modules +--------------------------------------- + +When writing unittests make sure that any ``postorius.*`` imports are made +at the test method level and not at the module level. Here's why: + +The Postorius documentation (the one you are reading right now) imports some +doctest modules from the test package using Sphinx's autodoc extension. This is +a very nice feature, but in this scenario it has the nasty side effect of +breaking the build process if application code is imported as well (it will +fail to find an environment variable that Django needs to run). This can be +easily prevented by avoiding module level imports of postorius code in the test +modules. + +Good: + +:: + + from django.utils import unittest + from mock import patch + + + class SomeTest(unittest.TestCase): + + def test_some_method(self): + from postorius.views import SomeViewClass + foo = 'bar' + +Bad: + +:: + + from django.utils import unittest + from mock import patch + from postorius.views import SomeViewClass + + + class SomeTest(unittest.TestCase): + + def test_some_method(self): + foo = 'bar' + + + +Mocking +------- + +Postorius uses Michael Foord's ``mock`` library for mocking. There are some +shortcuts you can use to quickly create mock objects that behave a little bit like +objects retreived from mailman.client, like: + +- Domains +- Mailing Lists +- Users +- Memberships +- Addresses + + +Mocking mailman.client objects +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. automodule:: postorius.tests.test_utils diff --git a/src/postorius/doc/index.rst b/src/postorius/doc/index.rst index b6027ff..da81de8 100644 --- a/src/postorius/doc/index.rst +++ b/src/postorius/doc/index.rst @@ -8,5 +8,5 @@ news.rst setup.rst - using.rst + development.rst diff --git a/src/postorius/doc/news.rst b/src/postorius/doc/news.rst index f717c70..358c245 100644 --- a/src/postorius/doc/news.rst +++ b/src/postorius/doc/news.rst @@ -2,22 +2,22 @@ News / Changelog ================ -Copyright (C) 1998-2012 by the Free Software Foundation, Inc. +Copyright (C) 2012 by the Free Software Foundation, Inc. -The postorius Django app provides a web user interface to +The Postorius Django app provides a web user interface to access GNU Mailman. -postorius is free software: you can redistribute it and/or +Postorius is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, version 3 of the License. -postorius is distributed in the hope that it will be useful, +Postorius is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License -along with postorius. If not, see . +along with Postorius. If not, see . 1.0 alpha 2 @@ -29,6 +29,7 @@ * moderation: fixed typo in success message call * installation documentation for Apache/mod_wsgi * moved project files to separate branch +* show error message if connection to Mailman API fails 1.0 alpha 1 -- "Space Farm" diff --git a/src/postorius/doc/setup.rst b/src/postorius/doc/setup.rst index d1e74fc..0d05d1f 100644 --- a/src/postorius/doc/setup.rst +++ b/src/postorius/doc/setup.rst @@ -50,7 +50,7 @@ Latest dev version ------------------ -If you want to keep up to date with the latest development version, you +If you want to always be up to date with the latest development version, you should install Postorius using bazaar: :: @@ -68,6 +68,14 @@ $ bzr pull $ cd .. +Make sure to keep mailman.client up to date as well: + +:: + + $ cd mailman.client + $ bzr pull lp:mailman.client + $ cd .. + Setup your django project ========================= @@ -86,7 +94,7 @@ in line 48 to the correct location. .. note:: - Detailed information on how to use different databse engines can be found + Detailed information on how to use different database engines can be found in the `Django documentation`_. .. _Django documentation: https://docs.djangoproject.com/en/1.4/ref/settings/#databases @@ -115,7 +123,7 @@ Running the development server ============================== -The quickest way to run postorius is to just start the development server: +The quickest way to run Postorius is to just start the development server: :: diff --git a/src/postorius/models.py b/src/postorius/models.py index 79e2b39..e1d4ab7 100644 --- a/src/postorius/models.py +++ b/src/postorius/models.py @@ -79,8 +79,8 @@ return self.get(**kwargs) except Mailman404Error: raise Http404 - except MailmanConnectionError: - raise MailmanApiError + except MailmanConnectionError, e: + raise MailmanApiError(e) def create(self, **kwargs): try: diff --git a/src/postorius/templates/postorius/lists/members.html b/src/postorius/templates/postorius/lists/members.html new file mode 100644 index 0000000..d3b09e8 --- /dev/null +++ b/src/postorius/templates/postorius/lists/members.html @@ -0,0 +1,22 @@ +{% extends "postorius/base.html" %} +{% load i18n %} + +{% block main %} + {% if user.is_superuser %} + {% include 'postorius/menu/list_nav.html' %} + {% endif %} + +

    {% trans "List members" %}: {{list.fqdn_listname}}

    + + + + + + + + + + +
    {% trans 'address' %}{% trans 'user' %}
    + +{% endblock main %} diff --git a/src/postorius/tests/__init__.py b/src/postorius/tests/__init__.py index c2b5ab9..58acd95 100644 --- a/src/postorius/tests/__init__.py +++ b/src/postorius/tests/__init__.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright (C) 1998-2012 by the Free Software Foundation, Inc. +# Copyright (C) 2012 by the Free Software Foundation, Inc. # # This file is part of Postorius. # @@ -15,7 +15,11 @@ # You should have received a copy of the GNU General Public License along with # Postorius. If not, see . -import tests +from postorius.tests import test_utils +from postorius.tests.test_list_members import * + __test__ = { + "Test Utils": test_utils, + "List members": ListMembersViewTest, #"Doctest": tests, } diff --git a/src/postorius/tests/test_list_members.py b/src/postorius/tests/test_list_members.py new file mode 100644 index 0000000..3797b79 --- /dev/null +++ b/src/postorius/tests/test_list_members.py @@ -0,0 +1,60 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2012 by the Free Software Foundation, Inc. +# +# This file is part of Postorius. +# +# Postorius is free software: you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free +# Software Foundation, either version 3 of the License, or (at your option) +# any later version. +# Postorius is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along with +# Postorius. If not, see . + +from django.utils import unittest +from mock import patch + + +class ListMembersViewTest(unittest.TestCase): + """Tests for the ListMembersView.""" + + def setUp(self): + from django.test.client import RequestFactory + from postorius.tests.utils import create_mock_list, create_mock_member + self.factory = RequestFactory() + # create a mock list with members + list_name = 'foolist@example.org' + self.mock_list = create_mock_list(dict( + fqdn_listname=list_name, + members=[ + create_mock_member(dict( + fqdn_listname=list_name, + address='les@example.org')), + create_mock_member(dict( + fqdn_listname=list_name, + address='ler@example.com')), + ])) + + def test_get_list(self): + """Test if list members are retreived correctly.""" + from postorius.views import ListMembersView + + # test get_list + view = ListMembersView() + with patch('mailman.client.Client.get_list') as mock: + mock.return_value = self.mock_list + the_list = view.get_list('foolist@example.org') + self.assertEqual(the_list.members[0].address, 'les@example.org') + self.assertEqual(the_list.members[1].address, 'ler@example.com') + + def test_return_code_by_login_status(self): + """Test that the correct status code is sent depending on the + login/user type.""" + pass + + def tearDown(self): + pass diff --git a/src/postorius/tests/test_utils.py b/src/postorius/tests/test_utils.py new file mode 100644 index 0000000..db9ca0e --- /dev/null +++ b/src/postorius/tests/test_utils.py @@ -0,0 +1,84 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2012 by the Free Software Foundation, Inc. +# +# This file is part of Postorius. +# +# Postorius is free software: you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free +# Software Foundation, either version 3 of the License, or (at your option) +# any later version. +# Postorius is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along with +# Postorius. If not, see . + +""" +.. testsetup:: + + >>> from __future__ import absolute_import, unicode_literals + + >>> from postorius.tests.utils import * + + +Domains +======= + +``postorius.tests.utils.create_mock_list`` creates a mock domain object: + + >>> properties = dict(contact_address='postmaster@example.org', + ... description='Example dot Org', + ... mail_host='example.org', + ... url_host='www.example.org') + >>> mock_domain = create_mock_domain(properties) + >>> print mock_domain + + >>> print mock_domain.contact_address + postmaster@example.org + >>> print mock_domain.description + Example dot Org + >>> print mock_domain.mail_host + example.org + >>> print mock_domain.url_host + www.example.org + + +Mailing Lists +============= + +``postorius.tests.utils.create_mock_list`` creates a mock list object: + + >>> properties = dict(fqdn_listname='testlist@example.org', + ... mail_host='example.org', + ... list_name='testlist', + ... display_name='Test List') + >>> mock_list = create_mock_list(properties) + >>> print mock_list + + >>> print mock_list.fqdn_listname + testlist@example.org + >>> print mock_list.mail_host + example.org + >>> print mock_list.list_name + testlist + >>> print mock_list.display_name + Test List + + +Memberships +=========== + +``postorius.tests.utils.create_mock_list`` creates a mock list object: + + >>> properties = dict(fqdn_listname='testlist@example.org', + ... address='les@example.org',) + >>> mock_member = create_mock_member(properties) + >>> print mock_member + + >>> print mock_member.fqdn_listname + testlist@example.org + >>> print mock_member.address + les@example.org +""" diff --git a/src/postorius/tests/utils.py b/src/postorius/tests/utils.py new file mode 100644 index 0000000..a6d1831 --- /dev/null +++ b/src/postorius/tests/utils.py @@ -0,0 +1,66 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2012 by the Free Software Foundation, Inc. +# +# This file is part of Postorius. +# +# Postorius is free software: you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free +# Software Foundation, either version 3 of the License, or (at your option) +# any later version. +# Postorius is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along with +# Postorius. If not, see . + +from mock import patch, MagicMock + +def create_mock_domain(properties=None): + """Create and return a mocked Domain. + + :param properties: A dictionary of the domain's properties. + :type properties: dict + :return: A MagicMock object with the properties set. + :rtype: MagicMock + """ + mock_object = MagicMock(name='Domain') + mock_object.base_url = '' + mock_object.contact_address = '' + mock_object.description = '' + mock_object.mail_host = '' + mock_object.url_host = '' + mock_object.lists = [] + if properties is not None: + for key in properties: + setattr(mock_object, key, properties[key]) + return mock_object + +def create_mock_list(properties=None): + """Create and return a mocked List. + + :param properties: A dictionary of the list's properties. + :type properties: dict + :return: A MagicMock object with the properties set. + :rtype: MagicMock + """ + mock_object = MagicMock(name='List') + if properties is not None: + for key in properties: + setattr(mock_object, key, properties[key]) + return mock_object + +def create_mock_member(properties=None): + """Create and return a mocked Member. + + :param properties: A dictionary of the member's properties. + :type properties: dict + :return: A MagicMock object with the properties set. + :rtype: MagicMock + """ + mock_object = MagicMock(name='Member') + if properties is not None: + for key in properties: + setattr(mock_object, key, properties[key]) + return mock_object diff --git a/src/postorius/urls.py b/src/postorius/urls.py index 3d26bce..18c9e8d 100644 --- a/src/postorius/urls.py +++ b/src/postorius/urls.py @@ -20,6 +20,8 @@ from django.conf import settings from django.conf.urls.static import static +from postorius.views import ListMembersView + urlpatterns = patterns('postorius.views', (r'^$', 'list_index'), @@ -41,6 +43,8 @@ # /lists/ url(r'^lists/$', 'list_index', name='list_index'), url(r'^lists/new/$', 'list_new', name='list_new'), + url(r'^lists/(?P[^/]+)/members$', ListMembersView.as_view(), + name='list_members'), url(r'^lists/(?P[^/]+)/metrics$', 'list_metrics', name='list_metrics'), url(r'^lists/(?P[^/]+)/$', 'list_summary', diff --git a/src/postorius/views.py b/src/postorius/views.py index 911b22b..499c9ee 100644 --- a/src/postorius/views.py +++ b/src/postorius/views.py @@ -35,7 +35,10 @@ from django.http import HttpResponse, HttpResponseRedirect from django.shortcuts import render_to_response, redirect from django.template import Context, loader, RequestContext +from django.utils.decorators import method_decorator from django.utils.translation import gettext as _ +from django.views.generic import TemplateView + from mailman.client import Client from models import (Domain, List, Member, MailmanUser, MailmanApiError, Mailman404Error) @@ -88,6 +91,21 @@ {'form': form,'message': message}, context_instance=RequestContext(request)) + +class ListMembersView(TemplateView): + """Display all members of a given list.""" + + def get_list(self, fqdn_listname): + return List.objects.get_or_404(fqdn_listname=fqdn_listname) + + @method_decorator(login_required(login_url='/accounts/login/')) + @method_decorator(user_passes_test(lambda u: u.is_superuser)) + def get(self, request, fqdn_listname): + return render_to_response('postorius/lists/members.html', + {'list': self.get_list(fqdn_listname)}, + context_instance=RequestContext(request)) + + @login_required @user_passes_test(lambda u: u.is_superuser) def list_new(request, template = 'postorius/lists/new.html'):