Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/dax/jmc.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/debian
diff options
context:
space:
mode:
authorDavid Rousselie <david.rousselie@happycoders.org>2010-06-04 21:59:40 +0400
committerDavid Rousselie <david.rousselie@happycoders.org>2010-06-04 21:59:40 +0400
commit6cba8014502d61d22b297dad36ad6b9ea440bfed (patch)
tree19c241bc37ab3673d9766a4954e9045f4a93461c /debian
parent74feff9ea9711a7725dd4909fc7a755c95e05311 (diff)
release JMC 0.3 beta3
Diffstat (limited to 'debian')
-rw-r--r--debian/changelog6
-rw-r--r--debian/control2
-rw-r--r--debian/patches/debian-changes-0.3b35745
-rw-r--r--debian/patches/series1
-rw-r--r--debian/source/format1
5 files changed, 5754 insertions, 1 deletions
diff --git a/debian/changelog b/debian/changelog
index 50b5334..000c192 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+jmc (0.3b3) unstable; urgency=low
+
+ * JMC version 0.3 beta 3
+
+ -- David Rousselie <dax@happycoders.org> Fri, 04 Jun 2010 19:44:55 +0200
+
jmc (0.3b2) unstable; urgency=low
* JMC version 0.3 beta 2
diff --git a/debian/control b/debian/control
index 89fd0f8..8f3d72f 100644
--- a/debian/control
+++ b/debian/control
@@ -7,7 +7,7 @@ Standards-Version: 3.8.4
Package: python-jmc
Architecture: all
-Depends: ${python:Depends}, python-jcl (= 0.1b2)
+Depends: ${python:Depends}, python-jcl (= 0.1b3)
Provides: ${python:Provides}
Description: JMC is an email gateway for Jabber
JMC is a jabber service to check email from POP3 and IMAP4 server and
diff --git a/debian/patches/debian-changes-0.3b3 b/debian/patches/debian-changes-0.3b3
new file mode 100644
index 0000000..11b7e2d
--- /dev/null
+++ b/debian/patches/debian-changes-0.3b3
@@ -0,0 +1,5745 @@
+Description: Upstream changes introduced in version 0.3b3
+ This patch has been created by dpkg-source during the package build.
+ Here's the last changelog entry, hopefully it gives details on why
+ those changes were made:
+ .
+ jmc (0.3b3) unstable; urgency=low
+ .
+ * JMC version 0.3 beta 3
+ .
+ The person named in the Author field signed this changelog entry.
+Author: David Rousselie <dax@happycoders.org>
+
+---
+The information above should follow the Patch Tagging Guidelines, please
+checkout http://dep.debian.net/deps/dep3/ to learn about the format. Here
+are templates for supplementary fields that you might want to add:
+
+Origin: <vendor|upstream|other>, <url of original patch>
+Bug: <url in upstream bugtracker>
+Bug-Debian: http://bugs.debian.org/<bugnumber>
+Forwarded: <no|not-needed|url proving that it has been forwarded>
+Reviewed-By: <name and email of someone who approved the patch>
+Last-Update: <YYYY-MM-DD>
+
+--- /dev/null
++++ jmc-0.3b3/jmc-local.conf
+@@ -0,0 +1,45 @@
++[jabber]
++server: localhost
++port: 5275
++secret: secret
++service_jid: jmc.octo-dro-linux
++#supported language: en, fr (See src/jmc/lang.py to add more)
++language: en
++
++[db]
++#SQLite config
++type: sqlite
++host:
++name: /tmp/jmc.db
++#Mysql config
++#type: mysql
++#host: root:pass@localhost
++#name: /jmc
++#db_url: %(type)s://%(host)s%(name)s?debug=1&debugThreading=1
++db_url: %(type)s://%(host)s%(name)s
++
++
++[component]
++pid_file: /tmp/jmc.pid
++#motd: "Message of the day"
++welcome_message: "Welcome to Jabber Mail Component"
++# a comma separated list of JIDs
++admins: admin@localhost
++log_file: /tmp/jmc.log
++
++[jmc]
++mail_default_encoding: iso-8859-1
++check_interval: 1
++
++[vcard]
++url: http://people.happycoders.org/dax/projects/jmc
++
++[smtp]
++smtp_default_login: test
++smtp_default_password: test
++smtp_default_host: testhost
++smtp_default_port: 25
++smtp_default_tls: True
++smtp_default_label: Default SMTP Server
++enable_smtp_default_account: False
++
+--- /dev/null
++++ jmc-0.3b3/Makefile
+@@ -0,0 +1,32 @@
++PYTHON=`which python`
++DESTDIR=/
++BUILDIR=$(CURDIR)/debian/jmc
++PROJECT=jmc
++VERSION=0.3b3
++
++all:
++ @echo "make source - Create source package"
++ @echo "make install - Install on local system"
++ @echo "make buildrpm - Generate a rpm package"
++ @echo "make builddeb - Generate a deb package"
++ @echo "make clean - Get rid of scratch and byte files"
++
++source:
++ $(PYTHON) setup.py sdist $(COMPILE)
++
++install:
++ $(PYTHON) setup.py install --root $(DESTDIR) $(COMPILE)
++
++buildrpm:
++ $(PYTHON) setup.py bdist_rpm --post-install=rpm/postinstall --pre-uninstall=rpm/preuninstall
++
++builddeb:
++ $(PYTHON) setup.py sdist $(COMPILE) --dist-dir=../
++ rename -f 's/$(PROJECT)-(.*)\.tar\.gz/$(PROJECT)_$$1\.orig\.tar\.gz/' ../*
++ dpkg-buildpackage -us -uc -i -I -rfakeroot
++
++clean:
++ $(PYTHON) setup.py clean
++ fakeroot $(MAKE) -f $(CURDIR)/debian/rules clean
++ rm -rf build/ MANIFEST
++ find . -name '*.pyc' -delete
+--- /dev/null
++++ jmc-0.3b3/analyse_profiling.py
+@@ -0,0 +1,27 @@
++# -*- coding: utf-8 -*-
++##
++## analyse_profiling.py
++## Login : David Rousselie <dax@happycoders.org>
++## Started on Thu May 29 19:09:02 2008 David Rousselie
++## $Id$
++##
++## Copyright (C) 2008 David Rousselie
++## This program 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 2 of the License, or
++## (at your option) any later version.
++##
++## This program 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 this program; if not, write to the Free Software
++## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++##
++
++import pstats
++
++stats = pstats.Stats("jmc.prof")
++stats.strip_dirs().sort_stats('time').print_stats()
+--- /dev/null
++++ jmc-0.3b3/run_tests.py
+@@ -0,0 +1,71 @@
++# -*- coding: utf-8 -*-
++##
++## run_tests.py
++## Login : David Rousselie <dax@happycoders.org>
++## Started on Wed Aug 9 21:37:35 2006 David Rousselie
++## $Id$
++##
++## Copyright (C) 2006 David Rousselie
++## This program 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 2 of the License, or
++## (at your option) any later version.
++##
++## This program 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 this program; if not, write to the Free Software
++## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++##
++
++import coverage
++coverage.erase()
++coverage.start()
++
++import logging
++import unittest
++from test import test_support
++
++import sys
++sys.path.append("src")
++reload(sys)
++sys.setdefaultencoding('utf8')
++del sys.setdefaultencoding
++
++import jmc
++import jmc.jabber
++import jmc.jabber.component
++
++import jmc.tests
++
++def suite():
++ return jmc.tests.suite()
++
++if __name__ == '__main__':
++ class MyTestProgram(unittest.TestProgram):
++ def runTests(self):
++ """run tests but do not exit after"""
++ self.testRunner = unittest.TextTestRunner(verbosity=self.verbosity)
++ self.testRunner.run(self.test)
++
++ logger = logging.getLogger()
++ logger.addHandler(logging.StreamHandler())
++ logger.setLevel(logging.CRITICAL)
++
++ MyTestProgram(defaultTest='suite')
++
++coverage.report(["src/jmc/__init__.py",
++ "src/jmc/lang.py",
++ "src/jmc/runner.py",
++ "src/jmc/jabber/__init__.py",
++ "src/jmc/jabber/command.py",
++ "src/jmc/jabber/component.py",
++ "src/jmc/jabber/disco.py",
++ "src/jmc/jabber/message.py",
++ "src/jmc/jabber/presence.py",
++ "src/jmc/jabber/presence.py",
++ "src/jmc/model/__init__.py",
++ "src/jmc/model/account.py"])
+--- /dev/null
++++ jmc-0.3b3/profile_jmc.py
+@@ -0,0 +1,27 @@
++# -*- coding: utf-8 -*-
++##
++## profile_jmc.py
++## Login : David Rousselie <dax@happycoders.org>
++## Started on Thu May 29 19:09:02 2008 David Rousselie
++## $Id$
++##
++## Copyright (C) 2008 David Rousselie
++## This program 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 2 of the License, or
++## (at your option) any later version.
++##
++## This program 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 this program; if not, write to the Free Software
++## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++##
++
++import cProfile
++import jmc.runner as runner
++
++cProfile.run("runner.main()", "jmc.prof")
+--- /dev/null
++++ jmc-0.3b3/resolv.conf
+@@ -0,0 +1,2 @@
++# Generated by NetworkManager
++nameserver 192.168.10.110
+--- /dev/null
++++ jmc-0.3b3/COPYING
+@@ -0,0 +1,340 @@
++ GNU GENERAL PUBLIC LICENSE
++ Version 2, June 1991
++
++ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
++ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++ Everyone is permitted to copy and distribute verbatim copies
++ of this license document, but changing it is not allowed.
++
++ Preamble
++
++ The licenses for most software are designed to take away your
++freedom to share and change it. By contrast, the GNU General Public
++License is intended to guarantee your freedom to share and change free
++software--to make sure the software is free for all its users. This
++General Public License applies to most of the Free Software
++Foundation's software and to any other program whose authors commit to
++using it. (Some other Free Software Foundation software is covered by
++the GNU Library General Public License instead.) You can apply it to
++your programs, too.
++
++ When we speak of free software, we are referring to freedom, not
++price. Our General Public Licenses are designed to make sure that you
++have the freedom to distribute copies of free software (and charge for
++this service if you wish), that you receive source code or can get it
++if you want it, that you can change the software or use pieces of it
++in new free programs; and that you know you can do these things.
++
++ To protect your rights, we need to make restrictions that forbid
++anyone to deny you these rights or to ask you to surrender the rights.
++These restrictions translate to certain responsibilities for you if you
++distribute copies of the software, or if you modify it.
++
++ For example, if you distribute copies of such a program, whether
++gratis or for a fee, you must give the recipients all the rights that
++you have. You must make sure that they, too, receive or can get the
++source code. And you must show them these terms so they know their
++rights.
++
++ We protect your rights with two steps: (1) copyright the software, and
++(2) offer you this license which gives you legal permission to copy,
++distribute and/or modify the software.
++
++ Also, for each author's protection and ours, we want to make certain
++that everyone understands that there is no warranty for this free
++software. If the software is modified by someone else and passed on, we
++want its recipients to know that what they have is not the original, so
++that any problems introduced by others will not reflect on the original
++authors' reputations.
++
++ Finally, any free program is threatened constantly by software
++patents. We wish to avoid the danger that redistributors of a free
++program will individually obtain patent licenses, in effect making the
++program proprietary. To prevent this, we have made it clear that any
++patent must be licensed for everyone's free use or not licensed at all.
++
++ The precise terms and conditions for copying, distribution and
++modification follow.
++
++ GNU GENERAL PUBLIC LICENSE
++ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
++
++ 0. This License applies to any program or other work which contains
++a notice placed by the copyright holder saying it may be distributed
++under the terms of this General Public License. The "Program", below,
++refers to any such program or work, and a "work based on the Program"
++means either the Program or any derivative work under copyright law:
++that is to say, a work containing the Program or a portion of it,
++either verbatim or with modifications and/or translated into another
++language. (Hereinafter, translation is included without limitation in
++the term "modification".) Each licensee is addressed as "you".
++
++Activities other than copying, distribution and modification are not
++covered by this License; they are outside its scope. The act of
++running the Program is not restricted, and the output from the Program
++is covered only if its contents constitute a work based on the
++Program (independent of having been made by running the Program).
++Whether that is true depends on what the Program does.
++
++ 1. You may copy and distribute verbatim copies of the Program's
++source code as you receive it, in any medium, provided that you
++conspicuously and appropriately publish on each copy an appropriate
++copyright notice and disclaimer of warranty; keep intact all the
++notices that refer to this License and to the absence of any warranty;
++and give any other recipients of the Program a copy of this License
++along with the Program.
++
++You may charge a fee for the physical act of transferring a copy, and
++you may at your option offer warranty protection in exchange for a fee.
++
++ 2. You may modify your copy or copies of the Program or any portion
++of it, thus forming a work based on the Program, and copy and
++distribute such modifications or work under the terms of Section 1
++above, provided that you also meet all of these conditions:
++
++ a) You must cause the modified files to carry prominent notices
++ stating that you changed the files and the date of any change.
++
++ b) You must cause any work that you distribute or publish, that in
++ whole or in part contains or is derived from the Program or any
++ part thereof, to be licensed as a whole at no charge to all third
++ parties under the terms of this License.
++
++ c) If the modified program normally reads commands interactively
++ when run, you must cause it, when started running for such
++ interactive use in the most ordinary way, to print or display an
++ announcement including an appropriate copyright notice and a
++ notice that there is no warranty (or else, saying that you provide
++ a warranty) and that users may redistribute the program under
++ these conditions, and telling the user how to view a copy of this
++ License. (Exception: if the Program itself is interactive but
++ does not normally print such an announcement, your work based on
++ the Program is not required to print an announcement.)
++
++These requirements apply to the modified work as a whole. If
++identifiable sections of that work are not derived from the Program,
++and can be reasonably considered independent and separate works in
++themselves, then this License, and its terms, do not apply to those
++sections when you distribute them as separate works. But when you
++distribute the same sections as part of a whole which is a work based
++on the Program, the distribution of the whole must be on the terms of
++this License, whose permissions for other licensees extend to the
++entire whole, and thus to each and every part regardless of who wrote it.
++
++Thus, it is not the intent of this section to claim rights or contest
++your rights to work written entirely by you; rather, the intent is to
++exercise the right to control the distribution of derivative or
++collective works based on the Program.
++
++In addition, mere aggregation of another work not based on the Program
++with the Program (or with a work based on the Program) on a volume of
++a storage or distribution medium does not bring the other work under
++the scope of this License.
++
++ 3. You may copy and distribute the Program (or a work based on it,
++under Section 2) in object code or executable form under the terms of
++Sections 1 and 2 above provided that you also do one of the following:
++
++ a) Accompany it with the complete corresponding machine-readable
++ source code, which must be distributed under the terms of Sections
++ 1 and 2 above on a medium customarily used for software interchange; or,
++
++ b) Accompany it with a written offer, valid for at least three
++ years, to give any third party, for a charge no more than your
++ cost of physically performing source distribution, a complete
++ machine-readable copy of the corresponding source code, to be
++ distributed under the terms of Sections 1 and 2 above on a medium
++ customarily used for software interchange; or,
++
++ c) Accompany it with the information you received as to the offer
++ to distribute corresponding source code. (This alternative is
++ allowed only for noncommercial distribution and only if you
++ received the program in object code or executable form with such
++ an offer, in accord with Subsection b above.)
++
++The source code for a work means the preferred form of the work for
++making modifications to it. For an executable work, complete source
++code means all the source code for all modules it contains, plus any
++associated interface definition files, plus the scripts used to
++control compilation and installation of the executable. However, as a
++special exception, the source code distributed need not include
++anything that is normally distributed (in either source or binary
++form) with the major components (compiler, kernel, and so on) of the
++operating system on which the executable runs, unless that component
++itself accompanies the executable.
++
++If distribution of executable or object code is made by offering
++access to copy from a designated place, then offering equivalent
++access to copy the source code from the same place counts as
++distribution of the source code, even though third parties are not
++compelled to copy the source along with the object code.
++
++ 4. You may not copy, modify, sublicense, or distribute the Program
++except as expressly provided under this License. Any attempt
++otherwise to copy, modify, sublicense or distribute the Program is
++void, and will automatically terminate your rights under this License.
++However, parties who have received copies, or rights, from you under
++this License will not have their licenses terminated so long as such
++parties remain in full compliance.
++
++ 5. You are not required to accept this License, since you have not
++signed it. However, nothing else grants you permission to modify or
++distribute the Program or its derivative works. These actions are
++prohibited by law if you do not accept this License. Therefore, by
++modifying or distributing the Program (or any work based on the
++Program), you indicate your acceptance of this License to do so, and
++all its terms and conditions for copying, distributing or modifying
++the Program or works based on it.
++
++ 6. Each time you redistribute the Program (or any work based on the
++Program), the recipient automatically receives a license from the
++original licensor to copy, distribute or modify the Program subject to
++these terms and conditions. You may not impose any further
++restrictions on the recipients' exercise of the rights granted herein.
++You are not responsible for enforcing compliance by third parties to
++this License.
++
++ 7. If, as a consequence of a court judgment or allegation of patent
++infringement or for any other reason (not limited to patent issues),
++conditions are imposed on you (whether by court order, agreement or
++otherwise) that contradict the conditions of this License, they do not
++excuse you from the conditions of this License. If you cannot
++distribute so as to satisfy simultaneously your obligations under this
++License and any other pertinent obligations, then as a consequence you
++may not distribute the Program at all. For example, if a patent
++license would not permit royalty-free redistribution of the Program by
++all those who receive copies directly or indirectly through you, then
++the only way you could satisfy both it and this License would be to
++refrain entirely from distribution of the Program.
++
++If any portion of this section is held invalid or unenforceable under
++any particular circumstance, the balance of the section is intended to
++apply and the section as a whole is intended to apply in other
++circumstances.
++
++It is not the purpose of this section to induce you to infringe any
++patents or other property right claims or to contest validity of any
++such claims; this section has the sole purpose of protecting the
++integrity of the free software distribution system, which is
++implemented by public license practices. Many people have made
++generous contributions to the wide range of software distributed
++through that system in reliance on consistent application of that
++system; it is up to the author/donor to decide if he or she is willing
++to distribute software through any other system and a licensee cannot
++impose that choice.
++
++This section is intended to make thoroughly clear what is believed to
++be a consequence of the rest of this License.
++
++ 8. If the distribution and/or use of the Program is restricted in
++certain countries either by patents or by copyrighted interfaces, the
++original copyright holder who places the Program under this License
++may add an explicit geographical distribution limitation excluding
++those countries, so that distribution is permitted only in or among
++countries not thus excluded. In such case, this License incorporates
++the limitation as if written in the body of this License.
++
++ 9. The Free Software Foundation may publish revised and/or new versions
++of the General Public License from time to time. Such new versions will
++be similar in spirit to the present version, but may differ in detail to
++address new problems or concerns.
++
++Each version is given a distinguishing version number. If the Program
++specifies a version number of this License which applies to it and "any
++later version", you have the option of following the terms and conditions
++either of that version or of any later version published by the Free
++Software Foundation. If the Program does not specify a version number of
++this License, you may choose any version ever published by the Free Software
++Foundation.
++
++ 10. If you wish to incorporate parts of the Program into other free
++programs whose distribution conditions are different, write to the author
++to ask for permission. For software which is copyrighted by the Free
++Software Foundation, write to the Free Software Foundation; we sometimes
++make exceptions for this. Our decision will be guided by the two goals
++of preserving the free status of all derivatives of our free software and
++of promoting the sharing and reuse of software generally.
++
++ NO WARRANTY
++
++ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
++FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
++OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
++PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
++OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
++MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
++TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
++PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
++REPAIR OR CORRECTION.
++
++ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
++WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
++REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
++INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
++OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
++TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
++YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
++PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
++POSSIBILITY OF SUCH DAMAGES.
++
++ END OF TERMS AND CONDITIONS
++
++ How to Apply These Terms to Your New Programs
++
++ If you develop a new program, and you want it to be of the greatest
++possible use to the public, the best way to achieve this is to make it
++free software which everyone can redistribute and change under these terms.
++
++ To do so, attach the following notices to the program. It is safest
++to attach them to the start of each source file to most effectively
++convey the exclusion of warranty; and each file should have at least
++the "copyright" line and a pointer to where the full notice is found.
++
++ <one line to give the program's name and a brief idea of what it does.>
++ Copyright (C) <year> <name of author>
++
++ This program 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 2 of the License, or
++ (at your option) any later version.
++
++ This program 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 this program; if not, write to the Free Software
++ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++
++
++Also add information on how to contact you by electronic and paper mail.
++
++If the program is interactive, make it output a short notice like this
++when it starts in an interactive mode:
++
++ Gnomovision version 69, Copyright (C) year name of author
++ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
++ This is free software, and you are welcome to redistribute it
++ under certain conditions; type `show c' for details.
++
++The hypothetical commands `show w' and `show c' should show the appropriate
++parts of the General Public License. Of course, the commands you use may
++be called something other than `show w' and `show c'; they could even be
++mouse-clicks or menu items--whatever suits your program.
++
++You should also get your employer (if you work as a programmer) or your
++school, if any, to sign a "copyright disclaimer" for the program, if
++necessary. Here is a sample; alter the names:
++
++ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
++ `Gnomovision' (which makes passes at compilers) written by James Hacker.
++
++ <signature of Ty Coon>, 1 April 1989
++ Ty Coon, President of Vice
++
++This General Public License does not permit incorporating your program into
++proprietary programs. If your program is a subroutine library, you may
++consider it more useful to permit linking proprietary applications with the
++library. If this is what you want to do, use the GNU Library General
++Public License instead of this License.
+--- /dev/null
++++ jmc-0.3b3/TODO
+@@ -0,0 +1,12 @@
++* Support for attachements with size limit and file format limit
++ (e.g. only png, jpeg,... but no exe, bat,...).
++
++* Make real documentation
++
++* Support for Ad Hoc Commands (see PyMSNt cvs, avatar
++ branch). Interesting for statistics.
++
++* Support for epoll, kpoll and kqueu (see PyMSNt cvs, avatar branch
++ code).
++
++
+--- /dev/null
++++ jmc-0.3b3/sqlobject_history/2007-11-05/POP3Account_sqlite.sql
+@@ -0,0 +1,9 @@
++-- Exported definition from 2007-11-05T19:02:34
++-- Class jmc.model.account.POP3Account
++-- Database: sqlite
++CREATE TABLE po_p3_account (
++ id INTEGER PRIMARY KEY,
++ nb_mail INT,
++ lastmail INT,
++ child_name VARCHAR(255)
++)
+--- /dev/null
++++ jmc-0.3b3/sqlobject_history/2007-11-05/PresenceAccount_sqlite.sql
+@@ -0,0 +1,13 @@
++-- Exported definition from 2007-11-05T19:02:34
++-- Class jcl.model.account.PresenceAccount
++-- Database: sqlite
++CREATE TABLE presence_account (
++ id INTEGER PRIMARY KEY,
++ chat_action INT,
++ online_action INT,
++ away_action INT,
++ xa_action INT,
++ dnd_action INT,
++ offline_action INT,
++ child_name VARCHAR(255)
++)
+--- /dev/null
++++ jmc-0.3b3/sqlobject_history/2007-11-05/IMAPAccount_sqlite.sql
+@@ -0,0 +1,9 @@
++-- Exported definition from 2007-11-05T19:02:34
++-- Class jmc.model.account.IMAPAccount
++-- Database: sqlite
++CREATE TABLE imap_account (
++ id INTEGER PRIMARY KEY,
++ mailbox TEXT,
++ delimiter TEXT,
++ child_name VARCHAR(255)
++)
+--- /dev/null
++++ jmc-0.3b3/sqlobject_history/2007-11-05/User_sqlite.sql
+@@ -0,0 +1,9 @@
++-- Exported definition from 2007-11-05T19:02:34
++-- Class jcl.model.account.User
++-- Database: sqlite
++CREATE TABLE user (
++ id INTEGER PRIMARY KEY,
++ jid TEXT,
++ has_received_motd TINYINT,
++ child_name VARCHAR(255)
++)
+--- /dev/null
++++ jmc-0.3b3/sqlobject_history/2007-11-05/LegacyJID_sqlite.sql
+@@ -0,0 +1,10 @@
++-- Exported definition from 2007-11-05T19:02:34
++-- Class jcl.model.account.LegacyJID
++-- Database: sqlite
++CREATE TABLE legacy_j_id (
++ id INTEGER PRIMARY KEY,
++ legacy_address TEXT,
++ jid TEXT,
++ account_id INT CONSTRAINT account_id_exists REFERENCES account(id) ,
++ child_name VARCHAR(255)
++)
+--- /dev/null
++++ jmc-0.3b3/sqlobject_history/2007-11-05/SMTPAccount_sqlite.sql
+@@ -0,0 +1,16 @@
++-- Exported definition from 2007-11-05T19:02:34
++-- Class jmc.model.account.SMTPAccount
++-- Database: sqlite
++CREATE TABLE smtp_account (
++ id INTEGER PRIMARY KEY,
++ login TEXT,
++ password TEXT,
++ host TEXT,
++ port INT,
++ tls TINYINT,
++ store_password TINYINT,
++ waiting_password_reply TINYINT,
++ default_from TEXT,
++ default_account TINYINT,
++ child_name VARCHAR(255)
++)
+--- /dev/null
++++ jmc-0.3b3/sqlobject_history/2007-11-05/MailAccount_sqlite.sql
+@@ -0,0 +1,18 @@
++-- Exported definition from 2007-11-05T19:02:34
++-- Class jmc.model.account.MailAccount
++-- Database: sqlite
++CREATE TABLE mail_account (
++ id INTEGER PRIMARY KEY,
++ login TEXT,
++ password TEXT,
++ host TEXT,
++ port INT,
++ _ssl TINYINT,
++ _interval INT,
++ store_password TINYINT,
++ live_email_only TINYINT,
++ lastcheck INT,
++ waiting_password_reply TINYINT,
++ first_check TINYINT,
++ child_name VARCHAR(255)
++)
+--- /dev/null
++++ jmc-0.3b3/sqlobject_history/2007-11-05/Account_sqlite.sql
+@@ -0,0 +1,14 @@
++-- Exported definition from 2007-11-05T19:02:34
++-- Class jcl.model.account.Account
++-- Database: sqlite
++CREATE TABLE account (
++ id INTEGER PRIMARY KEY,
++ name TEXT,
++ jid TEXT,
++ status TEXT,
++ in_error TINYINT,
++ enabled TINYINT,
++ lastlogin TIMESTAMP,
++ user_id INT CONSTRAINT user_id_exists REFERENCES user(id) ,
++ child_name VARCHAR(255)
++)
+--- /dev/null
++++ jmc-0.3b3/sqlobject_history/2008-05-29/POP3Account_sqlite.sql
+@@ -0,0 +1,9 @@
++-- Exported definition from 2008-05-29T19:26:03
++-- Class jmc.model.account.POP3Account
++-- Database: sqlite
++CREATE TABLE po_p3_account (
++ id INTEGER PRIMARY KEY,
++ nb_mail INT,
++ lastmail INT,
++ child_name VARCHAR(255)
++)
+--- /dev/null
++++ jmc-0.3b3/sqlobject_history/2008-05-29/IMAPAccount_sqlite.sql
+@@ -0,0 +1,9 @@
++-- Exported definition from 2008-05-29T19:26:03
++-- Class jmc.model.account.IMAPAccount
++-- Database: sqlite
++CREATE TABLE imap_account (
++ id INTEGER PRIMARY KEY,
++ mailbox TEXT,
++ delimiter TEXT,
++ child_name VARCHAR(255)
++)
+--- /dev/null
++++ jmc-0.3b3/sqlobject_history/2008-05-29/SMTPAccount_sqlite.sql
+@@ -0,0 +1,7 @@
++-- Exported definition from 2008-05-29T19:26:03
++-- Class jmc.model.account.SMTPAccount
++-- Database: sqlite
++CREATE TABLE smtp_account (
++ id INTEGER PRIMARY KEY,
++ child_name VARCHAR(255)
++)
+--- /dev/null
++++ jmc-0.3b3/sqlobject_history/2008-05-29/MailAccount_sqlite.sql
+@@ -0,0 +1,18 @@
++-- Exported definition from 2008-05-29T19:26:03
++-- Class jmc.model.account.MailAccount
++-- Database: sqlite
++CREATE TABLE mail_account (
++ id INTEGER PRIMARY KEY,
++ login TEXT,
++ password TEXT,
++ host TEXT,
++ port INT,
++ _ssl TINYINT,
++ _interval INT,
++ store_password TINYINT,
++ live_email_only TINYINT,
++ lastcheck INT,
++ waiting_password_reply TINYINT,
++ first_check TINYINT,
++ child_name VARCHAR(255)
++)
+--- /dev/null
++++ jmc-0.3b3/sqlobject_history/2008-05-29/AbstractSMTPAccount_sqlite.sql
+@@ -0,0 +1,9 @@
++-- Exported definition from 2008-05-29T19:26:03
++-- Class jmc.model.account.AbstractSMTPAccount
++-- Database: sqlite
++CREATE TABLE abstract_smtp_account (
++ id INTEGER PRIMARY KEY,
++ default_from TEXT,
++ default_account TINYINT,
++ child_name VARCHAR(255)
++)
+--- /dev/null
++++ jmc-0.3b3/sqlobject_history/2008-05-29/GlobalSMTPAccount_sqlite.sql
+@@ -0,0 +1,14 @@
++-- Exported definition from 2008-05-29T19:26:03
++-- Class jmc.model.account.GlobalSMTPAccount
++-- Database: sqlite
++CREATE TABLE global_smtp_account (
++ id INTEGER PRIMARY KEY,
++ login TEXT,
++ password TEXT,
++ host TEXT,
++ port INT,
++ tls TINYINT,
++ store_password TINYINT,
++ waiting_password_reply TINYINT,
++ child_name VARCHAR(255)
++)
+--- /dev/null
++++ jmc-0.3b3/sqlobject_history/2007-12-04/POP3Account_sqlite.sql
+@@ -0,0 +1,9 @@
++-- Exported definition from 2007-12-04T17:57:39
++-- Class jmc.model.account.POP3Account
++-- Database: sqlite
++CREATE TABLE po_p3_account (
++ id INTEGER PRIMARY KEY,
++ nb_mail INT,
++ lastmail INT,
++ child_name VARCHAR(255)
++)
+--- /dev/null
++++ jmc-0.3b3/sqlobject_history/2007-12-04/PresenceAccount_sqlite.sql
+@@ -0,0 +1,13 @@
++-- Exported definition from 2007-12-04T17:57:39
++-- Class jcl.model.account.PresenceAccount
++-- Database: sqlite
++CREATE TABLE presence_account (
++ id INTEGER PRIMARY KEY,
++ chat_action INT,
++ online_action INT,
++ away_action INT,
++ xa_action INT,
++ dnd_action INT,
++ offline_action INT,
++ child_name VARCHAR(255)
++)
+--- /dev/null
++++ jmc-0.3b3/sqlobject_history/2007-12-04/upgrade_sqlite_2008-05-29.sql
+@@ -0,0 +1,66 @@
++-- Class jmc.model.account.AbstractSMTPAccount
++-- Database: sqlite
++CREATE TABLE abstract_smtp_account (
++ id INTEGER PRIMARY KEY,
++ default_from TEXT,
++ default_account TINYINT,
++ child_name VARCHAR(255)
++);
++
++-- Class jmc.model.account.GlobalSMTPAccount
++-- Database: sqlite
++CREATE TABLE global_smtp_account (
++ id INTEGER PRIMARY KEY,
++ login TEXT,
++ password TEXT,
++ host TEXT,
++ port INT,
++ tls TINYINT,
++ store_password TINYINT,
++ waiting_password_reply TINYINT,
++ child_name VARCHAR(255)
++);
++
++INSERT INTO abstract_smtp_account
++ SELECT
++ id,
++ default_from,
++ default_account,
++ "GlobalSMTPAccount"
++ FROM
++ smtp_account;
++
++INSERT INTO global_smtp_account
++ SELECT
++ id,
++ login,
++ password,
++ host,
++ port,
++ tls,
++ store_password,
++ waiting_password_reply,
++ "SMTPAccount"
++ FROM
++ smtp_account;
++
++DROP TABLE smtp_account;
++
++-- Class jmc.model.account.SMTPAccount
++-- Database: sqlite
++CREATE TABLE smtp_account (
++ id INTEGER PRIMARY KEY,
++ child_name VARCHAR(255)
++);
++
++INSERT INTO smtp_account
++ SELECT
++ id,
++ NULL
++ FROM
++ global_smtp_account;
++
++UPDATE account SET
++ child_name="AbstractSMTPAccount"
++WHERE
++ child_name="SMTPAccount";
+--- /dev/null
++++ jmc-0.3b3/sqlobject_history/2007-12-04/IMAPAccount_sqlite.sql
+@@ -0,0 +1,9 @@
++-- Exported definition from 2007-12-04T17:57:39
++-- Class jmc.model.account.IMAPAccount
++-- Database: sqlite
++CREATE TABLE imap_account (
++ id INTEGER PRIMARY KEY,
++ mailbox TEXT,
++ delimiter TEXT,
++ child_name VARCHAR(255)
++)
+--- /dev/null
++++ jmc-0.3b3/sqlobject_history/2007-12-04/User_sqlite.sql
+@@ -0,0 +1,9 @@
++-- Exported definition from 2007-12-04T17:57:39
++-- Class jcl.model.account.User
++-- Database: sqlite
++CREATE TABLE user (
++ id INTEGER PRIMARY KEY,
++ jid TEXT,
++ has_received_motd TINYINT,
++ child_name VARCHAR(255)
++)
+--- /dev/null
++++ jmc-0.3b3/sqlobject_history/2007-12-04/LegacyJID_sqlite.sql
+@@ -0,0 +1,10 @@
++-- Exported definition from 2007-12-04T17:57:39
++-- Class jcl.model.account.LegacyJID
++-- Database: sqlite
++CREATE TABLE legacy_j_id (
++ id INTEGER PRIMARY KEY,
++ legacy_address TEXT,
++ jid TEXT,
++ account_id INT CONSTRAINT account_id_exists REFERENCES account(id) ,
++ child_name VARCHAR(255)
++)
+--- /dev/null
++++ jmc-0.3b3/sqlobject_history/2007-12-04/SMTPAccount_sqlite.sql
+@@ -0,0 +1,16 @@
++-- Exported definition from 2007-12-04T17:57:39
++-- Class jmc.model.account.SMTPAccount
++-- Database: sqlite
++CREATE TABLE smtp_account (
++ id INTEGER PRIMARY KEY,
++ login TEXT,
++ password TEXT,
++ host TEXT,
++ port INT,
++ tls TINYINT,
++ store_password TINYINT,
++ waiting_password_reply TINYINT,
++ default_from TEXT,
++ default_account TINYINT,
++ child_name VARCHAR(255)
++)
+--- /dev/null
++++ jmc-0.3b3/sqlobject_history/2007-12-04/MailAccount_sqlite.sql
+@@ -0,0 +1,18 @@
++-- Exported definition from 2007-12-04T17:57:39
++-- Class jmc.model.account.MailAccount
++-- Database: sqlite
++CREATE TABLE mail_account (
++ id INTEGER PRIMARY KEY,
++ login TEXT,
++ password TEXT,
++ host TEXT,
++ port INT,
++ _ssl TINYINT,
++ _interval INT,
++ store_password TINYINT,
++ live_email_only TINYINT,
++ lastcheck INT,
++ waiting_password_reply TINYINT,
++ first_check TINYINT,
++ child_name VARCHAR(255)
++)
+--- /dev/null
++++ jmc-0.3b3/sqlobject_history/2007-12-04/Account_sqlite.sql
+@@ -0,0 +1,14 @@
++-- Exported definition from 2007-12-04T17:57:39
++-- Class jcl.model.account.Account
++-- Database: sqlite
++CREATE TABLE account (
++ id INTEGER PRIMARY KEY,
++ name TEXT,
++ jid TEXT,
++ status TEXT,
++ error TEXT,
++ enabled TINYINT,
++ lastlogin TIMESTAMP,
++ user_id INT CONSTRAINT user_id_exists REFERENCES user(id) ,
++ child_name VARCHAR(255)
++)
+--- /dev/null
++++ jmc-0.3b3/conf/jmc.conf
+@@ -0,0 +1,45 @@
++[jabber]
++server: localhost
++port: 5347
++secret: secret
++service_jid: jmc.localhost
++#supported language: en, fr (See src/jmc/lang.py to add more)
++language: en
++
++[db]
++#SQLite config
++type: sqlite
++host:
++name: /var/spool/jabber/jmc.db
++#Mysql config
++#type: mysql
++#host: root:pass@localhost
++#name: /jmc
++#db_url: %(type)s://%(host)s%(name)s?debug=1&debugThreading=1
++db_url: %(type)s://%(host)s%(name)s
++
++
++[component]
++pid_file: /var/run/jabber/jmc.pid
++#motd: "Message of the day"
++welcome_message: "Welcome to Jabber Mail Component"
++# a comma separated list of JIDs
++admins: admin@localhost
++log_file: /var/log/jabber/jmc.log
++
++[jmc]
++mail_default_encoding: iso-8859-1
++check_interval: 1
++
++[vcard]
++url: http://people.happycoders.org/dax/projects/jmc
++
++[smtp]
++smtp_default_login: test
++smtp_default_password: test
++smtp_default_host: testhost
++smtp_default_port: 25
++smtp_default_tls: True
++smtp_default_label: Default SMTP Server
++enable_smtp_default_account: False
++
+--- /dev/null
++++ jmc-0.3b3/src/jmc/tests/runner.py
+@@ -0,0 +1,324 @@
++##
++## runner.py
++## Login : David Rousselie <dax@happycoders.org>
++## Started on Fri May 18 13:43:37 2007 David Rousselie
++## $Id$
++##
++## Copyright (C) 2007 David Rousselie
++## This program 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 2 of the License, or
++## (at your option) any later version.
++##
++## This program 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 this program; if not, write to the Free Software
++## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++##
++
++import unittest
++import sys
++import os
++
++from jcl.tests import JCLTestCase
++from jcl.tests.runner import JCLRunner_TestCase
++
++import jcl.model as model
++from jcl.model.account import Account, PresenceAccount, User, LegacyJID
++
++import jmc
++from jmc.lang import Lang
++from jmc.runner import JMCRunner
++from jmc.jabber.component import MailComponent
++import jmc.model.account as account
++from jmc.model.account import MailAccount, IMAPAccount, POP3Account, \
++ AbstractSMTPAccount, GlobalSMTPAccount, SMTPAccount
++
++if sys.platform == "win32":
++ DB_PATH = "/c|/temp/test.db"
++else:
++ DB_PATH = "/tmp/test.db"
++DB_URL = "sqlite://" + DB_PATH# + "?debug=1&debugThreading=1"
++
++class JMCRunner_TestCase(JCLTestCase):
++ def setUp(self):
++ JCLTestCase.setUp(self, tables=[Account, PresenceAccount, User,
++ GlobalSMTPAccount, AbstractSMTPAccount])
++ self.runner = JMCRunner("Jabber Mail Component", jmc.version)
++ self.smtp_default_login = account.smtp_default_login
++ self.smtp_default_password = account.smtp_default_password
++ self.smtp_default_host = account.smtp_default_host
++ self.smtp_default_port = account.smtp_default_port
++ self.smtp_default_tls = account.smtp_default_tls
++ self.mail_default_encoding = MailAccount.default_encoding
++ self.type_globalsmtp_name = Lang.en.type_globalsmtp_name
++
++ def tearDown(self):
++ self.runner = None
++ sys.argv = [""]
++ account.smtp_default_login = self.smtp_default_login
++ account.smtp_default_password = self.smtp_default_password
++ account.smtp_default_host = self.smtp_default_host
++ account.smtp_default_port = self.smtp_default_port
++ account.smtp_default_tls = self.smtp_default_tls
++ MailAccount.default_encoding = self.mail_default_encoding
++ Lang.en.type_globalsmtp_name = self.type_globalsmtp_name
++
++ def test_configure_default(self):
++ self.runner.configure()
++ self.assertEquals(self.runner.config_file, "jmc.conf")
++ self.assertEquals(self.runner.server, "localhost")
++ self.assertEquals(self.runner.port, 5347)
++ self.assertEquals(self.runner.secret, "secret")
++ self.assertEquals(self.runner.service_jid, "jmc.localhost")
++ self.assertEquals(self.runner.language, "en")
++ self.assertEquals(self.runner.db_url, "sqlite:///var/spool/jabber/jmc.db")
++ self.assertEquals(self.runner.pid_file, "/var/run/jabber/jmc.pid")
++ self.assertFalse(self.runner.debug)
++ self.assertEquals(self.runner.mail_default_encoding, "iso-8859-1")
++ self.assertEquals(self.runner.smtp_default_login, None)
++ self.assertEquals(self.runner.smtp_default_password, None)
++ self.assertEquals(self.runner.smtp_default_host, None)
++ self.assertEquals(self.runner.smtp_default_port, 0)
++ self.assertEquals(self.runner.smtp_default_tls, False)
++ self.assertEquals(self.runner.enable_smtp_default_account, False)
++ self.assertEquals(self.runner.smtp_default_label, None)
++ self.runner.setup_smtp_default()
++ self.assertEquals(Lang.en.type_globalsmtp_name,
++ "Default SMTP Server")
++ _account = GlobalSMTPAccount(user=User(jid="user1@test.com"),
++ name="account1",
++ jid="account1@jmc.test.com")
++ self.assertEquals(_account.login, '')
++ self.assertEquals(_account.password, '')
++ self.assertEquals(_account.host, 'localhost')
++ self.assertEquals(_account.port, 25)
++ self.assertEquals(_account.tls, False)
++
++ def test_configure_configfile(self):
++ self.runner.config_file = "src/jmc/tests/jmc.conf"
++ self.runner.configure()
++ self.assertEquals(self.runner.server, "test_localhost")
++ self.assertEquals(self.runner.port, 42)
++ self.assertEquals(self.runner.secret, "test_secret")
++ self.assertEquals(self.runner.service_jid, "test_jmc.localhost")
++ self.assertEquals(self.runner.language, "test_en")
++ self.assertEquals(self.runner.db_url, "test_sqlite://root@localhost/var/spool/jabber/test_jmc.db")
++ self.assertEquals(self.runner.pid_file, "/var/run/jabber/test_jmc.pid")
++ self.assertFalse(self.runner.debug)
++ self.assertEquals(self.runner.mail_default_encoding, "test_iso-8859-1")
++ self.assertEquals(self.runner.smtp_default_login, "testlogin")
++ self.assertEquals(self.runner.smtp_default_password, "testpassword")
++ self.assertEquals(self.runner.smtp_default_host, "testhost")
++ self.assertEquals(self.runner.smtp_default_port, 2525)
++ self.assertEquals(self.runner.smtp_default_tls, True)
++ self.assertEquals(self.runner.enable_smtp_default_account, True)
++ self.assertEquals(self.runner.smtp_default_label, "SMTP Server")
++ self.runner.setup_smtp_default()
++ self.assertEquals(Lang.en.type_globalsmtp_name,
++ "SMTP Server")
++ _account = GlobalSMTPAccount(user=User(jid="user1@test.com"),
++ name="account1",
++ jid="account1@jmc.test.com")
++ self.assertEquals(_account.login, 'testlogin')
++ self.assertEquals(_account.password, 'testpassword')
++ self.assertEquals(_account.host, 'testhost')
++ self.assertEquals(_account.port, 2525)
++ self.assertEquals(_account.tls, True)
++
++ def test_configure_uncomplete_configfile(self):
++ self.runner.config_file = "src/jmc/tests/uncomplete_jmc.conf"
++ self.runner.configure()
++ self.assertEquals(self.runner.server, "test_localhost")
++ self.assertEquals(self.runner.port, 42)
++ self.assertEquals(self.runner.secret, "test_secret")
++ self.assertEquals(self.runner.service_jid, "test_jmc.localhost")
++ self.assertEquals(self.runner.language, "test_en")
++ self.assertEquals(self.runner.db_url, "test_sqlite://root@localhost/var/spool/jabber/test_jmc.db")
++ self.assertEquals(self.runner.pid_file, "/var/run/jabber/test_jmc.pid")
++ self.assertFalse(self.runner.debug)
++ self.assertEquals(self.runner.mail_default_encoding, "test_iso-8859-1")
++ self.assertEquals(self.runner.smtp_default_login, None)
++ self.assertEquals(self.runner.smtp_default_password, None)
++ self.assertEquals(self.runner.smtp_default_host, None)
++ self.assertEquals(self.runner.smtp_default_port, 0)
++ self.assertEquals(self.runner.smtp_default_tls, False)
++ self.assertEquals(self.runner.enable_smtp_default_account, False)
++ self.assertEquals(self.runner.smtp_default_label, None)
++ self.runner.setup_smtp_default()
++ self.assertEquals(Lang.en.type_globalsmtp_name,
++ "Default SMTP Server")
++ _account = GlobalSMTPAccount(user=User(jid="user1@test.com"),
++ name="account1",
++ jid="account1@jmc.test.com")
++ self.assertEquals(_account.login, '')
++ self.assertEquals(_account.password, '')
++ self.assertEquals(_account.host, 'localhost')
++ self.assertEquals(_account.port, 25)
++ self.assertEquals(_account.tls, False)
++
++ def test_configure_commandline_shortopt(self):
++ sys.argv = ["", "-c", "src/jmc/tests/jmc.conf",
++ "-S", "test2_localhost",
++ "-P", "43",
++ "-s", "test2_secret",
++ "-j", "test2_jmc.localhost",
++ "-l", "test2_en",
++ "-u", "sqlite:///tmp/test_jmc.db",
++ "-p", "/tmp/test_jmc.pid",
++ "-e", "test2_iso-8859-1",
++ "-g", "testlogin",
++ "-a", "testpassword",
++ "-t", "testhost",
++ "-r", "2525",
++ "-m", "True",
++ "-n", "True",
++ "-b", "My Global SMTP server"]
++ self.runner.configure()
++ self.assertEquals(self.runner.server, "test2_localhost")
++ self.assertEquals(self.runner.port, 43)
++ self.assertEquals(self.runner.secret, "test2_secret")
++ self.assertEquals(self.runner.service_jid, "test2_jmc.localhost")
++ self.assertEquals(self.runner.language, "test2_en")
++ self.assertEquals(self.runner.db_url, "sqlite:///tmp/test_jmc.db")
++ self.assertEquals(self.runner.pid_file, "/tmp/test_jmc.pid")
++ self.assertFalse(self.runner.debug)
++ self.assertEquals(self.runner.mail_default_encoding, "test2_iso-8859-1")
++ self.assertEquals(self.runner.smtp_default_login, "testlogin")
++ self.assertEquals(self.runner.smtp_default_password, "testpassword")
++ self.assertEquals(self.runner.smtp_default_host, "testhost")
++ self.assertEquals(self.runner.smtp_default_port, 2525)
++ self.assertEquals(self.runner.smtp_default_tls, True)
++ self.assertEquals(self.runner.enable_smtp_default_account, True)
++ self.assertEquals(self.runner.smtp_default_label, "My Global SMTP server")
++ self.runner.setup_smtp_default()
++ self.assertEquals(Lang.en.type_globalsmtp_name,
++ "My Global SMTP server")
++ _account = GlobalSMTPAccount(user=User(jid="user1@test.com"),
++ name="account1",
++ jid="account1@jmc.test.com")
++ self.assertEquals(_account.login, 'testlogin')
++ self.assertEquals(_account.password, 'testpassword')
++ self.assertEquals(_account.host, 'testhost')
++ self.assertEquals(_account.port, 2525)
++ self.assertEquals(_account.tls, True)
++
++ def test_configure_commandline_longopt(self):
++ sys.argv = ["", "--config-file", "src/jmc/tests/jmc.conf",
++ "--server", "test2_localhost",
++ "--port", "43",
++ "--secret", "test2_secret",
++ "--service-jid", "test2_jmc.localhost",
++ "--language", "test2_en",
++ "--db-url", "sqlite:///tmp/test_jmc.db",
++ "--pid-file", "/tmp/test_jmc.pid",
++ "--mail-default-encoding", "test2_iso-8859-1",
++ "--smtp-default-login", "testlogin",
++ "--smtp-default-password", "testpassword",
++ "--smtp-default-host", "testhost",
++ "--smtp-default-port", "2525",
++ "--smtp-default-tls", "True",
++ "--enable-smtp-default-account", "True",
++ "--smtp-default-label", "My Global SMTP server"]
++ self.runner.configure()
++ self.assertEquals(self.runner.server, "test2_localhost")
++ self.assertEquals(self.runner.port, 43)
++ self.assertEquals(self.runner.secret, "test2_secret")
++ self.assertEquals(self.runner.service_jid, "test2_jmc.localhost")
++ self.assertEquals(self.runner.language, "test2_en")
++ self.assertEquals(self.runner.db_url, "sqlite:///tmp/test_jmc.db")
++ self.assertEquals(self.runner.pid_file, "/tmp/test_jmc.pid")
++ self.assertFalse(self.runner.debug)
++ self.assertEquals(self.runner.mail_default_encoding, "test2_iso-8859-1")
++ self.assertEquals(self.runner.smtp_default_login, "testlogin")
++ self.assertEquals(self.runner.smtp_default_password, "testpassword")
++ self.assertEquals(self.runner.smtp_default_host, "testhost")
++ self.assertEquals(self.runner.smtp_default_port, 2525)
++ self.assertEquals(self.runner.smtp_default_tls, True)
++ self.assertEquals(self.runner.enable_smtp_default_account, True)
++ self.assertEquals(self.runner.smtp_default_label, "My Global SMTP server")
++ self.runner.setup_smtp_default()
++ self.assertEquals(Lang.en.type_globalsmtp_name,
++ "My Global SMTP server")
++ _account = GlobalSMTPAccount(user=User(jid="user1@test.com"),
++ name="account1",
++ jid="account1@jmc.test.com")
++ self.assertEquals(_account.login, 'testlogin')
++ self.assertEquals(_account.password, 'testpassword')
++ self.assertEquals(_account.host, 'testhost')
++ self.assertEquals(_account.port, 2525)
++ self.assertEquals(_account.tls, True)
++
++ def test__run(self):
++ self.runner.pid_file = "/tmp/jmc.pid"
++ self.runner.db_url = DB_URL
++ def do_nothing():
++ return (False, 0)
++ self.runner._run(do_nothing)
++ model.db_connection_str = self.runner.db_url
++ model.db_connect()
++ # dropTable should succeed because tables should exist
++ Account.dropTable()
++ PresenceAccount.dropTable()
++ User.dropTable()
++ LegacyJID.dropTable()
++ MailAccount.dropTable()
++ IMAPAccount.dropTable()
++ POP3Account.dropTable()
++ SMTPAccount.dropTable()
++ model.db_disconnect()
++ os.unlink(DB_PATH)
++ self.assertFalse(os.access("/tmp/jmc.pid", os.F_OK))
++
++ def test_run_without_smtp_default_account(self):
++ """ """
++ def run_func(mail_component_self):
++ """ """
++ self.assertEquals(mail_component_self.account_manager.account_classes,
++ (IMAPAccount, POP3Account, SMTPAccount))
++ return (False, 0)
++
++ self.runner.enable_smtp_default_account = False
++ self.runner.pid_file = "/tmp/jmc.pid"
++ self.runner.db_url = DB_URL
++ self.runner.config = None
++ old_run_func = MailComponent.run
++ MailComponent.run = run_func
++ try:
++ self.runner.run()
++ finally:
++ MailComponent.run = old_run_func
++ self.assertFalse(os.access("/tmp/jmc.pid", os.F_OK))
++
++ def test_run_with_smtp_default_account(self):
++ """ """
++ def run_func(mail_component_self):
++ """ """
++ self.assertEquals(mail_component_self.account_manager.account_classes,
++ (IMAPAccount, POP3Account, SMTPAccount,
++ GlobalSMTPAccount))
++ return (False, 0)
++
++ self.runner.enable_smtp_default_account = True
++ self.runner.pid_file = "/tmp/jmc.pid"
++ self.runner.db_url = DB_URL
++ self.runner.config = None
++ old_run_func = MailComponent.run
++ MailComponent.run = run_func
++ try:
++ self.runner.run()
++ finally:
++ MailComponent.run = old_run_func
++ self.assertFalse(os.access("/tmp/jmc.pid", os.F_OK))
++
++def suite():
++ test_suite = unittest.TestSuite()
++ test_suite.addTest(unittest.makeSuite(JMCRunner_TestCase, 'test'))
++ return test_suite
++
++if __name__ == '__main__':
++ unittest.main(defaultTest='suite')
+--- /dev/null
++++ jmc-0.3b3/src/jmc/tests/uncomplete_jmc.conf
+@@ -0,0 +1,23 @@
++[jabber]
++server: test_localhost
++port: 42
++secret: test_secret
++service_jid: test_jmc.localhost
++#supported language: en, fr (See src/jmc/lang.py to add more)
++language: test_en
++
++[db]
++#type: mysql
++type: test_sqlite
++#host: root@localhost
++host: root@localhost
++name: /var/spool/jabber/test_jmc.db
++#url: %(type)%(host)%(name)?debug=1&debugThreading=1
++db_url: %(type)s://%(host)s%(name)s
++
++[component]
++pid_file: /var/run/jabber/test_jmc.pid
++log_file: /tmp/jmc.log
++
++[jmc]
++mail_default_encoding: test_iso-8859-1
+--- /dev/null
++++ jmc-0.3b3/src/jmc/tests/__init__.py
+@@ -0,0 +1,19 @@
++"""JMC test module"""
++__revision__ = ""
++
++import unittest
++
++from jmc.tests import lang, runner
++from jmc.jabber import tests as jabber
++from jmc.model import tests as model
++
++def suite():
++ test_suite = unittest.TestSuite()
++ test_suite.addTest(lang.suite())
++ test_suite.addTest(runner.suite())
++ test_suite.addTest(jabber.suite())
++ test_suite.addTest(model.suite())
++ return test_suite
++
++if __name__ == '__main__':
++ unittest.main(defaultTest='suite')
+--- /dev/null
++++ jmc-0.3b3/src/jmc/tests/lang.py
+@@ -0,0 +1,219 @@
++# -*- coding: utf-8 -*-
++##
++## test_lang.py
++## Login : David Rousselie <david.rousselie@happycoders.org>
++## Started on Fri May 20 10:46:58 2005
++## $Id: test_lang.py,v 1.1 2005/07/11 20:39:31 dax Exp $
++##
++## Copyright (C) 2005
++## This program 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 2 of the License, or
++## (at your option) any later version.
++##
++## This program 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 this program; if not, write to the Free Software
++## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++##
++
++import unittest
++
++import jcl.tests.lang
++
++import jmc.lang
++from jmc.lang import Lang
++
++from pyxmpp.iq import Iq
++
++class Lang_TestCase(unittest.TestCase):
++ def setUp(self):
++ self.lang = Lang()
++
++ def tearDown(self):
++ self.lang = None
++
++ def test_get_lang_class_exist(self):
++ lang_class = self.lang.get_lang_class("fr")
++ self.assertEquals(lang_class, Lang.fr)
++
++ def test_get_lang_class_not_exist(self):
++ lang_class = self.lang.get_lang_class("not_exist")
++ self.assertEquals(lang_class, Lang.en)
++
++ def test_get_lang_class_long_code(self):
++ lang_class = self.lang.get_lang_class("fr_FR")
++ self.assertEquals(lang_class, Lang.fr)
++
++ def test_get_lang_from_node(self):
++ iq = Iq(from_jid = "test@test.com", \
++ to_jid = "test2@test.com", \
++ stanza_type = "get")
++ iq_node = iq.get_node()
++ iq_node.setLang("fr")
++ lang = self.lang.get_lang_from_node(iq_node)
++ self.assertEquals(lang, "fr")
++
++ def test_get_lang_class_from_node(self):
++ iq = Iq(from_jid = "test@test.com", \
++ to_jid = "test2@test.com", \
++ stanza_type = "get")
++ iq_node = iq.get_node()
++ iq_node.setLang("fr")
++ lang = self.lang.get_lang_class_from_node(iq_node)
++ self.assertEquals(lang, Lang.fr)
++
++class Language_TestCase(jcl.tests.lang.Language_TestCase):
++ """Test language classes"""
++
++ def setUp(self):
++ """must define self.lang_class. Lang.en is default"""
++ self.lang_class = Lang.en
++
++ def test_strings(self):
++ jcl.tests.lang.Language_TestCase.test_strings(self)
++
++ self.assertNotEquals(self.lang_class.field_login, None)
++ self.assertNotEquals(self.lang_class.field_host, None)
++ self.assertNotEquals(self.lang_class.field_port, None)
++ self.assertNotEquals(self.lang_class.field_ssl, None)
++ self.assertNotEquals(self.lang_class.field_tls, None)
++ self.assertNotEquals(self.lang_class.field_store_password, None)
++ self.assertNotEquals(self.lang_class.field_live_email_only, None)
++ self.assertNotEquals(self.lang_class.field_interval, None)
++ self.assertNotEquals(self.lang_class.field_mailbox, None)
++
++ self.assertNotEquals(self.lang_class.field_action_1, None)
++ self.assertNotEquals(self.lang_class.field_chat_action_1, None)
++ self.assertNotEquals(self.lang_class.field_online_action_1, None)
++ self.assertNotEquals(self.lang_class.field_away_action_1, None)
++ self.assertNotEquals(self.lang_class.field_xa_action_1, None)
++ self.assertNotEquals(self.lang_class.field_dnd_action_1, None)
++ self.assertNotEquals(self.lang_class.field_offline_action_1, None)
++
++ self.assertNotEquals(self.lang_class.field_action_2, None)
++ self.assertNotEquals(self.lang_class.field_chat_action_2, None)
++ self.assertNotEquals(self.lang_class.field_online_action_2, None)
++ self.assertNotEquals(self.lang_class.field_away_action_2, None)
++ self.assertNotEquals(self.lang_class.field_xa_action_2, None)
++ self.assertNotEquals(self.lang_class.field_dnd_action_2, None)
++ self.assertNotEquals(self.lang_class.field_offline_action_2, None)
++
++ self.assertNotEquals(self.lang_class.field_default_from, None)
++ self.assertNotEquals(self.lang_class.field_default_account, None)
++
++ self.assertNotEquals(self.lang_class.new_mail_subject, None)
++ self.assertNotEquals(self.lang_class.new_digest_subject, None)
++
++ self.assertNotEquals(self.lang_class.type_imap_name, None)
++ self.assertNotEquals(self.lang_class.type_pop3_name, None)
++ self.assertNotEquals(self.lang_class.type_smtp_name, None)
++
++ self.assertNotEquals(self.lang_class.send_mail_error_no_to_header_subject,
++ None)
++ self.assertNotEquals(self.lang_class.send_mail_error_no_to_header_body,
++ None)
++ self.assertNotEquals(self.lang_class.send_mail_ok_subject, None)
++ self.assertNotEquals(self.lang_class.send_mail_ok_body, None)
++ self.assertNotEquals(self.lang_class.help_message_body, None)
++ self.assertNotEquals(self.lang_class.command_force_check, None)
++ self.assertNotEquals(self.lang_class.command_force_check_1_description, None)
++ self.assertNotEquals(self.lang_class.command_get_email, None)
++ self.assertNotEquals(self.lang_class.command_get_email_1_description, None)
++ self.assertNotEquals(self.lang_class.command_get_email_2_description, None)
++ self.assertNotEquals(self.lang_class.field_email_subject, None)
++ self.assertNotEquals(self.lang_class.mail_subject, None)
++ self.assertNotEquals(self.lang_class.field_select_more_emails, None)
++
++class SubLanguage_TestCase(Language_TestCase):
++ """
++ Test translation fallback mecanism :
++ jmc.lang.Lang.{translation class} -> jmc.lang.Lang.en -> jcl.lang.Lang.{translation class} -> jcl.lang.Lang.en
++ """
++
++ def test_fallback_jmc_en(self):
++ """
++ if a translation does not exist in JMC. It falls back to the English
++ translation.
++ """
++ value = self.lang_class.register_title
++ del self.lang_class.register_title
++ self.assertEquals(self.lang_class.register_title,
++ jmc.lang.Lang.en.register_title)
++ self.lang_class.register_title = value
++
++ def test_fallback_jcl_current(self):
++ """
++ if an attribut does not exist in JMC translation class nor in JMC
++ English class, it falls back to the current language in JCL.
++ """
++ lang_class_value = self.lang_class.register_title
++ jmc_lang_en_value = jmc.lang.Lang.en.register_title
++ del self.lang_class.register_title
++ del jmc.lang.Lang.en.register_title
++ self.assertEquals(\
++ self.lang_class.register_title,
++ jcl.lang.Lang.__dict__[self.lang_class.__name__].register_title)
++ jmc.lang.Lang.en.register_title = jmc_lang_en_value
++ self.lang_class.register_title = lang_class_value
++
++ def test_fallback_jcl_en(self):
++ """
++ if an attribut does not exist in JMC and is not translated in JCL,
++ it falls back to English in JCL
++ """
++ lang_class_value = self.lang_class.register_title
++ jmc_lang_en_value = jmc.lang.Lang.en.register_title
++ jcl_lang_class_value = jcl.lang.Lang.__dict__[self.lang_class.__name__].register_title
++ del self.lang_class.register_title
++ del jmc.lang.Lang.en.register_title
++ del jcl.lang.Lang.__dict__[self.lang_class.__name__].register_title
++ self.assertEquals(\
++ self.lang_class.register_title,
++ jcl.lang.Lang.en.register_title)
++ jcl.lang.Lang.__dict__[self.lang_class.__name__].register_title = jcl_lang_class_value
++ jmc.lang.Lang.en.register_title = jmc_lang_en_value
++ self.lang_class.register_title = lang_class_value
++
++class Language_fr_TestCase(SubLanguage_TestCase):
++ def setUp(self):
++ self.lang_class = Lang.fr
++
++class Language_nl_TestCase(Language_TestCase):
++ def setUp(self):
++ self.lang_class = Lang.nl
++
++class Language_es_TestCase(Language_TestCase):
++ def setUp(self):
++ self.lang_class = Lang.es
++
++class Language_pl_TestCase(Language_TestCase):
++ def setUp(self):
++ self.lang_class = Lang.pl
++
++class Language_cs_TestCase(Language_TestCase):
++ def setUp(self):
++ self.lang_class = Lang.cs
++
++class Language_ru_TestCase(Language_TestCase):
++ def setUp(self):
++ self.lang_class = Lang.ru
++
++def suite():
++ suite = unittest.TestSuite()
++ suite.addTest(unittest.makeSuite(Lang_TestCase, 'test'))
++ suite.addTest(unittest.makeSuite(Language_TestCase, 'test'))
++ suite.addTest(unittest.makeSuite(Language_fr_TestCase, 'test'))
++ suite.addTest(unittest.makeSuite(Language_nl_TestCase, 'test'))
++ suite.addTest(unittest.makeSuite(Language_es_TestCase, 'test'))
++ suite.addTest(unittest.makeSuite(Language_pl_TestCase, 'test'))
++ suite.addTest(unittest.makeSuite(Language_cs_TestCase, 'test'))
++ suite.addTest(unittest.makeSuite(Language_ru_TestCase, 'test'))
++ return suite
++
++if __name__ == '__main__':
++ unittest.main(defaultTest='suite')
+--- /dev/null
++++ jmc-0.3b3/src/jmc/tests/jmc.conf
+@@ -0,0 +1,32 @@
++[jabber]
++server: test_localhost
++port: 42
++secret: test_secret
++service_jid: test_jmc.localhost
++#supported language: en, fr (See src/jmc/lang.py to add more)
++language: test_en
++
++[db]
++#type: mysql
++type: test_sqlite
++#host: root@localhost
++host: root@localhost
++name: /var/spool/jabber/test_jmc.db
++#url: %(type)%(host)%(name)?debug=1&debugThreading=1
++db_url: %(type)s://%(host)s%(name)s
++
++[component]
++pid_file: /var/run/jabber/test_jmc.pid
++log_file: /tmp/jmc.log
++
++[jmc]
++mail_default_encoding: test_iso-8859-1
++
++[smtp]
++smtp_default_login: testlogin
++smtp_default_password: testpassword
++smtp_default_host: testhost
++smtp_default_port: 2525
++smtp_default_tls: True
++smtp_default_label: SMTP Server
++enable_smtp_default_account: True
+--- /dev/null
++++ jmc-0.3b3/src/jmc/model/tests/email_generator.py
+@@ -0,0 +1,66 @@
++# -*- coding: utf-8 -*-
++## email_generator.py
++## Login : David Rousselie <david.rousselie@happycoders.org>
++## Started on Tue May 17 15:33:35 2005
++## $Id: email_generator.py,v 1.1 2005/07/11 20:39:31 dax Exp $
++##
++## Copyright (C) 2005
++## This program 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 2 of the License, or
++## (at your option) any later version.
++##
++## This program 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 this program; if not, write to the Free Software
++## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++##
++
++from email.Header import Header
++from email.MIMEText import MIMEText
++from email.MIMEMultipart import MIMEMultipart
++
++def _create_multipart(encoded):
++ msg = MIMEMultipart()
++ if encoded:
++ part1 = MIMEText("utf-8 multipart1 with no charset (éàê)", _charset = "")
++ msg.attach(part1)
++ part2 = MIMEText("Encoded multipart2 with 'iso-8859-15' charset (éàê)", \
++ _charset = "iso-8859-15")
++ msg.attach(part2)
++ part3 = MIMEText("Encoded multipart3 with no charset (éàê)", \
++ _charset = "")
++ msg.attach(part3)
++ else:
++ part1 = MIMEText("Not encoded multipart1")
++ msg.attach(part1)
++ part2 = MIMEText("Not encoded multipart2")
++ msg.attach(part2)
++ return msg
++
++def _create_singlepart(encoded):
++ if encoded:
++ return MIMEText("Encoded single part with 'iso-8859-15' charset (éàê)", \
++ _charset = "iso-8859-15")
++ else:
++ return MIMEText("Not encoded single part")
++
++def generate(encoded, multipart, header):
++ msg = None
++ if multipart:
++ msg = _create_multipart(encoded)
++ else:
++ msg = _create_singlepart(encoded)
++ if header:
++ if encoded:
++ msg['Subject'] = Header("encoded subject (éàê)", "iso-8859-15")
++ msg['From'] = Header("encoded from (éàê)", "iso-8859-15")
++ else:
++ msg['Subject'] = Header("not encoded subject")
++ msg['From'] = Header("not encoded from")
++ return msg
++
+--- /dev/null
++++ jmc-0.3b3/src/jmc/model/tests/account.py
+@@ -0,0 +1,1140 @@
++# -*- coding: utf-8 -*-
++##
++## test_account.py
++## Login : <dax@happycoders.org>
++## Started on Wed Feb 14 08:23:17 2007 David Rousselie
++## $Id$
++##
++## Copyright (C) 2007 David Rousselie
++## This program 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 2 of the License, or
++## (at your option) any later version.
++##
++## This program 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 this program; if not, write to the Free Software
++## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++##
++
++import unittest
++import thread
++
++from jcl.tests import JCLTestCase
++import jcl.model as model
++from jcl.error import FieldError
++from jcl.model.account import Account, PresenceAccount, User
++import jmc.model.account
++from jmc.model.account import MailAccount, POP3Account, IMAPAccount, \
++ GlobalSMTPAccount, AbstractSMTPAccount, SMTPAccount
++from jmc.lang import Lang
++
++from jcl.model.tests.account import Account_TestCase, \
++ PresenceAccount_TestCase, InheritableAccount_TestCase, \
++ ExampleAccount
++from jmc.model.tests import email_generator, server
++
++class AccountModule_TestCase(unittest.TestCase):
++ def test_validate_login_with_empty_login(self):
++ self.assertRaises(FieldError, jmc.model.account.validate_login,
++ None, None, None)
++
++ def test_validate_login_with_login_with_whitespace(self):
++ self.assertRaises(FieldError, jmc.model.account.validate_login,
++ "login with spaces", None, None)
++
++ def test_validate_host_with_empty_login(self):
++ self.assertRaises(FieldError, jmc.model.account.validate_host,
++ None, None, None)
++
++ def test_validate_host_with_host_with_whitespace(self):
++ self.assertRaises(FieldError, jmc.model.account.validate_host,
++ "host with spaces", None, None)
++
++class MailAccount_TestCase(PresenceAccount_TestCase):
++ def setUp(self):
++ PresenceAccount_TestCase.setUp(self, tables=[MailAccount])
++ self.account = MailAccount(user=User(jid="user1@test.com"),
++ name="account1",
++ jid="account1@jmc.test.com")
++ self.account_class = MailAccount
++
++ def make_test(email_type, tested_func, expected_res):
++ def inner(self):
++ encoded, multipart, header = email_type
++ email = email_generator.generate(encoded,
++ multipart,
++ header)
++ part = tested_func(self, email)
++ self.assertEquals(part, expected_res)
++ return inner
++
++ test_get_decoded_part_not_encoded = \
++ make_test((False, False, False), \
++ lambda self, email: \
++ self.account.get_decoded_part(email, None),
++ u"Not encoded single part")
++
++ test_get_decoded_part_encoded = \
++ make_test((True, False, False),
++ lambda self, email: \
++ self.account.get_decoded_part(email, None),
++ u"Encoded single part with 'iso-8859-15' charset (éàê)")
++
++ test_format_message_summary_not_encoded = \
++ make_test((False, False, True),
++ lambda self, email: \
++ self.account.format_message_summary(email),
++ (u"From : not encoded from\nSubject : not encoded subject\n\n",
++ u"not encoded from"))
++
++ test_format_message_summary_encoded = \
++ make_test((True, False, True),
++ lambda self, email: \
++ self.account.format_message_summary(email),
++ (u"From : encoded from (éàê)\nSubject : encoded subject " + \
++ u"(éàê)\n\n",
++ u"encoded from (éàê)"))
++
++ test_format_message_summary_partial_encoded = \
++ make_test((True, False, True),
++ lambda self, email: \
++ email.replace_header("Subject",
++ "\" " + str(email["Subject"]) \
++ + " \" not encoded part") or \
++ email.replace_header("From",
++ "\" " + str(email["From"]) \
++ + " \" not encoded part") or \
++ self.account.format_message_summary(email),
++ (u"From : \"encoded from (éàê)\" not encoded part\nSubject " + \
++ u": \"encoded subject (éàê)\" not encoded part\n\n",
++ u"\"encoded from (éàê)\" not encoded part"))
++
++ test_format_message_single_not_encoded = \
++ make_test((False, False, True),
++ lambda self, email: \
++ self.account.format_message(email),
++ (u"From : not encoded from\nSubject : not encoded subject" + \
++ u"\n\nNot encoded single part\n",
++ u"not encoded from"))
++
++ test_format_message_single_encoded = \
++ make_test((True, False, True),
++ lambda self, email: \
++ self.account.format_message(email),
++ (u"From : encoded from (éàê)\nSubject : encoded subject " + \
++ u"(éàê)\n\nEncoded single part with 'iso-8859-15' charset" + \
++ u" (éàê)\n",
++ u"encoded from (éàê)"))
++
++ test_format_message_multi_not_encoded = \
++ make_test((False, True, True),
++ lambda self, email: \
++ self.account.format_message(email),
++ (u"From : not encoded from\nSubject : not encoded subject" + \
++ u"\n\nNot encoded multipart1\nNot encoded multipart2\n",
++ u"not encoded from"))
++
++ test_format_message_multi_encoded = \
++ make_test((True, True, True),
++ lambda self, email: \
++ self.account.format_message(email),
++ (u"From : encoded from (éàê)\nSubject : encoded subject (éà" + \
++ u"ê)\n\nutf-8 multipart1 with no charset (éàê)" + \
++ u"\nEncoded multipart2 with 'iso-8859-15' charset (éàê)\n" + \
++ u"Encoded multipart3 with no charset (éàê)\n",
++ u"encoded from (éàê)"))
++
++ def test_get_default_status_msg(self):
++ """
++ Get default status message for MailAccount.
++ Should raise NotImplementedError because get_type() method
++ is not implemented
++ """
++ try:
++ self.account.get_default_status_msg(Lang.en)
++ except NotImplementedError:
++ return
++ fail("No NotImplementedError raised")
++
++class POP3Account_TestCase(InheritableAccount_TestCase):
++ def setUp(self):
++ JCLTestCase.setUp(self, tables=[Account, PresenceAccount, User,
++ MailAccount, POP3Account])
++ self.pop3_account = POP3Account(user=User(jid="user1@test.com"),
++ name="account1",
++ jid="account1@jmc.test.com",
++ login="login")
++ self.pop3_account.password = "pass"
++ self.pop3_account.host = "localhost"
++ self.pop3_account.port = 1110
++ self.pop3_account.ssl = False
++ model.db_disconnect()
++ self.account_class = POP3Account
++
++ def make_test(responses=None, queries=None, core=None):
++ def inner(self):
++ self.server = server.DummyServer("localhost", 1110)
++ thread.start_new_thread(self.server.serve, ())
++ self.server.responses = ["+OK connected\r\n",
++ "+OK name is a valid mailbox\r\n",
++ "+OK pass\r\n"]
++ if responses:
++ self.server.responses += responses
++ self.server.queries = ["USER login\r\n",
++ "PASS pass\r\n"]
++ if queries:
++ self.server.queries += queries
++ self.server.queries += ["QUIT\r\n"]
++ self.pop3_account.connect()
++ self.failUnless(self.pop3_account.connection,
++ "Cannot establish connection")
++ if core:
++ model.db_connect()
++ core(self)
++ model.db_disconnect()
++ self.pop3_account.disconnect()
++ self.failUnless(self.server.verify_queries(),
++ "Sended queries does not match expected queries.")
++ return inner
++
++ test_connection = make_test
++
++ test_get_mail_list_summary = \
++ make_test(["+OK 2 20\r\n",
++ "+OK 10 octets\r\n" + \
++ "From: user@test.com\r\n" + \
++ "Subject: mail subject 1\r\n.\r\n",
++ "+OK 10 octets\r\n" + \
++ "From: user@test.com\r\n" + \
++ "Subject: mail subject 2\r\n.\r\n",
++ "+OK\r\n"],
++ ["STAT\r\n",
++ "TOP 1 0\r\n",
++ "TOP 2 0\r\n",
++ "RSET\r\n"],
++ lambda self: \
++ self.assertEquals(self.pop3_account.get_mail_list_summary(),
++ [("1", "mail subject 1"),
++ ("2", "mail subject 2")]))
++
++ test_get_mail_list_summary_start_index = \
++ make_test(["+OK 3 30\r\n",
++ "+OK 10 octets\r\n" + \
++ "From: user@test.com\r\n" + \
++ "Subject: mail subject 2\r\n.\r\n",
++ "+OK 10 octets\r\n" + \
++ "From: user@test.com\r\n" + \
++ "Subject: mail subject 3\r\n.\r\n",
++ "+OK\r\n"],
++ ["STAT\r\n",
++ "TOP 2 0\r\n",
++ "TOP 3 0\r\n",
++ "RSET\r\n"],
++ lambda self: \
++ self.assertEquals(self.pop3_account.get_mail_list_summary(start_index=2),
++ [("2", "mail subject 2"),
++ ("3", "mail subject 3")]))
++
++ test_get_mail_list_summary_end_index = \
++ make_test(["+OK 3 30\r\n",
++ "+OK 10 octets\r\n" + \
++ "From: user@test.com\r\n" + \
++ "Subject: mail subject 1\r\n.\r\n",
++ "+OK 10 octets\r\n" + \
++ "From: user@test.com\r\n" + \
++ "Subject: mail subject 2\r\n.\r\n",
++ "+OK\r\n"],
++ ["STAT\r\n",
++ "TOP 1 0\r\n",
++ "TOP 2 0\r\n",
++ "RSET\r\n"],
++ lambda self: \
++ self.assertEquals(self.pop3_account.get_mail_list_summary(end_index=2),
++ [("1", "mail subject 1"),
++ ("2", "mail subject 2")]))
++
++ test_get_new_mail_list = \
++ make_test(["+OK 2 20\r\n"],
++ ["STAT\r\n"],
++ lambda self: \
++ self.assertEquals(self.pop3_account.get_new_mail_list(),
++ ["1", "2"]))
++
++ test_get_mail_summary = \
++ make_test(["+OK 10 octets\r\n" + \
++ "From: user@test.com\r\n" + \
++ "Subject: subject test\r\n\r\n" + \
++ "mymessage\r\n.\r\n",
++ "+OK\r\n"],
++ ["RETR 1\r\n",
++ "RSET\r\n"],
++ lambda self: \
++ self.assertEquals(self.pop3_account.get_mail_summary(1),
++ (u"From : user@test.com\n" + \
++ u"Subject : subject test\n\n",
++ u"user@test.com")))
++
++ test_get_mail = \
++ make_test(["+OK 10 octets\r\n" + \
++ "From: user@test.com\r\n" + \
++ "Subject: subject test\r\n\r\n" + \
++ "mymessage\r\n.\r\n",
++ "+OK\r\n"],
++ ["RETR 1\r\n",
++ "RSET\r\n"],
++ lambda self: \
++ self.assertEquals(self.pop3_account.get_mail(1),
++ (u"From : user@test.com\n" + \
++ u"Subject : subject test\n\n" + \
++ u"mymessage\n",
++ u"user@test.com")))
++
++ test_unsupported_reset_command_get_mail_summary = \
++ make_test(["+OK 10 octets\r\n" + \
++ "From: user@test.com\r\n" + \
++ "Subject: subject test\r\n\r\n" + \
++ "mymessage\r\n.\r\n",
++ "-ERR unknown command\r\n"],
++ ["RETR 1\r\n",
++ "RSET\r\n"],
++ lambda self: \
++ self.assertEquals(self.pop3_account.get_mail_summary(1),
++ (u"From : user@test.com\n" + \
++ u"Subject : subject test\n\n",
++ u"user@test.com")))
++
++ test_unsupported_reset_command_get_mail = \
++ make_test(["+OK 10 octets\r\n" + \
++ "From: user@test.com\r\n" + \
++ "Subject: subject test\r\n\r\n" + \
++ "mymessage\r\n.\r\n",
++ "-ERR unknown command\r\n"],
++ ["RETR 1\r\n",
++ "RSET\r\n"],
++ lambda self: \
++ self.assertEquals(self.pop3_account.get_mail(1),
++ (u"From : user@test.com\n" + \
++ u"Subject : subject test\n\n" + \
++ u"mymessage\n",
++ u"user@test.com")))
++
++ def test_get_next_mail_index_empty(self):
++ """
++ Test get_next_mail_index with empty mail_list parameter.
++ """
++ mail_list = []
++ self.pop3_account.nb_mail = 0
++ self.pop3_account.lastmail = 0
++ result = []
++ for elt in self.pop3_account.get_next_mail_index(mail_list):
++ result.append(elt)
++ self.assertEquals(result, [])
++
++ def test_get_next_mail_index(self):
++ """
++ Test get_next_mail_index first check.
++ """
++ mail_list = [1, 2, 3, 4]
++ self.pop3_account.nb_mail = 4
++ self.pop3_account.lastmail = 0
++ result = []
++ for elt in self.pop3_account.get_next_mail_index(mail_list):
++ result.append(elt)
++ self.assertEquals(result, [1, 2, 3, 4])
++ self.assertEquals(self.pop3_account.lastmail, 4)
++
++ def test_get_next_mail_index_second_check(self):
++ """
++ Test get_next_mail_index second check (no parallel checking).
++ """
++ mail_list = [1, 2, 3, 4, 5, 6, 7, 8]
++ self.pop3_account.nb_mail = 8
++ self.pop3_account.lastmail = 4
++ result = []
++ for elt in self.pop3_account.get_next_mail_index(mail_list):
++ result.append(elt)
++ self.assertEquals(result, [5, 6, 7, 8])
++ self.assertEquals(self.pop3_account.lastmail, 8)
++
++ def test_get_next_mail_index_second_check_parallel_check(self):
++ """
++ Test get_next_mail_index second check (with parallel checking
++ but not more new emails than last index jmc stopped:
++ 3 new emails after another client checked emails).
++ """
++ mail_list = [1, 2, 3]
++ self.pop3_account.nb_mail = 3
++ self.pop3_account.lastmail = 4
++ result = []
++ for elt in self.pop3_account.get_next_mail_index(mail_list):
++ result.append(elt)
++ self.assertEquals(result, [1, 2, 3])
++ self.assertEquals(self.pop3_account.lastmail, 3)
++
++ def test_get_next_mail_index_second_check_bug_parallel_check(self):
++ """
++ Test get_next_mail_index second check (with parallel checking
++ but with more new emails than last index jmc stopped:
++ 5 new emails after another client checked emails). Cannot make
++ the difference with one new email since last jmc email check!!
++ """
++ mail_list = [1, 2, 3, 4, 5]
++ self.pop3_account.nb_mail = 5
++ self.pop3_account.lastmail = 4
++ result = []
++ for elt in self.pop3_account.get_next_mail_index(mail_list):
++ result.append(elt)
++ # with no bug it should be:
++ # self.assertEquals(result, [1, 2, 3, 4, 5])
++ self.assertEquals(result, [5])
++ self.assertEquals(self.pop3_account.lastmail, 5)
++
++ def test_get_default_status_msg(self):
++ """
++ Get default status message for POP3Account.
++ """
++ status_msg = self.pop3_account.get_default_status_msg(Lang.en)
++ self.assertEquals(status_msg, "pop3://login@localhost:1110")
++
++ def test_get_default_status_msg_ssl(self):
++ """
++ Get default status message for SSL POP3Account.
++ """
++ self.pop3_account.ssl = True
++ status_msg = self.pop3_account.get_default_status_msg(Lang.en)
++ self.assertEquals(status_msg, "pop3s://login@localhost:1110")
++
++class IMAPAccount_TestCase(InheritableAccount_TestCase):
++ def setUp(self):
++ JCLTestCase.setUp(self, tables=[Account, PresenceAccount, User,
++ MailAccount, IMAPAccount])
++ self.imap_account = IMAPAccount(user=User(jid="user1@test.com"),
++ name="account1",
++ jid="account1@jmc.test.com",
++ login="login")
++ self.imap_account.password = "pass"
++ self.imap_account.host = "localhost"
++ self.imap_account.port = 1143
++ self.imap_account.ssl = False
++ self.account_class = IMAPAccount
++
++ def make_test(self, responses=None, queries=None, core=None):
++ def inner():
++ self.server = server.DummyServer("localhost", 1143)
++ thread.start_new_thread(self.server.serve, ())
++ self.server.responses = ["* OK [CAPABILITY IMAP4 LOGIN-REFERRALS " + \
++ "AUTH=PLAIN]\r\n", \
++ lambda data: "* CAPABILITY IMAP4 " + \
++ "LOGIN-REFERRALS AUTH=PLAIN\r\n" + \
++ data.split()[0] + \
++ " OK CAPABILITY completed\r\n", \
++ lambda data: data.split()[0] + \
++ " OK LOGIN completed\r\n"]
++ if responses:
++ self.server.responses += responses
++ self.server.queries = ["^[^ ]* CAPABILITY", \
++ "^[^ ]* LOGIN login \"pass\""]
++ if queries:
++ self.server.queries += queries
++ self.server.queries += ["^[^ ]* LOGOUT"]
++ if not self.imap_account.connected:
++ self.imap_account.connect()
++ self.failUnless(self.imap_account.connection, \
++ "Cannot establish connection")
++ if core:
++ model.db_connect()
++ core(self)
++ model.db_disconnect()
++ if self.imap_account.connected:
++ self.imap_account.disconnect()
++ self.failUnless(self.server.verify_queries())
++ return inner
++
++ def test_connection(self):
++ test_func = self.make_test()
++ test_func()
++
++ def test_get_mail_list_summary(self):
++ test_func = self.make_test(\
++ [lambda data: "* 42 EXISTS\r\n* 1 RECENT\r\n* OK" +\
++ " [UNSEEN 9]\r\n* FLAGS (\Deleted \Seen\*)\r\n*" +\
++ " OK [PERMANENTFLAGS (\Deleted \Seen\*)\r\n" + \
++ data.split()[0] + \
++ " OK [READ-WRITE] SELECT completed\r\n",
++ lambda data: "* 1 FETCH ((RFC822.header) {38}\r\n" + \
++ "Subject: mail subject 1\r\n\r\nbody text\r\n)\r\n" + \
++ "* 2 FETCH ((RFC822.header) {38}\r\n" + \
++ "Subject: mail subject 2\r\n\r\nbody text\r\n)\r\n" + \
++ data.split()[0] + " OK FETCH completed\r\n"],
++ ["^[^ ]* EXAMINE INBOX",
++ "^[^ ]* FETCH 1:20 RFC822.header"],
++ lambda self: \
++ self.assertEquals(self.imap_account.get_mail_list_summary(),
++ [('1', 'mail subject 1'),
++ ('2', 'mail subject 2')]))
++ test_func()
++
++ def test_get_mail_list_summary_inbox_does_not_exist(self):
++ self.__test_select_inbox_does_not_exist(\
++ lambda: self.imap_account.get_mail_list_summary(), readonly=True)
++
++ def test_get_mail_list_summary_start_index(self):
++ test_func = self.make_test(\
++ [lambda data: "* 42 EXISTS\r\n* 1 RECENT\r\n* OK" +\
++ " [UNSEEN 9]\r\n* FLAGS (\Deleted \Seen\*)\r\n*" +\
++ " OK [PERMANENTFLAGS (\Deleted \Seen\*)\r\n" + \
++ data.split()[0] + \
++ " OK [READ-WRITE] SELECT completed\r\n",
++ lambda data: "* 2 FETCH ((RFC822.header) {38}\r\n" + \
++ "Subject: mail subject 2\r\n\r\nbody text\r\n)\r\n" + \
++ "* 3 FETCH ((RFC822.header) {38}\r\n" + \
++ "Subject: mail subject 3\r\n\r\nbody text\r\n)\r\n" + \
++ data.split()[0] + " OK FETCH completed\r\n"],
++ ["^[^ ]* EXAMINE INBOX",
++ "^[^ ]* FETCH 2:20 RFC822.header"],
++ lambda self: \
++ self.assertEquals(self.imap_account.get_mail_list_summary(start_index=2),
++ [('2', 'mail subject 2'),
++ ('3', 'mail subject 3')]))
++ test_func()
++
++ def test_get_mail_list_summary_end_index(self):
++ test_func = self.make_test(\
++ [lambda data: "* 42 EXISTS\r\n* 1 RECENT\r\n* OK" +\
++ " [UNSEEN 9]\r\n* FLAGS (\Deleted \Seen\*)\r\n*" +\
++ " OK [PERMANENTFLAGS (\Deleted \Seen\*)\r\n" + \
++ data.split()[0] + \
++ " OK [READ-WRITE] SELECT completed\r\n",
++ lambda data: "* 1 FETCH ((RFC822.header) {38}\r\n" + \
++ "Subject: mail subject 1\r\n\r\nbody text\r\n)\r\n" + \
++ "* 2 FETCH ((RFC822.header) {38}\r\n" + \
++ "Subject: mail subject 2\r\n\r\nbody text\r\n)\r\n" + \
++ data.split()[0] + " OK FETCH completed\r\n"],
++ ["^[^ ]* EXAMINE INBOX",
++ "^[^ ]* FETCH 1:2 RFC822.header"],
++ lambda self: \
++ self.assertEquals(self.imap_account.get_mail_list_summary(end_index=2),
++ [('1', 'mail subject 1'),
++ ('2', 'mail subject 2')]))
++ test_func()
++
++ def test_get_new_mail_list(self):
++ test_func = self.make_test(\
++ [lambda data: "* 42 EXISTS\r\n* 1 RECENT\r\n* OK" + \
++ " [UNSEEN 9]\r\n* FLAGS (\Deleted \Seen\*)\r\n*" + \
++ " OK [PERMANENTFLAGS (\Deleted \Seen\*)\r\n" + \
++ data.split()[0] + \
++ " OK [READ-WRITE] SELECT completed\r\n",
++ lambda data: "* SEARCH 9 10\r\n" + \
++ data.split()[0] + " OK SEARCH completed\r\n"],
++ ["^[^ ]* SELECT INBOX",
++ "^[^ ]* SEARCH RECENT"],
++ lambda self: \
++ self.assertEquals(self.imap_account.get_new_mail_list(),
++ ['9', '10']))
++ test_func()
++
++ def __test_select_inbox_does_not_exist(self, tested_func,
++ exception_message="Mailbox does not exist",
++ readonly=False):
++ def check_func(self):
++ try:
++ tested_func()
++ except Exception, e:
++ self.assertEquals(str(e), exception_message)
++ return
++ self.fail("No exception raised when selecting non existing mailbox")
++ test_func = self.make_test(\
++ [lambda data: "* 42 EXISTS\r\n* 1 RECENT\r\n* OK" + \
++ " [UNSEEN 9]\r\n* FLAGS (\Deleted \Seen\*)\r\n*" + \
++ " OK [PERMANENTFLAGS (\Deleted \Seen\*)\r\n" + \
++ data.split()[0] + \
++ " NO Mailbox does not exist\r\n"],
++ ["^[^ ]* " + (readonly and "EXAMINE" or "SELECT") + " INBOX"],
++ check_func)
++ test_func()
++
++ def test_get_new_mail_list_inbox_does_not_exist(self):
++ self.__test_select_inbox_does_not_exist(\
++ lambda: self.imap_account_get_new_mail_list())
++
++ def test_get_new_mail_list_delimiter1(self):
++ self.imap_account.mailbox = "INBOX/dir1/subdir2"
++ self.imap_account.delimiter = "."
++ test_func = self.make_test( \
++ [lambda data: "* 42 EXISTS\r\n* 1 RECENT\r\n* OK" + \
++ " [UNSEEN 9]\r\n* FLAGS (\Deleted \Seen\*)\r\n*" + \
++ " OK [PERMANENTFLAGS (\Deleted \Seen\*)\r\n" + \
++ data.split()[0] + \
++ " OK [READ-WRITE] SELECT completed\r\n",
++ lambda data: "* SEARCH 9 10\r\n" + \
++ data.split()[0] + " OK SEARCH completed\r\n"],
++ ["^[^ ]* SELECT \"?INBOX\.dir1\.subdir2\"?",
++ "^[^ ]* SEARCH RECENT"],
++ lambda self: \
++ self.assertEquals(self.imap_account.get_new_mail_list(),
++ ['9', '10']))
++ test_func()
++
++ def test_get_new_mail_list_delimiter2(self):
++ self.imap_account.mailbox = "INBOX/dir1/subdir2"
++ self.imap_account.delimiter = "/"
++ test_func = self.make_test( \
++ [lambda data: "* 42 EXISTS\r\n* 1 RECENT\r\n* OK" + \
++ " [UNSEEN 9]\r\n* FLAGS (\Deleted \Seen\*)\r\n*" + \
++ " OK [PERMANENTFLAGS (\Deleted \Seen\*)\r\n" + \
++ data.split()[0] + \
++ " OK [READ-WRITE] SELECT completed\r\n",
++ lambda data: "* SEARCH 9 10\r\n" + \
++ data.split()[0] + " OK SEARCH completed\r\n"],
++ ["^[^ ]* SELECT \"?INBOX/dir1/subdir2\"?",
++ "^[^ ]* SEARCH RECENT"],
++ lambda self: \
++ self.assertEquals(self.imap_account.get_new_mail_list(),
++ ['9', '10']))
++ test_func()
++
++ def test_get_mail_summary(self):
++ test_func = self.make_test(\
++ [lambda data: "* 42 EXISTS\r\n* 1 RECENT\r\n* OK" +\
++ " [UNSEEN 9]\r\n* FLAGS (\Deleted \Seen\*)\r\n*" +\
++ " OK [PERMANENTFLAGS (\Deleted \Seen\*)\r\n" + \
++ data.split()[0] + \
++ " OK [READ-WRITE] SELECT completed\r\n",
++ lambda data: "* 1 FETCH ((RFC822) {12}\r\nbody" + \
++ " text\r\n)\r\n" + \
++ data.split()[0] + " OK FETCH completed\r\n"],
++ ["^[^ ]* EXAMINE INBOX",
++ "^[^ ]* FETCH 1 \(RFC822.header\)"],
++ lambda self: \
++ self.assertEquals(self.imap_account.get_mail_summary(1),
++ (u"From : None\nSubject : None\n\n",
++ u"None")))
++ test_func()
++
++ def test_get_mail_summary_inbox_does_not_exist(self):
++ self.__test_select_inbox_does_not_exist(\
++ lambda: self.imap_account.get_mail_summary(1),
++ "Mailbox does not exist (email 1)", True)
++
++ def test_get_new_mail_list_inbox_does_not_exist(self):
++ def check_func(self):
++ try:
++ self.imap_account.get_new_mail_list()
++ except Exception, e:
++ self.assertEquals(str(e), "Mailbox does not exist")
++ return
++ self.fail("No exception raised when selecting non existing mailbox")
++ test_func = self.make_test(\
++ [lambda data: "* 42 EXISTS\r\n* 1 RECENT\r\n* OK" + \
++ " [UNSEEN 9]\r\n* FLAGS (\Deleted \Seen\*)\r\n*" + \
++ " OK [PERMANENTFLAGS (\Deleted \Seen\*)\r\n" + \
++ data.split()[0] + \
++ " NO Mailbox does not exist\r\n"],
++ ["^[^ ]* SELECT INBOX"],
++ check_func)
++ test_func()
++
++ def test_get_mail_summary_delimiter(self):
++ self.imap_account.mailbox = "INBOX/dir1/subdir2"
++ self.imap_account.delimiter = "."
++ test_func = self.make_test(\
++ [lambda data: "* 42 EXISTS\r\n* 1 RECENT\r\n* OK" +\
++ " [UNSEEN 9]\r\n* FLAGS (\Deleted \Seen\*)\r\n*" +\
++ " OK [PERMANENTFLAGS (\Deleted \Seen\*)\r\n" + \
++ data.split()[0] + \
++ " OK [READ-WRITE] SELECT completed\r\n",
++ lambda data: "* 1 FETCH ((RFC822) {12}\r\nbody" + \
++ " text\r\n)\r\n" + \
++ data.split()[0] + " OK FETCH completed\r\n"],
++ ["^[^ ]* EXAMINE \"?INBOX\.dir1\.subdir2\"?",
++ "^[^ ]* FETCH 1 \(RFC822.header\)"],
++ lambda self: \
++ self.assertEquals(self.imap_account.get_mail_summary(1),
++ (u"From : None\nSubject : None\n\n",
++ u"None")))
++ test_func()
++
++ def test_get_mail(self):
++ test_func = self.make_test(\
++ [lambda data: "* 42 EXISTS\r\n* 1 RECENT\r\n* OK" + \
++ " [UNSEEN 9]\r\n* FLAGS (\Deleted \Seen\*)\r\n*" + \
++ " OK [PERMANENTFLAGS (\Deleted \Seen\*)\r\n" + \
++ data.split()[0] + \
++ " OK [READ-WRITE] SELECT completed\r\n",
++ lambda data: "* 1 FETCH ((RFC822) {11}\r\nbody" + \
++ " text\r\n)\r\n" + \
++ data.split()[0] + " OK FETCH completed\r\n"],
++ ["^[^ ]* EXAMINE INBOX",
++ "^[^ ]* FETCH 1 \(RFC822\)"],
++ lambda self: \
++ self.assertEquals(self.imap_account.get_mail(1),
++ (u"From : None\nSubject : None\n\nbody text\r\n\n",
++ u"None")))
++ test_func()
++
++ def test_get_mail_inbox_does_not_exist(self):
++ self.__test_select_inbox_does_not_exist(\
++ lambda: self.imap_account.get_mail(1),
++ "Mailbox does not exist (email 1)", True)
++
++ def test_get_mail_delimiter(self):
++ self.imap_account.mailbox = "INBOX/dir1/subdir2"
++ self.imap_account.delimiter = "."
++ test_func = self.make_test(\
++ [lambda data: "* 42 EXISTS\r\n* 1 RECENT\r\n* OK" + \
++ " [UNSEEN 9]\r\n* FLAGS (\Deleted \Seen\*)\r\n*" + \
++ " OK [PERMANENTFLAGS (\Deleted \Seen\*)\r\n" + \
++ data.split()[0] + \
++ " OK [READ-WRITE] SELECT completed\r\n",
++ lambda data: "* 1 FETCH ((RFC822) {11}\r\nbody" + \
++ " text\r\n)\r\n" + \
++ data.split()[0] + " OK FETCH completed\r\n"],
++ ["^[^ ]* EXAMINE \"?INBOX\.dir1\.subdir2\"?",
++ "^[^ ]* FETCH 1 \(RFC822\)"],
++ lambda self: \
++ self.assertEquals(self.imap_account.get_mail(1),
++ (u"From : None\nSubject : None\n\nbody text\r\n\n",
++ u"None")))
++ test_func()
++
++ def test_build_folder_cache(self):
++ test_func = self.make_test(\
++ [lambda data: '* LIST () "." "INBOX"\r\n' + \
++ '* LIST () "." "INBOX.dir1"\r\n' + \
++ '* LIST () "." "INBOX.dir1.subdir1"\r\n' + \
++ '* LIST () "." "INBOX.dir1.subdir2"\r\n' + \
++ '* LIST () "." "INBOX.dir2"\r\n' + \
++ data.split()[0] + ' OK LIST completed\r\n'],
++ ["^[^ ]* LIST \"\" \*"],
++ lambda self: self.assertEquals(self.imap_account._build_folder_cache(),
++ {"INBOX":
++ {"dir1":
++ {"subdir1": {},
++ "subdir2": {}},
++ "dir2": {}}}))
++ test_func()
++
++ def test_ls_dir_base(self):
++ self.test_build_folder_cache()
++ self.assertEquals(self.imap_account.ls_dir(""),
++ ["INBOX"])
++
++ def test_ls_dir_subdir(self):
++ self.test_build_folder_cache()
++ result = self.imap_account.ls_dir("INBOX")
++ result.sort()
++ self.assertEquals(result,
++ ["dir1", "dir2"])
++
++ def test_ls_dir_subsubdir_delim1(self):
++ self.test_build_folder_cache()
++ self.imap_account.default_delimiter = "."
++ result = self.imap_account.ls_dir("INBOX/dir1")
++ result.sort()
++ self.assertEquals(result,
++ ["subdir1", "subdir2"])
++
++ def test_ls_dir_subsubdir_delim2(self):
++ self.test_build_folder_cache()
++ result = self.imap_account.ls_dir("INBOX/dir1")
++ result.sort()
++ self.assertEquals(result,
++ ["subdir1", "subdir2"])
++
++ def test_populate_handler(self):
++ self.assertEquals(".", self.imap_account.delimiter)
++ self.imap_account.mailbox = "INBOX/dir1/subdir2"
++ def call_func(self):
++ self.imap_account.populate_handler()
++ self.assertEquals("INBOX.dir1.subdir2", self.imap_account.mailbox)
++ test_func = self.make_test(\
++ [lambda data: '* LIST () "." "INBOX.dir1.subdir2"\r\n' + \
++ data.split()[0] + ' OK LIST completed\r\n'],
++ ["^[^ ]* LIST \"?INBOX.dir1.subdir2\"? \*"],
++ call_func)
++ test_func()
++
++ def test_populate_handler_wrong_default_delimiter(self):
++ self.imap_account.delimiter = "/"
++ self.imap_account.mailbox = "INBOX/dir1/subdir2"
++ def call_func(self):
++ self.imap_account.populate_handler()
++ self.assertEquals("INBOX.dir1.subdir2", self.imap_account.mailbox)
++ self.assertEquals(".", self.imap_account.delimiter)
++ test_func = self.make_test(\
++ [lambda data: data.split()[0] + ' OK LIST completed\r\n',
++ lambda data: '* LIST () "." "INBOX.dir1.subdir2"\r\n' + \
++ data.split()[0] + ' OK LIST completed\r\n'],
++ ["^[^ ]* LIST \"?INBOX/dir1/subdir2\"? \*",
++ "^[^ ]* LIST \"?INBOX.dir1.subdir2\"? \*"],
++ call_func)
++ test_func()
++
++ def test_populate_handler_wrong_mailbox(self):
++ self.assertEquals(".", self.imap_account.delimiter)
++ self.imap_account.mailbox = "INBOX.dir1.subdir2"
++ def call_func(self):
++ try:
++ self.imap_account.populate_handler()
++ except Exception, e:
++ return
++ self.fail("Exception should have been raised")
++ test_func = self.make_test(\
++ [lambda data: data.split()[0] + ' ERR LIST completed\r\n'],
++ ["^[^ ]* LIST \"?INBOX.dir1.subdir2\"? \*"],
++ call_func)
++ test_func()
++
++ def check_get_next_mail_index(self, mail_list):
++ """
++ Common tests for get_next_mail_index method.
++ """
++ result = []
++ original_mail_list = [elt for elt in mail_list]
++ for elt in self.imap_account.get_next_mail_index(mail_list):
++ result.append(elt)
++ self.assertEquals(mail_list, [])
++ self.assertEquals(result, original_mail_list)
++
++ def test_get_next_mail_index_empty(self):
++ """
++ Test get_next_mail_index with empty mail_list parameter.
++ """
++ mail_list = []
++ self.check_get_next_mail_index(mail_list)
++
++ def test_get_next_mail_index(self):
++ """
++ Test get_next_mail_index.
++ """
++ mail_list = [1, 2, 3, 4]
++ self.check_get_next_mail_index(mail_list)
++
++ def test_get_default_status_msg(self):
++ """
++ Get default status message for IMAPAccount.
++ """
++ status_msg = self.imap_account.get_default_status_msg(Lang.en)
++ self.assertEquals(status_msg, "imap://login@localhost:1143")
++
++ def test_get_default_status_msg_ssl(self):
++ """
++ Get default status message for SSL IMAPAccount.
++ """
++ self.imap_account.ssl = True
++ status_msg = self.imap_account.get_default_status_msg(Lang.en)
++ self.assertEquals(status_msg, "imaps://login@localhost:1143")
++
++class AbstractSMTPAccount_TestCase(Account_TestCase):
++ def setUp(self):
++ JCLTestCase.setUp(self, tables=[Account, ExampleAccount, User,
++ GlobalSMTPAccount, AbstractSMTPAccount])
++ self.account_class = AbstractSMTPAccount
++
++ def test_default_account_post_func_no_default_true(self):
++ user1 = User(jid="user1@test.com")
++ account11 = AbstractSMTPAccount(user=user1,
++ name="account11",
++ jid="account11@jmc.test.com")
++ account12 = AbstractSMTPAccount(user=user1,
++ name="account12",
++ jid="account12@jmc.test.com")
++ (name, field_type, field_options, post_func, default_func) = \
++ AbstractSMTPAccount.get_register_fields()[0]
++ value = post_func("True", None, "user1@test.com")
++ self.assertTrue(value)
++
++ def test_default_account_post_func_no_default_false(self):
++ user1 = User(jid="user1@test.com")
++ account11 = AbstractSMTPAccount(user=user1,
++ name="account11",
++ jid="account11@jmc.test.com")
++ account12 = AbstractSMTPAccount(user=user1,
++ name="account12",
++ jid="account12@jmc.test.com")
++ (name, field_type, field_options, post_func, default_func) = \
++ AbstractSMTPAccount.get_register_fields()[0]
++ value = post_func("False", None, "user1@test.com")
++ self.assertTrue(value)
++
++ def test_default_account_post_func_true(self):
++ user1 = User(jid="user1@test.com")
++ account11 = AbstractSMTPAccount(user=user1,
++ name="account11",
++ jid="account11@jmc.test.com")
++ account12 = AbstractSMTPAccount(user=user1,
++ name="account12",
++ jid="account12@jmc.test.com")
++ account12.default_account = True
++ (name, field_type, field_options, post_func, default_func) = \
++ AbstractSMTPAccount.get_register_fields()[0]
++ value = post_func("True", None, "user1@test.com")
++ self.assertTrue(value)
++ self.assertFalse(account12.default_account)
++
++ def test_default_account_post_func_false(self):
++ user1 = User(jid="user1@test.com")
++ account11 = AbstractSMTPAccount(user=user1,
++ name="account11",
++ jid="account11@jmc.test.com")
++ account12 = AbstractSMTPAccount(user=user1,
++ name="account12",
++ jid="account12@jmc.test.com")
++ account12.default_account = True
++ (name, field_type, field_options, post_func, default_func) = \
++ AbstractSMTPAccount.get_register_fields()[0]
++ value = post_func("False", None, "user1@test.com")
++ self.assertFalse(value)
++ self.assertTrue(account12.default_account)
++
++ def test_create_email(self):
++ account11 = AbstractSMTPAccount(user=User(jid="user1@test.com"),
++ name="account11",
++ jid="account11@jmc.test.com")
++ email = account11.create_email("from@test.com",
++ "to@test.com",
++ "subject",
++ "body")
++ self.assertEqual(email['From'], "from@test.com")
++ self.assertEqual(email['To'], "to@test.com")
++ self.assertEqual(email['Subject'], "subject")
++ self.assertEqual(email.get_payload(), "body")
++
++ def test_create_email_other_headers(self):
++ account11 = AbstractSMTPAccount(user=User(jid="user1@test.com"),
++ name="account11",
++ jid="account11@jmc.test.com")
++ email = account11.create_email("from@test.com",
++ "to@test.com",
++ "subject",
++ "body",
++ {"Bcc": "bcc@test.com",
++ "Cc": "cc@test.com"})
++ self.assertEqual(email['From'], "from@test.com")
++ self.assertEqual(email['To'], "to@test.com")
++ self.assertEqual(email['Subject'], "subject")
++ self.assertEqual(email['Bcc'], "bcc@test.com")
++ self.assertEqual(email['Cc'], "cc@test.com")
++ self.assertEqual(email.get_payload(), "body")
++
++class SMTPAccount_TestCase(Account_TestCase):
++ def setUp(self):
++ JCLTestCase.setUp(self, tables=[Account, ExampleAccount, User,
++ GlobalSMTPAccount,
++ AbstractSMTPAccount, SMTPAccount])
++ self.account_class = SMTPAccount
++
++ def make_test(self, responses=None, queries=None, core=None):
++ def inner():
++ self.server = server.DummyServer("localhost", 1025)
++ thread.start_new_thread(self.server.serve, ())
++ self.server.responses = []
++ if responses:
++ self.server.responses += responses
++ self.server.responses += ["221 localhost closing connection\r\n"]
++ self.server.queries = []
++ if queries:
++ self.server.queries += queries
++ self.server.queries += ["quit\r\n"]
++ if core:
++ model.db_connect()
++ core(self)
++ model.db_disconnect()
++ self.failUnless(self.server.verify_queries())
++ return inner
++
++ def test_send_email_esmtp_no_auth(self):
++ model.db_connect()
++ smtp_account = SMTPAccount(user=User(jid="user1@test.com"),
++ name="account11",
++ jid="account11@jmc.test.com")
++ smtp_account.host = "localhost"
++ smtp_account.port = 1025
++ model.db_disconnect()
++ email = smtp_account.create_email("from@test.com",
++ "to@test.com",
++ "subject",
++ "body")
++ test_func = self.make_test(["220 localhost ESMTP\r\n",
++ "250-localhost Hello 127.0.0.1\r\n"
++ + "250-SIZE 52428800\r\n"
++ + "250-PIPELINING\r\n"
++ + "250 HELP\r\n",
++ "250 OK\r\n",
++ "250 Accepted\r\n",
++ "354 Enter message\r\n",
++ None, None, None, None,
++ None, None, None, None,
++ "250 OK\r\n"],
++ ["ehlo .*\r\n",
++ "mail FROM:<" + str(email['From']) + ">.*",
++ "rcpt TO:<" + str(email['To']) + ">\r\n",
++ "data\r\n"] +
++ email.as_string().split("\n") + [".\r\n"],
++ lambda self: \
++ smtp_account.send_email(email))
++ test_func()
++
++ def test_send_email_no_auth(self):
++ model.db_connect()
++ smtp_account = SMTPAccount(user=User(jid="user1@test.com"),
++ name="account11",
++ jid="account11@jmc.test.com")
++ smtp_account.host = "localhost"
++ smtp_account.port = 1025
++ model.db_disconnect()
++ email = smtp_account.create_email("from@test.com",
++ "to@test.com",
++ "subject",
++ "body")
++ test_func = self.make_test(["220 localhost SMTP\r\n",
++ "504 ESMTP not supported\r\n",
++ "250-localhost Hello 127.0.0.1\r\n"
++ + "250-SIZE 52428800\r\n"
++ + "250-PIPELINING\r\n"
++ + "250 HELP\r\n",
++ "250 OK\r\n",
++ "250 Accepted\r\n",
++ "354 Enter message\r\n",
++ None, None, None, None,
++ None, None, None, None,
++ "250 OK\r\n"],
++ ["ehlo .*\r\n",
++ "helo .*\r\n",
++ "mail FROM:<" + str(email['From']) + ">.*",
++ "rcpt TO:<" + str(email['To']) + ">\r\n",
++ "data\r\n"] +
++ email.as_string().split("\n") + [".\r\n"],
++ lambda self: \
++ smtp_account.send_email(email))
++ test_func()
++
++ def test_send_email_esmtp_auth(self):
++ model.db_connect()
++ smtp_account = SMTPAccount(user=User(jid="user1@test.com"),
++ name="account11",
++ jid="account11@jmc.test.com")
++ smtp_account.host = "localhost"
++ smtp_account.port = 1025
++ smtp_account.login = "user"
++ smtp_account.password = "pass"
++ model.db_disconnect()
++ email = smtp_account.create_email("from@test.com",
++ "to@test.com",
++ "subject",
++ "body")
++ test_func = self.make_test(["220 localhost ESMTP\r\n",
++ "250-localhost Hello 127.0.0.1\r\n"
++ + "250-SIZE 52428800\r\n"
++ + "250-AUTH PLAIN LOGIN CRAM-MD5\r\n"
++ + "250-PIPELINING\r\n"
++ + "250 HELP\r\n",
++ "334 ZGF4IDNmNDM2NzY0YzBhNjgyMTQ1MzhhZGNiMjE2YTYxZjRm\r\n",
++ "235 Authentication succeeded\r\n",
++ "250 OK\r\n",
++ "250 Accepted\r\n",
++ "354 Enter message\r\n",
++ None, None, None, None,
++ None, None, None, None,
++ "250 OK\r\n"],
++ ["ehlo .*\r\n",
++ "AUTH CRAM-MD5\r\n",
++ ".*\r\n",
++ "mail FROM:<" + str(email['From']) + ">.*",
++ "rcpt TO:<" + str(email['To']) + ">\r\n",
++ "data\r\n"] +
++ email.as_string().split("\n") + [".\r\n"],
++ lambda self: \
++ smtp_account.send_email(email))
++ test_func()
++
++ def test_send_email_esmtp_auth_method2(self):
++ model.db_connect()
++ smtp_account = SMTPAccount(user=User(jid="user1@test.com"),
++ name="account11",
++ jid="account11@jmc.test.com")
++ smtp_account.host = "localhost"
++ smtp_account.port = 1025
++ smtp_account.login = "user"
++ smtp_account.password = "pass"
++ model.db_disconnect()
++ email = smtp_account.create_email("from@test.com",
++ "to@test.com",
++ "subject",
++ "body")
++ test_func = self.make_test(["220 localhost ESMTP\r\n",
++ "250-localhost Hello 127.0.0.1\r\n"
++ + "250-SIZE 52428800\r\n"
++ + "250-AUTH PLAIN LOGIN CRAM-MD5\r\n"
++ + "250-PIPELINING\r\n"
++ + "250 HELP\r\n",
++ "334 ZGF4IDNmNDM2NzY0YzBhNjgyMTQ1MzhhZGNiMjE2YTYxZjRm\r\n",
++ "535 Incorrect Authentication data\r\n",
++ "334 asd235r4\r\n",
++ "235 Authentication succeeded\r\n",
++ "250 OK\r\n",
++ "250 Accepted\r\n",
++ "354 Enter message\r\n",
++ None, None, None, None,
++ None, None, None, None,
++ "250 OK\r\n"],
++ ["ehlo .*\r\n",
++ "AUTH CRAM-MD5\r\n",
++ ".*\r\n",
++ "AUTH LOGIN .*\r\n",
++ ".*\r\n",
++ "mail FROM:<" + str(email['From']) + ">.*",
++ "rcpt TO:<" + str(email['To']) + ">\r\n",
++ "data\r\n"] +
++ email.as_string().split("\n") + [".\r\n"],
++ lambda self: \
++ smtp_account.send_email(email))
++ test_func()
++
++ def test_get_default_status_msg(self):
++ """
++ Get default status message for IMAPAccount.
++ """
++ smtp_account = SMTPAccount(user=User(jid="user1@test.com"),
++ name="account11",
++ jid="account11@jmc.test.com")
++ smtp_account.host = "localhost"
++ smtp_account.port = 1025
++ smtp_account.login = "user"
++ smtp_account.password = "pass"
++ status_msg = smtp_account.get_default_status_msg(Lang.en)
++ self.assertEquals(status_msg, "smtp://user@localhost:1025")
++
++ def test_get_default_status_msg_ssl(self):
++ """
++ Get default status message for SSL IMAPAccount.
++ """
++ smtp_account = SMTPAccount(user=User(jid="user1@test.com"),
++ name="account11",
++ jid="account11@jmc.test.com")
++ smtp_account.host = "localhost"
++ smtp_account.port = 1025
++ smtp_account.login = "user"
++ smtp_account.password = "pass"
++ smtp_account.tls = True
++ status_msg = smtp_account.get_default_status_msg(Lang.en)
++ self.assertEquals(status_msg, "smtps://user@localhost:1025")
++
++def suite():
++ suite = unittest.TestSuite()
++ suite.addTest(unittest.makeSuite(AccountModule_TestCase, 'test'))
++ suite.addTest(unittest.makeSuite(MailAccount_TestCase, 'test'))
++ suite.addTest(unittest.makeSuite(POP3Account_TestCase, 'test'))
++ suite.addTest(unittest.makeSuite(IMAPAccount_TestCase, 'test'))
++ suite.addTest(unittest.makeSuite(AbstractSMTPAccount_TestCase, 'test'))
++ suite.addTest(unittest.makeSuite(SMTPAccount_TestCase, 'test'))
++ return suite
++
++if __name__ == '__main__':
++ unittest.main(defaultTest='suite')
+--- /dev/null
++++ jmc-0.3b3/src/jmc/model/tests/__init__.py
+@@ -0,0 +1,14 @@
++"""JMC test module"""
++__revision__ = ""
++
++import unittest
++
++from jmc.model.tests import account
++
++def suite():
++ suite = unittest.TestSuite()
++ suite.addTest(account.suite())
++ return suite
++
++if __name__ == '__main__':
++ unittest.main(defaultTest='suite')
+--- /dev/null
++++ jmc-0.3b3/src/jmc/model/tests/server.py
+@@ -0,0 +1,205 @@
++##
++## dummy_server.py
++## Login : David Rousselie <david.rousselie@happycoders.org>
++## Started on Fri May 13 12:53:17 2005
++## $Id: dummy_server.py,v 1.1 2005/07/11 20:39:31 dax Exp $
++##
++## Copyright (C) 2005
++## This program 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 2 of the License, or
++## (at your option) any later version.
++##
++## This program 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 this program; if not, write to the Free Software
++## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++##
++
++import sys
++import time
++import traceback
++import re
++import os
++import socket
++import types
++import select
++import xml.dom.minidom
++from pyxmpp import xmlextra
++
++def xmldiff(node1, node2):
++ if node1.nodeType == node1.TEXT_NODE:
++ if not node2.nodeType == node2.TEXT_NODE \
++ or re.compile(node2.data + "$").match(node1.data) is None:
++ raise Exception("data in text node " + node1.data + " does not match " + node2.data)
++ elif node1.nodeType == node1.DOCUMENT_NODE:
++ if not node2.nodeType == node2.DOCUMENT_NODE:
++ raise Exception("node1 is Document but not node2 (" + node2.nodeType + ")")
++ elif node1.tagName != node2.tagName:
++ raise Exception("Different tag name : " + node1.tagName + " != " + node2.tagName)
++ else:
++ for attr in node1._get_attributes().keys():
++ if not node2.hasAttribute(attr) \
++ or node1.getAttribute(attr) != node2.getAttribute(attr):
++ raise Exception("(" + node1.tagName + ") Different attributes : " + node1.getAttribute(attr) + " != " + node2.getAttribute(attr))
++ if len(node1.childNodes) != len(node2.childNodes):
++ raise Exception("(" + node1.tagName + ") Different children number : " + str(len(node1.childNodes)) + " != " + str(len(node2.childNodes)))
++ for i in range(len(node1.childNodes)):
++ xmldiff(node1.childNodes[i], node2.childNodes[i])
++
++class DummyServer:
++ def __init__(self, host, port, responses = None):
++ for res in socket.getaddrinfo(host, port, socket.AF_INET, socket.SOCK_STREAM, 0, socket.AI_PASSIVE):
++ af, socktype, proto, canonname, sa = res
++ try:
++ s = socket.socket(af, socktype, proto)
++ except socket.error, msg:
++ print >>sys.stderr, msg
++ s = None
++ raise socket.error
++ try:
++ s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
++ s.bind(sa)
++ s.listen(1)
++ except socket.error, msg:
++ print >>sys.stderr, msg
++ s.close()
++ s = None
++ raise socket.error
++ break
++ self.socket = s
++ self.responses = None
++ self.queries = None
++ self.real_queries = []
++
++ def serve(self):
++ conn = None
++ try:
++ conn, addr = self.socket.accept()
++ rfile = conn.makefile('rb', -1)
++ if self.responses:
++ data = None
++ for idx in range(len(self.responses)):
++ # if response is a function apply it (it must return a string)
++ # it is given previous received data
++ if isinstance(self.responses[idx], types.FunctionType):
++ response = self.responses[idx](data)
++ else:
++ response = self.responses[idx]
++ if response is not None:
++ #print >>sys.stderr, 'Sending : ', response
++ conn.send(response)
++ data = rfile.readline()
++ if not data:
++ break
++ else:
++ self.real_queries.append(data)
++ #print >>sys.stderr, 'Receive : ', data
++ if conn is not None:
++ conn.close()
++ if self.socket is not None:
++ self.socket.close()
++ self.socket = None
++ except:
++ type, value, stack = sys.exc_info()
++ print >>sys.stderr, "".join(traceback.format_exception
++ (type, value, stack, 5))
++
++ def verify_queries(self):
++ result = True
++ queries_len = len(self.queries)
++ if queries_len == len(self.real_queries):
++ for idx in range(queries_len):
++ real_query = self.real_queries[idx]
++ match = (re.compile(self.queries[idx], re.M).match(real_query) is not None)
++ if not match:
++ result = False
++ print >>sys.stderr, "Unexpected query :\n" + \
++ "Expected query : _" + self.queries[idx] + "_\n" + \
++ "Receive query : _" + real_query + "_\n"
++ else:
++ result = False
++ print >>sys.stderr, "Expected " + str(queries_len) + \
++ " queries, got " + str(len(self.real_queries)) + \
++ "\t" + str(self.real_queries)
++ return result
++
++class XMLDummyServer(DummyServer):
++ def __init__(self, host, port, responses, stream_handler):
++ DummyServer.__init__(self, host, port, responses)
++ self._reader = xmlextra.StreamReader(stream_handler)
++
++ def serve(self):
++ try:
++ conn, addr = self.socket.accept()
++ if self.responses:
++ data = None
++ for idx in range(len(self.responses)):
++ try:
++ # This approximation is not clean
++ # received size is based on the expected size in self.queries
++ data = conn.recv(1024 + len(self.queries[idx]))
++# print "receive : " + data
++ if data:
++ #print "-----------RECEIVE1 " + data
++ r = self._reader.feed(data)
++ except:
++ type, value, stack = sys.exc_info()
++ print "".join (traceback.format_exception
++ (type, value, stack, 5))
++ raise
++ if data:
++ self.real_queries.append(data)
++ # if response is a function apply it (it must return a string)
++ # it is given previous received data
++ if isinstance(self.responses[idx], types.FunctionType):
++ response = self.responses[idx](data)
++ else:
++ response = self.responses[idx]
++ if response is not None:
++# print >>sys.stderr, '---------SENDING : ', response
++ conn.send(response)
++ data = conn.recv(1024)
++ if data:
++# print "-----------RECEIVE2 " + data
++ r = self._reader.feed(data)
++ self.real_queries.append(data)
++ conn.close()
++ self.socket.close()
++ self.socket = None
++ except:
++ type, value, stack = sys.exc_info()
++ print "".join (traceback.format_exception
++ (type, value, stack, 5))
++ raise
++
++ def verify_queries(self):
++ result = True
++ full_real_queries = ""
++ full_recv_queries = ""
++ for idx in range(len(self.real_queries)):
++ full_real_queries += self.real_queries[idx].rstrip(os.linesep)
++ for idx in range(len(self.queries)):
++ full_recv_queries += self.queries[idx].rstrip(os.linesep)
++ # Do not receive it but add it so that xml parsing can succeed
++ #full_real_queries += "</stream:stream>"
++ real_query = xml.dom.minidom.parseString(full_real_queries)
++ recv_query = xml.dom.minidom.parseString(full_recv_queries)
++ try:
++ utils.xmldiff(real_query, recv_query)
++ except Exception, msg:
++ result = False
++ print >>sys.stderr, msg
++ return result
++
++def test():
++ server = DummyServer(("localhost", 4242))
++ server.responses = ["rep1\n", "rep2\n"]
++ server.serve()
++
++if __name__ == '__main__':
++ test()
+--- /dev/null
++++ jmc-0.3b3/src/jmc/jabber/tests/disco.py
+@@ -0,0 +1,83 @@
++##
++## disco.py
++## Login : David Rousselie <dax@happycoders.org>
++## Started on Sun Jul 8 20:59:32 2007 David Rousselie
++## $Id$
++##
++## Copyright (C) 2007 David Rousselie
++## This program 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 2 of the License, or
++## (at your option) any later version.
++##
++## This program 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 this program; if not, write to the Free Software
++## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++##
++
++import unittest
++
++from jmc.jabber.disco import MailRootDiscoGetInfoHandler, \
++ IMAPAccountDiscoGetInfoHandler
++from jmc.lang import Lang
++
++class MockDiscoIndentity(object):
++ def __init__(self):
++ self.category = ""
++ self.type = ""
++
++class MockAccountManager(object):
++ def __init__(self):
++ self.has_multiple_account_type = False
++
++class MockComponent(object):
++ def __init__(self):
++ self.name = ""
++ self.disco_identity = MockDiscoIndentity()
++ self.account_manager = MockAccountManager()
++
++class MailRootDiscoGetInfoHandler_TestCase(unittest.TestCase):
++ def test_root_disco_get_info(self):
++ component = MockComponent()
++ component.name = "Mock component"
++ component.disco_identity.category = "gateway"
++ component.disco_identity.type = "smtp"
++ component.account_manager.has_multiple_account_type = True
++ handler = MailRootDiscoGetInfoHandler(component)
++ # stanza, lang_class, node, disco_obj, data
++ disco_infos = handler.handle(None, None, None, None, None)
++ self.assertTrue(disco_infos[0].has_feature("jabber:iq:gateway"))
++ self.assertTrue(disco_infos[0].has_feature("http://jabber.org/protocol/disco#info"))
++ self.assertTrue(disco_infos[0].has_feature("http://jabber.org/protocol/disco#items"))
++ self.assertTrue(disco_infos[0].has_feature("http://jabber.org/protocol/commands"))
++ self.assertEquals(len(disco_infos[0].get_identities()), 2)
++ self.assertTrue(disco_infos[0].identity_is("gateway", "smtp"))
++ self.assertTrue(disco_infos[0].identity_is("headline", "newmail"))
++
++class IMAPAccountDiscoGetInfoHandler_TestCase(unittest.TestCase):
++ def test_handle_not_imap(self):
++ component = MockComponent()
++ component.name = "Mock component"
++ component.disco_identity.category = "gateway"
++ component.disco_identity.type = "smtp"
++ component.account_manager.has_multiple_account_type = True
++ handler = IMAPAccountDiscoGetInfoHandler(component)
++ # stanza, lang_class, node, disco_obj, data
++ disco_infos = handler.handle(None, Lang.en, "account@jmc.test.com/POP3",
++ None, None)
++ self.assertTrue(disco_infos[0].has_feature("jabber:iq:register"))
++ self.assertFalse(disco_infos[0].has_feature("http://jabber.org/protocol/commands"))
++
++def suite():
++ suite = unittest.TestSuite()
++ suite.addTest(unittest.makeSuite(MailRootDiscoGetInfoHandler_TestCase, 'test'))
++ suite.addTest(unittest.makeSuite(IMAPAccountDiscoGetInfoHandler_TestCase, 'test'))
++ return suite
++
++if __name__ == '__main__':
++ unittest.main(defaultTest='suite')
+--- /dev/null
++++ jmc-0.3b3/src/jmc/jabber/tests/component.py
+@@ -0,0 +1,1584 @@
++
++
++# -*- coding: utf-8 -*-
++##
++## test_component.py
++## Login : <dax@happycoders.org>
++## Started on Wed Feb 14 18:04:49 2007 David Rousselie
++## $Id$
++##
++## Copyright (C) 2007 David Rousselie
++## This program 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 2 of the License, or
++## (at your option) any later version.
++##
++## This program 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 this program; if not, write to the Free Software
++## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++##
++
++import unittest
++import sys
++import time
++import logging
++import time
++
++from sqlobject import *
++from sqlobject.dbconnection import TheURIOpener
++
++from pyxmpp.presence import Presence
++from pyxmpp.message import Message
++from pyxmpp.iq import Iq
++
++from jcl.tests import JCLTestCase
++import jcl.model as model
++from jcl.model import account
++from jcl.model.account import Account, PresenceAccount, LegacyJID, User
++from jcl.jabber.tests.presence import DefaultSubscribeHandler_TestCase, \
++ DefaultUnsubscribeHandler_TestCase
++from jcl.jabber.tests.feeder import FeederMock, SenderMock
++
++from jmc.model.account import MailAccount, IMAPAccount, POP3Account, \
++ GlobalSMTPAccount, AbstractSMTPAccount, SMTPAccount, NoAccountError
++from jmc.jabber import MailHandler
++from jmc.jabber.message import SendMailMessageHandler
++from jmc.jabber.presence import MailSubscribeHandler, \
++ MailUnsubscribeHandler, MailPresenceHandler
++from jmc.jabber.component import MailComponent, MailFeederHandler, \
++ MailSender
++from jmc.lang import Lang
++
++if sys.platform == "win32":
++ DB_PATH = "/c|/temp/jmc_test.db"
++else:
++ DB_PATH = "/tmp/jmc_test.db"
++DB_URL = DB_PATH# + "?debug=1&debugThreading=1"
++
++class MockStream(object):
++ def __init__(self,
++ jid="",
++ secret="",
++ server="",
++ port="",
++ keepalive=True):
++ self.sent = []
++ self.connection_started = False
++ self.connection_stopped = False
++ self.eof = False
++ self.socket = []
++
++ def send(self, iq):
++ self.sent.append(iq)
++
++ def set_iq_set_handler(self, iq_type, ns, handler):
++ if not iq_type in ["query"]:
++ raise Exception("IQ type unknown: " + iq_type)
++ if not ns in ["jabber:iq:version",
++ "jabber:iq:register",
++ "http://jabber.org/protocol/disco#items",
++ "http://jabber.org/protocol/disco#info"]:
++ raise Exception("Unknown namespace: " + ns)
++ if handler is None:
++ raise Exception("Handler must not be None")
++
++ set_iq_get_handler = set_iq_set_handler
++
++ def set_presence_handler(self, status, handler):
++ if not status in ["available",
++ "unavailable",
++ "probe",
++ "subscribe",
++ "subscribed",
++ "unsubscribe",
++ "unsubscribed"]:
++ raise Exception("Status unknown: " + status)
++ if handler is None:
++ raise Exception("Handler must not be None")
++
++ def set_message_handler(self, msg_type, handler):
++ if not msg_type in ["normal"]:
++ raise Exception("Message type unknown: " + msg_type)
++ if handler is None:
++ raise Exception("Handler must not be None")
++
++ def connect(self):
++ self.connection_started = True
++
++ def disconnect(self):
++ self.connection_stopped = True
++
++ def loop_iter(self, timeout):
++ time.sleep(timeout)
++
++ def close(self):
++ pass
++
++class MockMailAccount(object):
++ def _init(self):
++ self.connected = False
++ self.has_connected = False
++ self.marked_all_as_read = False
++ self._action = PresenceAccount.DO_NOTHING
++
++ def connect(self):
++ self.connected = True
++ self.has_connected = True
++
++ def mark_all_as_read(self):
++ self.marked_all_as_read = True
++
++ def disconnect(self):
++ self.connected = False
++
++ def get_action(self):
++ return self._action
++
++ action = property(get_action)
++
++class MockIMAPAccount(MockMailAccount, IMAPAccount):
++ def _init(self, *args, **kw):
++ IMAPAccount._init(self, *args, **kw)
++ MockMailAccount._init(self)
++ self.get_mail_list_summary_called = False
++
++ def ls_dir(self, imap_dir):
++ if imap_dir == "":
++ return ["INBOX"]
++ elif imap_dir == "INBOX":
++ return ["dir1", "dir2"]
++ elif imap_dir == "INBOX/dir1":
++ return ["subdir1", "subdir2"]
++ return []
++
++ def get_mail_with_attachment_list(self):
++ return [("1", "mail 1"),
++ ("2", "mail 2")]
++
++ def get_mail_list_summary(self, start_index=1, end_index=20):
++ if self.get_mail_list_summary_called:
++ return [("11", "mail 11"),
++ ("12", "mail 12"),
++ ("13", "mail 13"),
++ ("14", "mail 14"),
++ ("15", "mail 15"),
++ ("16", "mail 16"),
++ ("17", "mail 17"),
++ ("18", "mail 18"),
++ ("19", "mail 19"),
++ ("20", "mail 20")]
++ else:
++ self.get_mail_list_summary_called = True
++ return [("1", "mail 1"),
++ ("2", "mail 2"),
++ ("3", "mail 3"),
++ ("4", "mail 4"),
++ ("5", "mail 5"),
++ ("6", "mail 6"),
++ ("7", "mail 7"),
++ ("8", "mail 8"),
++ ("9", "mail 9"),
++ ("10", "mail 10")]
++
++
++class MockPOP3Account(MockMailAccount, POP3Account):
++ def _init(self, *args, **kw):
++ POP3Account._init(self, *args, **kw)
++ MockMailAccount._init(self)
++
++class MailComponent_TestCase(JCLTestCase):
++ def setUp(self):
++ JCLTestCase.setUp(self, tables=[Account, PresenceAccount, User,
++ MailAccount, IMAPAccount, POP3Account,
++ GlobalSMTPAccount,
++ AbstractSMTPAccount, SMTPAccount,
++ MockIMAPAccount, MockPOP3Account])
++ self.comp = MailComponent("jmc.test.com",
++ "password",
++ "localhost",
++ "5347",
++ None,
++ None)
++ self.comp.stream = MockStream()
++ self.comp.stream_class = MockStream
++
++ def _account_has_been_checked(self, _account, old_value):
++ if old_value == _account.lastcheck:
++ return False
++ else:
++ delta = int(time.time()) - _account.lastcheck
++ return (delta <= 1) and (delta >= 0)
++
++ ###########################################################################
++ # 'feed' test methods
++ ###########################################################################
++ def test_feed_first_check(self):
++ account11 = MockIMAPAccount(user=User(jid="test1@test.com"),
++ name="account11",
++ jid="account11@jmc.test.com")
++ account11.status = account.ONLINE
++ self.assertTrue(account11.first_check)
++ self.assertEquals(account11.error, None)
++ self.assertFalse(account11.waiting_password_reply)
++ account11.live_email_only = False
++ account11.lastcheck = 0
++ account11.password = ""
++ result = self.comp.tick_handlers[0].feeder.feed(account11)
++ self.assertEquals(len(result), 0)
++ sent = self.comp.stream.sent
++ self.assertEquals(len(sent), 0)
++ self.assertFalse(account11.first_check)
++ self.assertFalse(account11.waiting_password_reply)
++ self.assertEquals(account11.error, None)
++ self.assertFalse(account11.connected)
++ self.assertFalse(account11.has_connected)
++ self.assertFalse(account11.marked_all_as_read)
++ self.assertTrue(self._account_has_been_checked(account11,
++ 0))
++
++ def test_feed_live_email_init_no_password(self):
++ account11 = MockIMAPAccount(user=User(jid="test1@test.com"),
++ name="account11",
++ jid="account11@jmc.test.com")
++ account11.status = account.ONLINE
++ self.assertTrue(account11.first_check)
++ self.assertEquals(account11.error, None)
++ self.assertFalse(account11.waiting_password_reply)
++ account11.live_email_only = True
++ account11.password = None
++ result = self.comp.tick_handlers[0].feeder.feed(account11)
++ self.assertEquals(len(result), 0)
++ sent = self.comp.stream.sent
++ self.assertEquals(len(sent), 1)
++ self.assertEquals(sent[0].get_to(), "test1@test.com")
++ self.assertEquals(sent[0].get_from(), "account11@jmc.test.com")
++ self.assertTrue(account11.first_check)
++ self.assertTrue(account11.waiting_password_reply)
++ self.assertEquals(account11.error, None)
++ self.assertFalse(account11.connected)
++ self.assertFalse(account11.has_connected)
++ self.assertFalse(account11.marked_all_as_read)
++
++ def test_feed_live_email_init_no_password2(self):
++ account11 = MockIMAPAccount(user=User(jid="test1@test.com"),
++ name="account11",
++ jid="account11@jmc.test.com")
++ account11.status = account.ONLINE
++ self.assertTrue(account11.first_check)
++ self.assertEquals(account11.error, None)
++ account11.waiting_password_reply = True
++ account11.live_email_only = True
++ account11.password = None
++ result = self.comp.tick_handlers[0].feeder.feed(account11)
++ self.assertEquals(result, [])
++ self.assertTrue(account11.first_check)
++ self.assertTrue(account11.waiting_password_reply)
++ self.assertEquals(account11.error, None)
++ self.assertFalse(account11.connected)
++ self.assertFalse(account11.has_connected)
++ self.assertFalse(account11.marked_all_as_read)
++ self.assertEquals(len(self.comp.stream.sent), 0)
++
++ def test_feed_interval_no_check(self):
++ account11 = MockIMAPAccount(user=User(jid="test1@test.com"),
++ name="account11",
++ jid="account11@jmc.test.com")
++ account11._action = PresenceAccount.DO_NOTHING
++ account11.first_check = False
++ account11.lastcheck = old_value = int(time.time()) - 2
++ account11.interval = 2
++ result = self.comp.tick_handlers[0].feeder.feed(account11)
++ self.assertEquals(result, [])
++ self.assertFalse(self._account_has_been_checked(account11,
++ old_value))
++
++ def test_feed_interval_first_check(self):
++ account11 = MockIMAPAccount(user=User(jid="test1@test.com"),
++ name="account11",
++ jid="account11@jmc.test.com")
++ account11._action = PresenceAccount.DO_NOTHING
++ account11.first_check = True
++ account11.lastcheck = 0
++ account11.interval = 2
++ result = self.comp.tick_handlers[0].feeder.feed(account11)
++ self.assertEquals(result, [])
++ self.assertTrue(self._account_has_been_checked(account11, 0))
++
++ def test_feed_interval_check(self):
++ account11 = MockIMAPAccount(user=User(jid="test1@test.com"),
++ name="account11",
++ jid="account11@jmc.test.com")
++ account11._action = PresenceAccount.DO_NOTHING
++ account11.first_check = False
++ account11.lastcheck = 0
++ account11.interval = 2
++ result = self.comp.tick_handlers[0].feeder.feed(account11)
++ self.assertEquals(result, [])
++ self.assertTrue(self._account_has_been_checked(account11, 0))
++
++ def test_feed_no_password(self):
++ account11 = MockIMAPAccount(user=User(jid="test1@test.com"),
++ name="account11",
++ jid="account11@jmc.test.com")
++ account11._action = MailAccount.RETRIEVE
++ account11.status = account.ONLINE
++ account11.first_check = False
++ account11.lastcheck = 0
++ account11.interval = 2
++ account11.password = None
++ self.assertFalse(account11.waiting_password_reply)
++ result = self.comp.tick_handlers[0].feeder.feed(account11)
++ self.assertEquals(account11.error, None)
++ self.assertEquals(len(result), 0)
++ sent = self.comp.stream.sent
++ self.assertEquals(len(sent), 1)
++ self.assertEquals(sent[0].get_to(), "test1@test.com")
++ self.assertEquals(sent[0].get_from(), "account11@jmc.test.com")
++ self.assertTrue(self._account_has_been_checked(account11, 0))
++ self.assertFalse(account11.connected)
++ self.assertFalse(account11.has_connected)
++
++ def test_feed_unknown_action(self):
++ account11 = MockIMAPAccount(user=User(jid="test1@test.com"),
++ name="account11",
++ jid="account11@jmc.test.com")
++ account11._action = 42 # Unknown action
++ account11.status = account.ONLINE
++ account11.first_check = False
++ account11.lastcheck = 0
++ account11.interval = 2
++ account11.password = "password"
++ account11.get_new_mail_list = lambda: []
++ result = self.comp.tick_handlers[0].feeder.feed(account11)
++ self.assertNotEquals(account11.error, None)
++ self.assertEquals(len(result), 0)
++ sent = self.comp.stream.sent
++ self.assertEquals(len(sent), 2)
++ self.assertEquals(sent[0].get_to(), "test1@test.com")
++ self.assertEquals(sent[0].get_from(), "account11@jmc.test.com")
++ self.assertEquals(sent[1].get_to(), "test1@test.com")
++ self.assertEquals(sent[1].get_from(), "account11@jmc.test.com")
++ self.assertEquals(sent[1].xmlnode.name, "presence")
++ self.assertEquals(sent[1].xmlnode.children.name, "show")
++ self.assertEquals(sent[1].xmlnode.children.content, "dnd")
++ self.assertTrue(self._account_has_been_checked(account11, 0))
++ self.assertFalse(account11.connected)
++ self.assertTrue(account11.has_connected)
++
++ def test_feed_retrieve_no_mail(self):
++ account11 = MockIMAPAccount(user=User(jid="test1@test.com"),
++ name="account11",
++ jid="account11@jmc.test.com")
++ account11._action = MailAccount.RETRIEVE
++ account11.status = account.ONLINE
++ account11.first_check = False
++ account11.lastcheck = 0
++ account11.interval = 2
++ account11.password = "password"
++ account11.get_new_mail_list = lambda: []
++ result = self.comp.tick_handlers[0].feeder.feed(account11)
++ self.assertEquals(account11.error, None)
++ self.assertEquals(result, [])
++ self.assertTrue(self._account_has_been_checked(account11, 0))
++ self.assertFalse(account11.connected)
++ self.assertTrue(account11.has_connected)
++ self.assertEquals(len(self.comp.stream.sent), 0)
++
++ def test_feed_cancel_error(self):
++ account11 = MockIMAPAccount(user=User(jid="test1@test.com"),
++ name="account11",
++ jid="account11@jmc.test.com")
++ account11._action = MailAccount.RETRIEVE
++ account11.status = account.DND
++ account11.error = "An error"
++ account11.first_check = False
++ account11.lastcheck = 0
++ account11.interval = 2
++ account11.password = "password"
++ account11.get_new_mail_list = lambda: []
++ result = self.comp.tick_handlers[0].feeder.feed(account11)
++ self.assertEquals(account11.error, None)
++ self.assertEquals(result, [])
++ self.assertTrue(self._account_has_been_checked(account11, 0))
++ self.assertFalse(account11.connected)
++ self.assertTrue(account11.has_connected)
++ sent = self.comp.stream.sent
++ self.assertEquals(len(sent), 1)
++ self.assertEquals(sent[0].get_to(), "test1@test.com")
++ self.assertEquals(sent[0].get_from(), "account11@jmc.test.com")
++ self.assertEquals(sent[0].xmlnode.name, "presence")
++ self.assertEquals(sent[0].xmlnode.children.name, "show")
++ self.assertEquals(sent[0].xmlnode.children.content, "online")
++
++ def test_feed_retrieve_mail(self):
++ def mock_get_mail(index):
++ return [("body1", "from1@test.com"),
++ ("body2", "from2@test.com")][index]
++ model.db_connect()
++ account11 = MockIMAPAccount(user=User(jid="test1@test.com"),
++ name="account11",
++ jid="account11@jmc.test.com")
++ account11._action = MailAccount.RETRIEVE
++ account11.status = account.ONLINE
++ account11.first_check = False
++ account11.lastcheck = 0
++ account11.interval = 2
++ account11.password = "password"
++ account11.get_new_mail_list = lambda: [0, 1]
++ account11.get_mail = mock_get_mail
++ result = self.comp.tick_handlers[0].feeder.feed(account11)
++ self.assertEquals(account11.error, None)
++ self.assertTrue(self._account_has_been_checked(account11, 0))
++ self.assertFalse(account11.connected)
++ self.assertTrue(account11.has_connected)
++ self.assertEquals(len(self.comp.stream.sent), 0)
++ self.assertEquals(len(result), 2)
++ self.assertEquals(result[0][0],
++ "from1@test.com")
++ self.assertEquals(result[0][1],
++ account11.default_lang_class.new_mail_subject \
++ % ("from1@test.com"))
++ self.assertEquals(result[0][2], "body1")
++ self.assertEquals(result[1][0],
++ "from2@test.com")
++ self.assertEquals(result[1][1], \
++ account11.default_lang_class.new_mail_subject \
++ % ("from2@test.com"))
++ self.assertEquals(result[1][2], "body2")
++ model.db_disconnect()
++
++ def test_feed_digest_no_mail(self):
++ model.db_connect()
++ account11 = MockIMAPAccount(user=User(jid="test1@test.com"),
++ name="account11",
++ jid="account11@jmc.test.com")
++ account11._action = MailAccount.DIGEST
++ account11.status = account.ONLINE
++ account11.first_check = False
++ account11.lastcheck = 0
++ account11.interval = 2
++ account11.password = "password"
++ account11.get_new_mail_list = lambda: []
++ result = self.comp.tick_handlers[0].feeder.feed(account11)
++ self.assertEquals(account11.error, None)
++ self.assertEquals(result, [])
++ self.assertTrue(self._account_has_been_checked(account11, 0))
++ self.assertFalse(account11.connected)
++ self.assertTrue(account11.has_connected)
++ self.assertEquals(len(self.comp.stream.sent), 0)
++ model.db_disconnect()
++
++ def test_feed_digest_mail(self):
++ def mock_get_mail_summary(index):
++ return [("body1", "from1@test.com"),
++ ("body2", "from2@test.com")][index]
++ model.db_connect()
++ account11 = MockIMAPAccount(user=User(jid="test1@test.com"),
++ name="account11",
++ jid="account11@jmc.test.com")
++ account11._action = MailAccount.DIGEST
++ account11.status = account.ONLINE
++ account11.first_check = False
++ account11.lastcheck = 0
++ account11.interval = 2
++ account11.password = "password"
++ account11.get_new_mail_list = lambda: [0, 1]
++ account11.get_mail_summary = mock_get_mail_summary
++ result = self.comp.tick_handlers[0].feeder.feed(account11)
++ self.assertEquals(account11.error, None)
++ self.assertTrue(self._account_has_been_checked(account11, 0))
++ self.assertFalse(account11.connected)
++ self.assertTrue(account11.has_connected)
++ self.assertEquals(len(self.comp.stream.sent), 0)
++ self.assertEquals(len(result), 1)
++ self.assertEquals(result[0][1],
++ account11.default_lang_class.new_digest_subject \
++ % (2))
++ self.assertEquals(result[0][2],
++ "body1\n----------------------------------\nbody2\n----------------------------------\n")
++ model.db_disconnect()
++
++ ###########################################################################
++ # 'initialize_live_email' test methods
++ ###########################################################################
++ def test_initialize_live_email(self):
++ account11 = MockIMAPAccount(user=User(jid="test1@test.com"),
++ name="account11",
++ jid="account11@jmc.test.com")
++ account11.status = account.ONLINE
++ self.assertTrue(account11.first_check)
++ self.assertEquals(account11.error, None)
++ account11.live_email_only = True
++ account11.password = "password"
++ continue_checking = self.comp.tick_handlers[0].feeder.initialize_live_email(account11)
++ self.assertEquals(continue_checking, True)
++ self.assertFalse(account11.first_check)
++ self.assertFalse(account11.waiting_password_reply)
++ self.assertEquals(account11.error, None)
++ self.assertFalse(account11.connected)
++ self.assertTrue(account11.has_connected)
++ self.assertTrue(account11.marked_all_as_read)
++
++ def test_initialize_live_email_connection_error(self):
++ def raiser():
++ raise Exception
++ account11 = MockIMAPAccount(user=User(jid="test1@test.com"),
++ name="account11",
++ jid="account11@jmc.test.com")
++ account11.connect = raiser
++ account11.status = account.ONLINE
++ self.assertTrue(account11.first_check)
++ self.assertEquals(account11.error, None)
++ account11.live_email_only = True
++ account11.password = "password"
++ continue_checking = self.comp.tick_handlers[0].feeder.initialize_live_email(account11)
++ self.assertEquals(continue_checking, False)
++ sent = self.comp.stream.sent
++ self.assertEquals(len(sent), 2)
++ self.assertEquals(sent[0].get_to(), "test1@test.com")
++ self.assertEquals(sent[0].get_from(), "account11@jmc.test.com")
++ self.assertEquals(sent[1].get_to(), "test1@test.com")
++ self.assertEquals(sent[1].get_from(), "account11@jmc.test.com")
++ self.assertEquals(sent[1].xmlnode.name, "presence")
++ self.assertEquals(sent[1].xmlnode.children.name, "show")
++ self.assertEquals(sent[1].xmlnode.children.content, "dnd")
++ self.assertTrue(account11.first_check)
++ self.assertFalse(account11.waiting_password_reply)
++ self.assertEquals(account11.error, "")
++ self.assertFalse(account11.connected)
++ self.assertFalse(account11.has_connected)
++ self.assertFalse(account11.marked_all_as_read)
++
++ def test_initialize_live_email_mark_as_read_error(self):
++ def raiser():
++ raise Exception
++ account11 = MockIMAPAccount(user=User(jid="test1@test.com"),
++ name="account11",
++ jid="account11@jmc.test.com")
++ account11.mark_all_as_read = raiser
++ account11.status = account.ONLINE
++ self.assertTrue(account11.first_check)
++ self.assertEquals(account11.error, None)
++ account11.live_email_only = True
++ account11.password = "password"
++ continue_checking = self.comp.tick_handlers[0].feeder.initialize_live_email(account11)
++ self.assertEquals(continue_checking, False)
++ sent = self.comp.stream.sent
++ self.assertEquals(len(sent), 2)
++ self.assertEquals(sent[0].get_to(), "test1@test.com")
++ self.assertEquals(sent[0].get_from(), "account11@jmc.test.com")
++ self.assertEquals(sent[1].get_to(), "test1@test.com")
++ self.assertEquals(sent[1].get_from(), "account11@jmc.test.com")
++ self.assertEquals(sent[1].xmlnode.name, "presence")
++ self.assertEquals(sent[1].xmlnode.children.name, "show")
++ self.assertEquals(sent[1].xmlnode.children.content, "dnd")
++ self.assertTrue(account11.first_check)
++ self.assertFalse(account11.waiting_password_reply)
++ self.assertEquals(account11.error, "")
++ self.assertFalse(account11.connected)
++ self.assertTrue(account11.has_connected)
++ self.assertFalse(account11.marked_all_as_read)
++
++ def test_initialize_live_email_disconnection_error(self):
++ def raiser():
++ raise Exception
++ account11 = MockIMAPAccount(user=User(jid="test1@test.com"),
++ name="account11",
++ jid="account11@jmc.test.com")
++ account11.disconnect = raiser
++ account11.status = account.ONLINE
++ self.assertTrue(account11.first_check)
++ self.assertEquals(account11.error, None)
++ account11.live_email_only = True
++ account11.password = "password"
++ continue_checking = self.comp.tick_handlers[0].feeder.initialize_live_email(account11)
++ self.assertFalse(continue_checking)
++ sent = self.comp.stream.sent
++ self.assertEquals(len(sent), 2)
++ self.assertEquals(sent[0].get_to(), "test1@test.com")
++ self.assertEquals(sent[0].get_from(), "account11@jmc.test.com")
++ self.assertEquals(sent[1].get_to(), "test1@test.com")
++ self.assertEquals(sent[1].get_from(), "account11@jmc.test.com")
++ self.assertEquals(sent[1].xmlnode.name, "presence")
++ self.assertEquals(sent[1].xmlnode.children.name, "show")
++ self.assertEquals(sent[1].xmlnode.children.content, "dnd")
++ self.assertEquals(continue_checking, False)
++ self.assertTrue(account11.first_check)
++ self.assertFalse(account11.waiting_password_reply)
++ self.assertEquals(account11.error, "")
++ self.assertFalse(account11.connected)
++ self.assertTrue(account11.has_connected)
++ self.assertTrue(account11.marked_all_as_read)
++
++ def test_initialize_live_email_cancel_error(self):
++ account11 = MockIMAPAccount(user=User(jid="test1@test.com"),
++ name="account11",
++ jid="account11@jmc.test.com")
++ account11.status = account.DND
++ account11.error = "An error"
++ self.assertTrue(account11.first_check)
++ account11.live_email_only = True
++ account11.password = "password"
++ continue_checking = self.comp.tick_handlers[0].feeder.initialize_live_email(account11)
++ self.assertEquals(continue_checking, True)
++ self.assertFalse(account11.first_check)
++ self.assertFalse(account11.waiting_password_reply)
++ self.assertEquals(account11.error, None)
++ self.assertFalse(account11.connected)
++ self.assertTrue(account11.has_connected)
++ self.assertTrue(account11.marked_all_as_read)
++ sent = self.comp.stream.sent
++ self.assertEquals(len(sent), 1)
++ self.assertEquals(sent[0].get_to(), "test1@test.com")
++ self.assertEquals(sent[0].get_from(), "account11@jmc.test.com")
++ self.assertEquals(sent[0].xmlnode.name, "presence")
++ self.assertEquals(sent[0].xmlnode.children.name, "show")
++ self.assertEquals(sent[0].xmlnode.children.content, "online")
++
++ def test_disco_get_info_imap_node(self):
++ self.comp.stream = MockStream()
++ self.comp.stream_class = MockStream
++ account11 = MockIMAPAccount(user=User(jid="user1@test.com"),
++ name="account11",
++ jid="account11@jmc.test.com")
++ info_query = Iq(stanza_type="get",
++ from_jid="user1@test.com",
++ to_jid="jcl.test.com/IMAP")
++ disco_info = self.comp.disco_get_info("IMAP", info_query)
++ self.assertEquals(len(self.comp.stream.sent), 0)
++ self.assertTrue(disco_info.has_feature("jabber:iq:register"))
++ self.assertTrue(disco_info.has_feature("http://jabber.org/protocol/disco#info"))
++ self.assertTrue(disco_info.has_feature("http://jabber.org/protocol/disco#items"))
++
++ def test_disco_get_info_imap_node_no_account(self):
++ self.comp.stream = MockStream()
++ self.comp.stream_class = MockStream
++ account11 = MockPOP3Account(user=User(jid="user1@test.com"),
++ name="account11",
++ jid="account11@jmc.test.com")
++ account21 = MockIMAPAccount(user=User(jid="user2@test.com"),
++ name="account21",
++ jid="account21@jmc.test.com")
++ info_query = Iq(stanza_type="get",
++ from_jid="user1@test.com",
++ to_jid="jcl.test.com/IMAP")
++ disco_info = self.comp.disco_get_info("IMAP", info_query)
++ self.assertEquals(len(self.comp.stream.sent), 0)
++ self.assertTrue(disco_info.has_feature("jabber:iq:register"))
++ self.assertFalse(disco_info.has_feature("http://jabber.org/protocol/disco#info"))
++ self.assertFalse(disco_info.has_feature("http://jabber.org/protocol/disco#items"))
++
++ def test_disco_get_info_imap_long_node(self):
++ self.comp.stream = MockStream()
++ self.comp.stream_class = MockStream
++ account11 = MockIMAPAccount(user=User(jid="user1@test.com"),
++ name="account11",
++ jid="account11@jmc.test.com")
++ info_query = Iq(stanza_type="get",
++ from_jid="user1@test.com",
++ to_jid="account11@jcl.test.com/IMAP")
++ disco_info = self.comp.disco_get_info("IMAP/account11",
++ info_query)
++ self.assertEquals(len(self.comp.stream.sent), 0)
++ self.assertTrue(disco_info.has_feature("jabber:iq:register"))
++ self.assertTrue(disco_info.has_feature("http://jabber.org/protocol/disco#info"))
++ self.assertTrue(disco_info.has_feature("http://jabber.org/protocol/disco#items"))
++
++ def test_disco_get_info_not_imap_long_node(self):
++ self.comp.stream = MockStream()
++ self.comp.stream_class = MockStream
++ account11 = MockPOP3Account(user=User(jid="user1@test.com"),
++ name="account11",
++ jid="account11@jmc.test.com")
++ info_query = Iq(stanza_type="get",
++ from_jid="user1@test.com",
++ to_jid="account11@jcl.test.com/POP3")
++ disco_info = self.comp.disco_get_info("POP3/account11",
++ info_query)
++ self.assertEquals(len(self.comp.stream.sent), 0)
++ self.assertTrue(disco_info.has_feature("jabber:iq:register"))
++ self.assertFalse(disco_info.has_feature("http://jabber.org/protocol/disco#info"))
++ self.assertFalse(disco_info.has_feature("http://jabber.org/protocol/disco#items"))
++
++ def test_disco_get_info_imap_dir_node(self):
++ self.comp.stream = MockStream()
++ self.comp.stream_class = MockStream
++ account11 = MockIMAPAccount(user=User(jid="user1@test.com"),
++ name="account11",
++ jid="account11@jmc.test.com")
++ account11.mailbox = "INBOX/dir1"
++ info_query = Iq(stanza_type="get",
++ from_jid="user1@test.com",
++ to_jid="account11@jcl.test.com/IMAP/INBOX")
++ disco_info = self.comp.disco_get_info("IMAP/account11/INBOX",
++ info_query)
++ self.assertEquals(len(self.comp.stream.sent), 0)
++ self.assertTrue(disco_info.has_feature("jabber:iq:register"))
++ self.assertTrue(disco_info.has_feature("http://jabber.org/protocol/disco#info"))
++ self.assertTrue(disco_info.has_feature("http://jabber.org/protocol/disco#items"))
++
++ def test_disco_get_info_imap_dir_node_already_registered(self):
++ self.comp.stream = MockStream()
++ self.comp.stream_class = MockStream
++ account11 = MockIMAPAccount(user=User(jid="user1@test.com"),
++ name="account11",
++ jid="account11@jmc.test.com")
++ account11.mailbox = "INBOX"
++ info_query = Iq(stanza_type="get",
++ from_jid="user1@test.com",
++ to_jid="account11@jcl.test.com/IMAP/INBOX")
++ disco_info = self.comp.disco_get_info("IMAP/account11/INBOX",
++ info_query)
++ self.assertEquals(len(self.comp.stream.sent), 0)
++ self.assertTrue(disco_info.has_feature("jabber:iq:register"))
++ self.assertTrue(disco_info.has_feature("http://jabber.org/protocol/disco#info"))
++ self.assertTrue(disco_info.has_feature("http://jabber.org/protocol/disco#items"))
++
++ def test_disco_get_info_imap_dir_node_last_subdir(self):
++ self.comp.stream = MockStream()
++ self.comp.stream_class = MockStream
++ account11 = MockIMAPAccount(user=User(jid="user1@test.com"),
++ name="account11",
++ jid="account11@jmc.test.com")
++ account11.mailbox = "INBOX/dir1/subdir1"
++ info_query = Iq(stanza_type="get",
++ from_jid="user1@test.com",
++ to_jid="account11@jcl.test.com/IMAP/INBOX/dir1/subdir1")
++ disco_info = self.comp.disco_get_info("IMAP/account11/INBOX/dir1/subdir1",
++ info_query)
++ self.assertEquals(len(self.comp.stream.sent), 0)
++ self.assertTrue(disco_info.has_feature("jabber:iq:register"))
++ self.assertTrue(disco_info.has_feature("http://jabber.org/protocol/disco#info"))
++ self.assertFalse(disco_info.has_feature("http://jabber.org/protocol/disco#items"))
++
++ def test_disco_get_items_base_imap_account(self):
++ account11 = MockIMAPAccount(user=User(jid="user1@test.com"),
++ name="account11",
++ jid="account11@jcl.test.com")
++ info_query = Iq(stanza_type="get",
++ from_jid="user1@test.com",
++ to_jid="account11@jcl.test.com/IMAP")
++ disco_items = self.comp.disco_get_items("IMAP/account11", info_query)
++ self.assertEquals(len(disco_items.get_items()), 1)
++ disco_item = disco_items.get_items()[0]
++ self.assertEquals(unicode(disco_item.get_jid()), unicode(account11.jid)
++ + "/IMAP/INBOX")
++ self.assertEquals(disco_item.get_node(), "IMAP/" + account11.name + "/INBOX")
++ self.assertEquals(disco_item.get_name(), "INBOX")
++
++ def test_disco_get_items_inbox_imap_account(self):
++ account11 = MockIMAPAccount(user=User(jid="user1@test.com"),
++ name="account11",
++ jid="account11@jcl.test.com")
++ info_query = Iq(stanza_type="get",
++ from_jid="user1@test.com",
++ to_jid="account11@jcl.test.com/IMAP/INBOX")
++ disco_items = self.comp.disco_get_items("IMAP/account11/INBOX", info_query)
++ self.assertEquals(len(disco_items.get_items()), 2)
++ disco_item = disco_items.get_items()[0]
++ self.assertEquals(unicode(disco_item.get_jid()), unicode(account11.jid)
++ + "/IMAP/INBOX/dir1")
++ self.assertEquals(disco_item.get_node(), "IMAP/" + account11.name + "/INBOX"
++ + "/dir1")
++ self.assertEquals(disco_item.get_name(), "dir1")
++ disco_item = disco_items.get_items()[1]
++ self.assertEquals(unicode(disco_item.get_jid()), unicode(account11.jid)
++ + "/IMAP/INBOX/dir2")
++ self.assertEquals(disco_item.get_node(), "IMAP/" + account11.name + "/INBOX"
++ + "/dir2")
++ self.assertEquals(disco_item.get_name(), "dir2")
++
++ def test_disco_get_items_subdir_imap_account(self):
++ account11 = MockIMAPAccount(user=User(jid="user1@test.com"),
++ name="account11",
++ jid="account11@jcl.test.com")
++ info_query = Iq(stanza_type="get",
++ from_jid="user1@test.com",
++ to_jid="account11@jcl.test.com/IMAP")
++ disco_items = self.comp.disco_get_items("IMAP/account11/INBOX/dir1", info_query)
++ self.assertEquals(len(disco_items.get_items()), 2)
++ disco_item = disco_items.get_items()[0]
++ self.assertEquals(unicode(disco_item.get_jid()), unicode(account11.jid)
++ + "/IMAP/INBOX/dir1/subdir1")
++ self.assertEquals(disco_item.get_node(), "IMAP/" + account11.name + "/INBOX"
++ + "/dir1/subdir1")
++ self.assertEquals(disco_item.get_name(), "subdir1")
++ disco_item = disco_items.get_items()[1]
++ self.assertEquals(unicode(disco_item.get_jid()), unicode(account11.jid)
++ + "/IMAP/INBOX/dir1/subdir2")
++ self.assertEquals(disco_item.get_node(), "IMAP/" + account11.name + "/INBOX"
++ + "/dir1/subdir2")
++ self.assertEquals(disco_item.get_name(), "subdir2")
++
++ def test_account_get_register_imap_dir_already_registered(self):
++ model.db_connect()
++ self.comp.stream = MockStream()
++ self.comp.stream_class = MockStream
++ user1 = User(jid="user1@test.com")
++ account1 = MockIMAPAccount(user=user1,
++ name="account1",
++ jid="account1@jcl.test.com")
++ account1.mailbox = "INBOX"
++ account11 = MockIMAPAccount(user=user1,
++ name="account11",
++ jid="account11@jcl.test.com")
++ account11.mailbox = "INBOX/dir1"
++ account11.password = "pass1"
++ account11.port = 993
++ account11.host = "host1"
++ account11.login = "login1"
++ account11.ssl = True
++ account11.interval = 1
++ account11.store_password = False
++ account11.live_email_only = True
++ account11.chat_action = PresenceAccount.DO_NOTHING
++ account11.online_action = PresenceAccount.DO_NOTHING
++ account11.away_action = PresenceAccount.DO_NOTHING
++ account11.xa_action = PresenceAccount.DO_NOTHING
++ account11.dnd_action = PresenceAccount.DO_NOTHING
++ account11.offline_action = PresenceAccount.DO_NOTHING
++ account21 = MockIMAPAccount(user=User(jid="user2@test.com"),
++ name="account21",
++ jid="account21@jcl.test.com")
++ model.db_disconnect()
++ self.comp.handle_get_register(Iq(stanza_type="get",
++ from_jid="user1@test.com",
++ to_jid="account1@jcl.test.com/IMAP/INBOX/dir1"))
++ self.assertEquals(len(self.comp.stream.sent), 1)
++ iq_sent = self.comp.stream.sent[0]
++ self.assertEquals(iq_sent.get_to(), "user1@test.com")
++ titles = iq_sent.xpath_eval("jir:query/jxd:x/jxd:title",
++ {"jir" : "jabber:iq:register",
++ "jxd" : "jabber:x:data"})
++ self.assertEquals(len(titles), 1)
++ self.assertEquals(titles[0].content,
++ Lang.en.register_title)
++ instructions = iq_sent.xpath_eval("jir:query/jxd:x/jxd:instructions",
++ {"jir" : "jabber:iq:register",
++ "jxd" : "jabber:x:data"})
++ self.assertEquals(len(instructions), 1)
++ self.assertEquals(instructions[0].content,
++ Lang.en.register_instructions)
++ fields = iq_sent.xpath_eval("jir:query/jxd:x/jxd:field",
++ {"jir" : "jabber:iq:register",
++ "jxd" : "jabber:x:data"})
++ self.assertEquals(len(fields), 16)
++ field = fields[0]
++ self.assertEquals(field.prop("type"), "hidden")
++ self.assertEquals(field.prop("var"), "name")
++ self.assertEquals(field.prop("label"), Lang.en.account_name)
++ self.assertEquals(field.children.name, "value")
++ self.assertEquals(field.children.content, "account11")
++ self.assertEquals(field.children.next.name, "required")
++ field = fields[1]
++ self.assertEquals(field.prop("type"), "list-single")
++ self.assertEquals(field.prop("var"), "chat_action")
++ self.assertEquals(field.prop("label"), Lang.en.field_chat_action)
++ self.assertEquals(field.children.name, "value")
++ self.assertEquals(field.children.content, "0")
++ field = fields[2]
++ self.assertEquals(field.prop("type"), "list-single")
++ self.assertEquals(field.prop("var"), "online_action")
++ self.assertEquals(field.prop("label"), Lang.en.field_online_action)
++ self.assertEquals(field.children.name, "value")
++ self.assertEquals(field.children.content, "0")
++ field = fields[3]
++ self.assertEquals(field.prop("type"), "list-single")
++ self.assertEquals(field.prop("var"), "away_action")
++ self.assertEquals(field.prop("label"), Lang.en.field_away_action)
++ self.assertEquals(field.children.name, "value")
++ self.assertEquals(field.children.content, "0")
++ field = fields[4]
++ self.assertEquals(field.prop("type"), "list-single")
++ self.assertEquals(field.prop("var"), "xa_action")
++ self.assertEquals(field.prop("label"), Lang.en.field_xa_action)
++ self.assertEquals(field.children.name, "value")
++ self.assertEquals(field.children.content, "0")
++ field = fields[5]
++ self.assertEquals(field.prop("type"), "list-single")
++ self.assertEquals(field.prop("var"), "dnd_action")
++ self.assertEquals(field.prop("label"), Lang.en.field_dnd_action)
++ self.assertEquals(field.children.name, "value")
++ self.assertEquals(field.children.content, "0")
++ field = fields[6]
++ self.assertEquals(field.prop("type"), "list-single")
++ self.assertEquals(field.prop("var"), "offline_action")
++ self.assertEquals(field.prop("label"), Lang.en.field_offline_action)
++ self.assertEquals(field.children.name, "value")
++ self.assertEquals(field.children.content, "0")
++ field = fields[7]
++ self.assertEquals(field.prop("type"), "text-single")
++ self.assertEquals(field.prop("var"), "login")
++ self.assertEquals(field.prop("label"), Lang.en.field_login)
++ self.assertEquals(field.children.name, "value")
++ self.assertEquals(field.children.content, "login1")
++ self.assertEquals(field.children.next.name, "required")
++ field = fields[8]
++ self.assertEquals(field.prop("type"), "text-private")
++ self.assertEquals(field.prop("var"), "password")
++ self.assertEquals(field.prop("label"), Lang.en.field_password)
++ self.assertEquals(field.children.name, "value")
++ self.assertEquals(field.children.content, "pass1")
++ field = fields[9]
++ self.assertEquals(field.prop("type"), "text-single")
++ self.assertEquals(field.prop("var"), "host")
++ self.assertEquals(field.prop("label"), Lang.en.field_host)
++ self.assertEquals(field.children.name, "value")
++ self.assertEquals(field.children.content, "host1")
++ self.assertEquals(field.children.next.name, "required")
++ field = fields[10]
++ self.assertEquals(field.prop("type"), "text-single")
++ self.assertEquals(field.prop("var"), "port")
++ self.assertEquals(field.prop("label"), Lang.en.field_port)
++ self.assertEquals(field.children.name, "value")
++ self.assertEquals(field.children.content, "993")
++ field = fields[11]
++ self.assertEquals(field.prop("type"), "boolean")
++ self.assertEquals(field.prop("var"), "ssl")
++ self.assertEquals(field.prop("label"), Lang.en.field_ssl)
++ self.assertEquals(field.children.name, "value")
++ self.assertEquals(field.children.content, "1")
++ field = fields[12]
++ self.assertEquals(field.prop("type"), "boolean")
++ self.assertEquals(field.prop("var"), "store_password")
++ self.assertEquals(field.prop("label"), Lang.en.field_store_password)
++ self.assertEquals(field.children.name, "value")
++ self.assertEquals(field.children.content, "0")
++ field = fields[13]
++ self.assertEquals(field.prop("type"), "boolean")
++ self.assertEquals(field.prop("var"), "live_email_only")
++ self.assertEquals(field.prop("label"), Lang.en.field_live_email_only)
++ self.assertEquals(field.children.name, "value")
++ self.assertEquals(field.children.content, "1")
++ field = fields[14]
++ self.assertEquals(field.prop("type"), "text-single")
++ self.assertEquals(field.prop("var"), "interval")
++ self.assertEquals(field.prop("label"), Lang.en.field_interval)
++ self.assertEquals(field.children.name, "value")
++ self.assertEquals(field.children.content, "1")
++ field = fields[15]
++ self.assertEquals(field.prop("type"), "text-single")
++ self.assertEquals(field.prop("var"), "mailbox")
++ self.assertEquals(field.prop("label"), Lang.en.field_mailbox)
++ self.assertEquals(field.children.name, "value")
++ self.assertEquals(field.children.content, "INBOX/dir1")
++
++ def test_account_get_register_imap_dir_new(self):
++ model.db_connect()
++ self.comp.stream = MockStream()
++ self.comp.stream_class = MockStream
++ user1 = User(jid="user1@test.com")
++ account1 = MockIMAPAccount(user=user1,
++ name="account1",
++ jid="account1@jcl.test.com")
++ account1.maildir = "INBOX"
++ account1.password = "pass1"
++ account1.port = 993
++ account1.host = "host1"
++ account1.login = "login1"
++ account1.ssl = True
++ account1.interval = 1
++ account1.store_password = False
++ account1.live_email_only = True
++ account1.chat_action = PresenceAccount.DO_NOTHING
++ account1.online_action = PresenceAccount.DO_NOTHING
++ account1.away_action = PresenceAccount.DO_NOTHING
++ account1.xa_action = PresenceAccount.DO_NOTHING
++ account1.dnd_action = PresenceAccount.DO_NOTHING
++ account1.offline_action = PresenceAccount.DO_NOTHING
++ account11 = MockIMAPAccount(user=user1,
++ name="account11",
++ jid="account11@jcl.test.com")
++ account11.maildir = "INBOX/dir1"
++ account11.delimiter = "/"
++ account21 = MockIMAPAccount(user=User(jid="user2@test.com"),
++ name="account21",
++ jid="account21@jcl.test.com")
++ model.db_disconnect()
++ self.comp.handle_get_register(Iq(stanza_type="get",
++ from_jid="user1@test.com",
++ to_jid="account1@jcl.test.com/IMAP/INBOX/dir1/subdir1"))
++ self.assertEquals(len(self.comp.stream.sent), 1)
++ iq_sent = self.comp.stream.sent[0]
++ self.assertEquals(iq_sent.get_to(), "user1@test.com")
++ titles = iq_sent.xpath_eval("jir:query/jxd:x/jxd:title",
++ {"jir" : "jabber:iq:register",
++ "jxd" : "jabber:x:data"})
++ self.assertEquals(len(titles), 1)
++ self.assertEquals(titles[0].content,
++ Lang.en.register_title)
++ instructions = iq_sent.xpath_eval("jir:query/jxd:x/jxd:instructions",
++ {"jir" : "jabber:iq:register",
++ "jxd" : "jabber:x:data"})
++ self.assertEquals(len(instructions), 1)
++ self.assertEquals(instructions[0].content,
++ Lang.en.register_instructions)
++ fields = iq_sent.xpath_eval("jir:query/jxd:x/jxd:field",
++ {"jir" : "jabber:iq:register",
++ "jxd" : "jabber:x:data"})
++ self.assertEquals(len(fields), 16)
++ field = fields[0]
++ self.assertEquals(field.prop("type"), "text-single")
++ self.assertEquals(field.prop("var"), "name")
++ self.assertEquals(field.prop("label"), Lang.en.account_name)
++ self.assertEquals(field.children.name, "required")
++ self.assertEquals(field.children.next, None)
++ field = fields[1]
++ self.assertEquals(field.prop("type"), "list-single")
++ self.assertEquals(field.prop("var"), "chat_action")
++ self.assertEquals(field.prop("label"), Lang.en.field_chat_action)
++ self.assertEquals(field.children.name, "value")
++ self.assertEquals(field.children.content, "0")
++ field = fields[2]
++ self.assertEquals(field.prop("type"), "list-single")
++ self.assertEquals(field.prop("var"), "online_action")
++ self.assertEquals(field.prop("label"), Lang.en.field_online_action)
++ self.assertEquals(field.children.name, "value")
++ self.assertEquals(field.children.content, "0")
++ field = fields[3]
++ self.assertEquals(field.prop("type"), "list-single")
++ self.assertEquals(field.prop("var"), "away_action")
++ self.assertEquals(field.prop("label"), Lang.en.field_away_action)
++ self.assertEquals(field.children.name, "value")
++ self.assertEquals(field.children.content, "0")
++ field = fields[4]
++ self.assertEquals(field.prop("type"), "list-single")
++ self.assertEquals(field.prop("var"), "xa_action")
++ self.assertEquals(field.prop("label"), Lang.en.field_xa_action)
++ self.assertEquals(field.children.name, "value")
++ self.assertEquals(field.children.content, "0")
++ field = fields[5]
++ self.assertEquals(field.prop("type"), "list-single")
++ self.assertEquals(field.prop("var"), "dnd_action")
++ self.assertEquals(field.prop("label"), Lang.en.field_dnd_action)
++ self.assertEquals(field.children.name, "value")
++ self.assertEquals(field.children.content, "0")
++ field = fields[6]
++ self.assertEquals(field.prop("type"), "list-single")
++ self.assertEquals(field.prop("var"), "offline_action")
++ self.assertEquals(field.prop("label"), Lang.en.field_offline_action)
++ self.assertEquals(field.children.name, "value")
++ self.assertEquals(field.children.content, "0")
++ field = fields[7]
++ self.assertEquals(field.prop("type"), "text-single")
++ self.assertEquals(field.prop("var"), "login")
++ self.assertEquals(field.prop("label"), Lang.en.field_login)
++ self.assertEquals(field.children.name, "value")
++ self.assertEquals(field.children.content, "login1")
++ self.assertEquals(field.children.next.name, "required")
++ field = fields[8]
++ self.assertEquals(field.prop("type"), "text-private")
++ self.assertEquals(field.prop("var"), "password")
++ self.assertEquals(field.prop("label"), Lang.en.field_password)
++ self.assertEquals(field.children.name, "value")
++ self.assertEquals(field.children.content, "pass1")
++ field = fields[9]
++ self.assertEquals(field.prop("type"), "text-single")
++ self.assertEquals(field.prop("var"), "host")
++ self.assertEquals(field.prop("label"), Lang.en.field_host)
++ self.assertEquals(field.children.name, "value")
++ self.assertEquals(field.children.content, "host1")
++ self.assertEquals(field.children.next.name, "required")
++ field = fields[10]
++ self.assertEquals(field.prop("type"), "text-single")
++ self.assertEquals(field.prop("var"), "port")
++ self.assertEquals(field.prop("label"), Lang.en.field_port)
++ self.assertEquals(field.children.name, "value")
++ self.assertEquals(field.children.content, "993")
++ field = fields[11]
++ self.assertEquals(field.prop("type"), "boolean")
++ self.assertEquals(field.prop("var"), "ssl")
++ self.assertEquals(field.prop("label"), Lang.en.field_ssl)
++ self.assertEquals(field.children.name, "value")
++ self.assertEquals(field.children.content, "1")
++ field = fields[12]
++ self.assertEquals(field.prop("type"), "boolean")
++ self.assertEquals(field.prop("var"), "store_password")
++ self.assertEquals(field.prop("label"), Lang.en.field_store_password)
++ self.assertEquals(field.children.name, "value")
++ self.assertEquals(field.children.content, "0")
++ field = fields[13]
++ self.assertEquals(field.prop("type"), "boolean")
++ self.assertEquals(field.prop("var"), "live_email_only")
++ self.assertEquals(field.prop("label"), Lang.en.field_live_email_only)
++ self.assertEquals(field.children.name, "value")
++ self.assertEquals(field.children.content, "1")
++ field = fields[14]
++ self.assertEquals(field.prop("type"), "text-single")
++ self.assertEquals(field.prop("var"), "interval")
++ self.assertEquals(field.prop("label"), Lang.en.field_interval)
++ self.assertEquals(field.children.name, "value")
++ self.assertEquals(field.children.content, "1")
++ field = fields[15]
++ self.assertEquals(field.prop("type"), "text-single")
++ self.assertEquals(field.prop("var"), "mailbox")
++ self.assertEquals(field.prop("label"), Lang.en.field_mailbox)
++ self.assertEquals(field.children.name, "value")
++ self.assertEquals(field.children.content, "INBOX/dir1/subdir1")
++
++ def test_account_get_register_imap_dir_new(self):
++ model.db_connect()
++ self.comp.stream = MockStream()
++ self.comp.stream_class = MockStream
++ user1 = User(jid="user1@test.com")
++ account1 = MockIMAPAccount(user=user1,
++ name="account1",
++ jid="account1@jcl.test.com")
++ account1.maildir = "INBOX"
++ account1.password = "pass1"
++ account1.port = 993
++ account1.host = "host1"
++ account1.login = "login1"
++ account1.ssl = True
++ account1.interval = 1
++ account1.store_password = False
++ account1.live_email_only = True
++ account1.chat_action = PresenceAccount.DO_NOTHING
++ account1.online_action = PresenceAccount.DO_NOTHING
++ account1.away_action = PresenceAccount.DO_NOTHING
++ account1.xa_action = PresenceAccount.DO_NOTHING
++ account1.dnd_action = PresenceAccount.DO_NOTHING
++ account1.offline_action = PresenceAccount.DO_NOTHING
++ account11 = MockIMAPAccount(user=user1,
++ name="account11",
++ jid="account11@jcl.test.com")
++ account11.maildir = "INBOX/dir1"
++ account11.delimiter = "."
++ account21 = MockIMAPAccount(user=User(jid="user2@test.com"),
++ name="account21",
++ jid="account21@jcl.test.com")
++ model.db_disconnect()
++ self.comp.handle_get_register(Iq(stanza_type="get",
++ from_jid="user1@test.com",
++ to_jid="account1@jcl.test.com/IMAP/INBOX/dir1/subdir1"))
++ self.assertEquals(len(self.comp.stream.sent), 1)
++ iq_sent = self.comp.stream.sent[0]
++ self.assertEquals(iq_sent.get_to(), "user1@test.com")
++ titles = iq_sent.xpath_eval("jir:query/jxd:x/jxd:title",
++ {"jir" : "jabber:iq:register",
++ "jxd" : "jabber:x:data"})
++ self.assertEquals(len(titles), 1)
++ self.assertEquals(titles[0].content,
++ Lang.en.register_title)
++ instructions = iq_sent.xpath_eval("jir:query/jxd:x/jxd:instructions",
++ {"jir" : "jabber:iq:register",
++ "jxd" : "jabber:x:data"})
++ self.assertEquals(len(instructions), 1)
++ self.assertEquals(instructions[0].content,
++ Lang.en.register_instructions)
++ fields = iq_sent.xpath_eval("jir:query/jxd:x/jxd:field",
++ {"jir" : "jabber:iq:register",
++ "jxd" : "jabber:x:data"})
++ self.assertEquals(len(fields), 16)
++ field = fields[0]
++ self.assertEquals(field.prop("type"), "text-single")
++ self.assertEquals(field.prop("var"), "name")
++ self.assertEquals(field.prop("label"), Lang.en.account_name)
++ self.assertEquals(field.children.name, "required")
++ self.assertEquals(field.children.next, None)
++ field = fields[1]
++ self.assertEquals(field.prop("type"), "list-single")
++ self.assertEquals(field.prop("var"), "chat_action")
++ self.assertEquals(field.prop("label"), Lang.en.field_chat_action)
++ self.assertEquals(field.children.name, "value")
++ self.assertEquals(field.children.content, "0")
++ field = fields[2]
++ self.assertEquals(field.prop("type"), "list-single")
++ self.assertEquals(field.prop("var"), "online_action")
++ self.assertEquals(field.prop("label"), Lang.en.field_online_action)
++ self.assertEquals(field.children.name, "value")
++ self.assertEquals(field.children.content, "0")
++ field = fields[3]
++ self.assertEquals(field.prop("type"), "list-single")
++ self.assertEquals(field.prop("var"), "away_action")
++ self.assertEquals(field.prop("label"), Lang.en.field_away_action)
++ self.assertEquals(field.children.name, "value")
++ self.assertEquals(field.children.content, "0")
++ field = fields[4]
++ self.assertEquals(field.prop("type"), "list-single")
++ self.assertEquals(field.prop("var"), "xa_action")
++ self.assertEquals(field.prop("label"), Lang.en.field_xa_action)
++ self.assertEquals(field.children.name, "value")
++ self.assertEquals(field.children.content, "0")
++ field = fields[5]
++ self.assertEquals(field.prop("type"), "list-single")
++ self.assertEquals(field.prop("var"), "dnd_action")
++ self.assertEquals(field.prop("label"), Lang.en.field_dnd_action)
++ self.assertEquals(field.children.name, "value")
++ self.assertEquals(field.children.content, "0")
++ field = fields[6]
++ self.assertEquals(field.prop("type"), "list-single")
++ self.assertEquals(field.prop("var"), "offline_action")
++ self.assertEquals(field.prop("label"), Lang.en.field_offline_action)
++ self.assertEquals(field.children.name, "value")
++ self.assertEquals(field.children.content, "0")
++ field = fields[7]
++ self.assertEquals(field.prop("type"), "text-single")
++ self.assertEquals(field.prop("var"), "login")
++ self.assertEquals(field.prop("label"), Lang.en.field_login)
++ self.assertEquals(field.children.name, "value")
++ self.assertEquals(field.children.content, "login1")
++ self.assertEquals(field.children.next.name, "required")
++ field = fields[8]
++ self.assertEquals(field.prop("type"), "text-private")
++ self.assertEquals(field.prop("var"), "password")
++ self.assertEquals(field.prop("label"), Lang.en.field_password)
++ self.assertEquals(field.children.name, "value")
++ self.assertEquals(field.children.content, "pass1")
++ field = fields[9]
++ self.assertEquals(field.prop("type"), "text-single")
++ self.assertEquals(field.prop("var"), "host")
++ self.assertEquals(field.prop("label"), Lang.en.field_host)
++ self.assertEquals(field.children.name, "value")
++ self.assertEquals(field.children.content, "host1")
++ self.assertEquals(field.children.next.name, "required")
++ field = fields[10]
++ self.assertEquals(field.prop("type"), "text-single")
++ self.assertEquals(field.prop("var"), "port")
++ self.assertEquals(field.prop("label"), Lang.en.field_port)
++ self.assertEquals(field.children.name, "value")
++ self.assertEquals(field.children.content, "993")
++ field = fields[11]
++ self.assertEquals(field.prop("type"), "boolean")
++ self.assertEquals(field.prop("var"), "ssl")
++ self.assertEquals(field.prop("label"), Lang.en.field_ssl)
++ self.assertEquals(field.children.name, "value")
++ self.assertEquals(field.children.content, "1")
++ field = fields[12]
++ self.assertEquals(field.prop("type"), "boolean")
++ self.assertEquals(field.prop("var"), "store_password")
++ self.assertEquals(field.prop("label"), Lang.en.field_store_password)
++ self.assertEquals(field.children.name, "value")
++ self.assertEquals(field.children.content, "0")
++ field = fields[13]
++ self.assertEquals(field.prop("type"), "boolean")
++ self.assertEquals(field.prop("var"), "live_email_only")
++ self.assertEquals(field.prop("label"), Lang.en.field_live_email_only)
++ self.assertEquals(field.children.name, "value")
++ self.assertEquals(field.children.content, "1")
++ field = fields[14]
++ self.assertEquals(field.prop("type"), "text-single")
++ self.assertEquals(field.prop("var"), "interval")
++ self.assertEquals(field.prop("label"), Lang.en.field_interval)
++ self.assertEquals(field.children.name, "value")
++ self.assertEquals(field.children.content, "1")
++ field = fields[15]
++ self.assertEquals(field.prop("type"), "text-single")
++ self.assertEquals(field.prop("var"), "mailbox")
++ self.assertEquals(field.prop("label"), Lang.en.field_mailbox)
++ self.assertEquals(field.children.name, "value")
++ self.assertEquals(field.children.content, "INBOX.dir1.subdir1")
++
++class MailSender_TestCase(JCLTestCase):
++ def setUp(self):
++ JCLTestCase.setUp(self, tables=[Account, PresenceAccount, MailAccount,
++ IMAPAccount, POP3Account, User])
++
++ def test_create_message(self):
++ mail_sender = MailSender()
++ model.db_connect()
++ user1 = User(jid="test1@test.com")
++ account11 = IMAPAccount(user=user1,
++ name="account11",
++ jid="account11@jmc.test.com")
++ account11.online_action = MailAccount.RETRIEVE
++ account11.status = account.ONLINE
++ message = mail_sender.create_message(account11, ("from@test.com",
++ "subject",
++ "message body"))
++ self.assertEquals(message.get_to(), user1.jid)
++ model.db_disconnect()
++ self.assertEquals(message.get_subject(), "subject")
++ self.assertEquals(message.get_body(), "message body")
++ addresses = message.xpath_eval("add:addresses/add:address",
++ {"add": "http://jabber.org/protocol/address"})
++ self.assertEquals(len(addresses), 1)
++ self.assertEquals(addresses[0].prop("type"),
++ "replyto")
++ self.assertEquals(addresses[0].prop("jid"),
++ "from%test.com@jmc.test.com")
++
++ def test_create_message_missing_email_from(self):
++ mail_sender = MailSender()
++ model.db_connect()
++ user1 = User(jid="test1@test.com")
++ account11 = IMAPAccount(user=user1,
++ name="account11",
++ jid="account11@jmc.test.com")
++ account11.online_action = MailAccount.RETRIEVE
++ account11.status = account.ONLINE
++ message = mail_sender.create_message(account11, (None,
++ "subject",
++ "message body"))
++ self.assertEquals(message.get_to(), user1.jid)
++ self.assertEquals(message.get_subject(), "subject")
++ self.assertEquals(message.get_body(), "message body")
++ addresses = message.xpath_eval("add:addresses/add:address",
++ {"add": "http://jabber.org/protocol/address"})
++ self.assertEquals(addresses, [])
++
++ def test_create_message_digest(self):
++ mail_sender = MailSender()
++ model.db_connect()
++ user1 = User(jid="test1@test.com")
++ account11 = IMAPAccount(user=user1,
++ name="account11",
++ jid="account11@jmc.test.com")
++ account11.online_action = MailAccount.DIGEST
++ account11.status = account.ONLINE
++ message = mail_sender.create_message(account11, ("from@test.com",
++ "subject",
++ "message body"))
++ self.assertEquals(message.get_to(), user1.jid)
++ model.db_disconnect()
++ self.assertEquals(message.get_subject(), "subject")
++ self.assertEquals(message.get_body(), "message body")
++ self.assertEquals(message.get_type(), "headline")
++
++class MailHandler_TestCase(JCLTestCase):
++ def setUp(self, tables=[]):
++ self.handler = MailHandler(None)
++ JCLTestCase.setUp(self, tables=[Account, AbstractSMTPAccount,
++ GlobalSMTPAccount, SMTPAccount, User] \
++ + tables)
++
++ def test_filter(self):
++ model.db_connect()
++ user1 = User(jid="user1@test.com")
++ account11 = SMTPAccount(user=user1,
++ name="account11",
++ jid="account11@jcl.test.com")
++ account11.default_account = True
++ account12 = SMTPAccount(user=user1,
++ name="account12",
++ jid="account12@jcl.test.com")
++ message = Message(from_jid="user1@test.com",
++ to_jid="user2%test.com@jcl.test.com",
++ body="message")
++ accounts = self.handler.filter(message, None)
++ self.assertNotEquals(accounts, None)
++ i = 0
++ for _account in accounts:
++ i += 1
++ if i == 1:
++ self.assertEquals(_account.name, "account11")
++ self.assertEquals(i, 1)
++ model.db_disconnect()
++
++ def test_filter_root(self):
++ model.db_connect()
++ user1 = User(jid="user1@test.com")
++ account11 = SMTPAccount(user=user1,
++ name="account11",
++ jid="account11@jcl.test.com")
++ account11.default_account = True
++ account12 = SMTPAccount(user=user1,
++ name="account12",
++ jid="account12@jcl.test.com")
++ message = Message(from_jid="user1@test.com",
++ to_jid="jcl.test.com",
++ body="message")
++ accounts = self.handler.filter(message, None)
++ self.assertEquals(accounts, None)
++ model.db_disconnect()
++
++ def test_filter_no_default(self):
++ model.db_connect()
++ user1 = User(jid="user1@test.com")
++ account11 = SMTPAccount(user=user1,
++ name="account11",
++ jid="account11@jcl.test.com")
++ account12 = SMTPAccount(user=user1,
++ name="account12",
++ jid="account12@jcl.test.com")
++ message = Message(from_jid="user1@test.com",
++ to_jid="user2%test.com@jcl.test.com",
++ body="message")
++ accounts = self.handler.filter(message, None)
++ self.assertNotEquals(accounts, None)
++ i = 0
++ for _account in accounts:
++ i += 1
++ if i == 1:
++ self.assertEquals(_account.name, "account11")
++ else:
++ self.assertEquals(_account.name, "account12")
++ self.assertEquals(i, 2)
++ model.db_disconnect()
++
++ def test_filter_wrong_dest(self):
++ model.db_connect()
++ user1 = User(jid="user1@test.com")
++ account11 = SMTPAccount(user=user1,
++ name="account11",
++ jid="account11@jcl.test.com")
++ account12 = SMTPAccount(user=user1,
++ name="account12",
++ jid="account12@jcl.test.com")
++ message = Message(from_jid="user1@test.com",
++ to_jid="user2test.com@jcl.test.com",
++ body="message")
++ accounts = self.handler.filter(message, None)
++ self.assertEquals(accounts, None)
++ model.db_disconnect()
++
++ def test_filter_wrong_account(self):
++ model.db_connect()
++ user1 = User(jid="user1@test.com")
++ account11 = SMTPAccount(user=user1,
++ name="account11",
++ jid="account11@jcl.test.com")
++ account12 = SMTPAccount(user=user1,
++ name="account12",
++ jid="account12@jcl.test.com")
++ message = Message(from_jid="user3@test.com",
++ to_jid="user2%test.com@jcl.test.com",
++ body="message")
++ try:
++ accounts = self.handler.filter(message, None)
++ model.db_disconnect()
++ except NoAccountError, e:
++ model.db_disconnect()
++ self.assertNotEquals(e, None)
++ else:
++ self.fail("No exception 'NoAccountError' catched")
++
++class MailPresenceHandler_TestCase(unittest.TestCase):
++ def setUp(self):
++ self.handler = MailPresenceHandler(None)
++
++ def test_filter(self):
++ message = Message(from_jid="user1@test.com",
++ to_jid="user11%test.com@jcl.test.com",
++ body="message")
++ result = self.handler.filter(message, None)
++ self.assertNotEquals(result, None)
++
++ def test_filter_wrong_dest(self):
++ message = Message(from_jid="user1@test.com",
++ to_jid="user11@jcl.test.com",
++ body="message")
++ result = self.handler.filter(message, None)
++ self.assertEquals(result, None)
++
++ def test_filter_wrong_dest2(self):
++ message = Message(from_jid="user1@test.com",
++ to_jid="jcl.test.com",
++ body="message")
++ result = self.handler.filter(message, None)
++ self.assertEquals(result, None)
++
++class MailSubscribeHandler_TestCase(DefaultSubscribeHandler_TestCase, MailHandler_TestCase):
++ def setUp(self):
++ MailHandler_TestCase.setUp(self, tables=[LegacyJID])
++ self.handler = MailSubscribeHandler(None)
++
++ def test_handle(self):
++ model.db_connect()
++ account11 = SMTPAccount(user=User(jid="user1@test.com"),
++ name="account11",
++ jid="account11@jcl.test.com")
++ presence = Presence(from_jid="user1@test.com",
++ to_jid="user1%test.com@jcl.test.com",
++ stanza_type="subscribe")
++ result = self.handler.handle(presence, Lang.en, [account11])
++ legacy_jids = LegacyJID.select()
++ self.assertEquals(legacy_jids.count(), 1)
++ model.db_disconnect()
++
++class MailUnsubscribeHandler_TestCase(DefaultUnsubscribeHandler_TestCase, MailHandler_TestCase):
++ def setUp(self):
++ MailHandler_TestCase.setUp(self, tables=[LegacyJID])
++ self.handler = MailUnsubscribeHandler(None)
++
++ def test_handle(self):
++ model.db_connect()
++ user1 = User(jid="user1@test.com")
++ account11 = SMTPAccount(user=user1,
++ name="account11",
++ jid="account11@jcl.test.com")
++ account12 = SMTPAccount(user=user1,
++ name="account12",
++ jid="account12@jcl.test.com")
++ account2 = SMTPAccount(user=User(jid="user2@test.com"),
++ name="account2",
++ jid="account2@jcl.test.com")
++ presence = Presence(from_jid="user1@test.com",
++ to_jid="u111%test.com@jcl.test.com",
++ stanza_type="unsubscribe")
++ legacy_jid111 = LegacyJID(legacy_address="u111@test.com",
++ jid="u111%test.com@jcl.test.com",
++ account=account11)
++ legacy_jid112 = LegacyJID(legacy_address="u112@test.com",
++ jid="u112%test.com@jcl.test.com",
++ account=account11)
++ legacy_jid121 = LegacyJID(legacy_address="u121@test.com",
++ jid="u121%test.com@jcl.test.com",
++ account=account12)
++ legacy_jid122 = LegacyJID(legacy_address="u122@test.com",
++ jid="u122%test.com@jcl.test.com",
++ account=account12)
++ legacy_jid21 = LegacyJID(legacy_address="u21@test.com",
++ jid="u21%test.com@jcl.test.com",
++ account=account2)
++ result = self.handler.handle(presence, Lang.en, [account11])
++ legacy_jids = LegacyJID.select()
++ self.assertEquals(legacy_jids.count(), 4)
++ removed_legacy_jid = LegacyJID.select(\
++ LegacyJID.q.jid == "u111%test.com@jcl.test.com")
++ self.assertEquals(removed_legacy_jid.count(), 0)
++ model.db_disconnect()
++
++class MailFeederHandler_TestCase(JCLTestCase):
++ def setUp(self):
++ self.handler = MailFeederHandler(FeederMock(), SenderMock())
++ JCLTestCase.setUp(self, tables=[Account, PresenceAccount, MailAccount,
++ IMAPAccount, POP3Account, SMTPAccount,
++ GlobalSMTPAccount,
++ AbstractSMTPAccount, User])
++
++ def test_filter(self):
++ model.db_connect()
++ account11 = SMTPAccount(user=User(jid="user1@test.com"),
++ name="account11",
++ jid="account11@jcl.test.com")
++ account13 = IMAPAccount(user=User(jid="user3@test.com"),
++ name="account13",
++ jid="account13@jcl.test.com")
++ account12 = POP3Account(user=User(jid="user2@test.com"),
++ name="account12",
++ jid="account12@jcl.test.com")
++ accounts = self.handler.filter(None, None)
++ i = 0
++ # SQLObject > 0.8 is needed
++ for _account in accounts:
++ i += 1
++ if i == 1:
++ self.assertEquals(_account.name, "account13")
++ else:
++ self.assertEquals(_account.name, "account12")
++ self.assertEquals(i, 2)
++ model.db_disconnect()
++
++def suite():
++ test_suite = unittest.TestSuite()
++ test_suite.addTest(unittest.makeSuite(MailComponent_TestCase, 'test'))
++ test_suite.addTest(unittest.makeSuite(MailSender_TestCase, 'test'))
++ test_suite.addTest(unittest.makeSuite(MailHandler_TestCase, 'test'))
++ test_suite.addTest(unittest.makeSuite(MailUnsubscribeHandler_TestCase, 'test'))
++ test_suite.addTest(unittest.makeSuite(MailSubscribeHandler_TestCase, 'test'))
++ test_suite.addTest(unittest.makeSuite(MailPresenceHandler_TestCase, 'test'))
++ test_suite.addTest(unittest.makeSuite(MailFeederHandler_TestCase, 'test'))
++ return test_suite
++
++if __name__ == '__main__':
++ logger = logging.getLogger()
++ logger.addHandler(logging.StreamHandler())
++ if '-v' in sys.argv:
++ logger.setLevel(logging.INFO)
++ unittest.main(defaultTest='suite')
+--- /dev/null
++++ jmc-0.3b3/src/jmc/jabber/tests/presence.py
+@@ -0,0 +1,73 @@
++# -*- coding: utf-8 -*-
++##
++## presence.py
++## Login : <dax@happycoders.org>
++## Started on Thu Dec 6 08:19:59 2007 David Rousselie
++## $Id$
++##
++## Copyright (C) 2007 David Rousselie
++## This program 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 2 of the License, or
++## (at your option) any later version.
++##
++## This program 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 this program; if not, write to the Free Software
++## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++##
++
++import unittest
++import time
++
++from pyxmpp.iq import Iq
++
++from jcl.model.account import User, LegacyJID, Account
++from jcl.tests import JCLTestCase
++
++from jmc.jabber.component import MailComponent
++from jmc.jabber.presence import MailAccountIQLastHandler
++
++class MailAccountIQLastHandler_TestCase(JCLTestCase):
++ def setUp(self):
++ JCLTestCase.setUp(self, tables=[User, LegacyJID, Account])
++ self.comp = MailComponent("jmc.test.com",
++ "password",
++ "localhost",
++ "5347",
++ None, None)
++ self.handler = MailAccountIQLastHandler(self.comp)
++
++ def test_handle(self):
++ user1 = User(jid="user1@test.com")
++ account11 = Account(user=user1,
++ name="account11",
++ jid="account11@jcl.test.com")
++ account12 = Account(user=user1,
++ name="account12",
++ jid="account12@jcl.test.com")
++ info_query = Iq(from_jid="user1@test.com",
++ to_jid="account11@jcl.test.com",
++ stanza_type="get")
++ account11.lastcheck = int(time.time())
++ time.sleep(1)
++ result = self.handler.handle(info_query, None, account11)
++ self.assertEquals(len(result), 1)
++ self.assertEquals(result[0].get_to(), "user1@test.com")
++ self.assertEquals(result[0].get_from(), "account11@jcl.test.com")
++ self.assertEquals(result[0].get_type(), "result")
++ self.assertNotEquals(result[0].xmlnode.children, None)
++ self.assertEquals(result[0].xmlnode.children.name, "query")
++ self.assertEquals(int(result[0].xmlnode.children.prop("seconds")), 1)
++
++def suite():
++ test_suite = unittest.TestSuite()
++ test_suite.addTest(unittest.makeSuite(MailAccountIQLastHandler_TestCase, 'test'))
++ return test_suite
++
++if __name__ == '__main__':
++ unittest.main(defaultTest='suite')
+--- /dev/null
++++ jmc-0.3b3/src/jmc/jabber/tests/__init__.py
+@@ -0,0 +1,18 @@
++"""JMC test module"""
++__revision__ = ""
++
++import unittest
++
++from jmc.jabber.tests import component, disco, command, message, presence
++
++def suite():
++ test_suite = unittest.TestSuite()
++ test_suite.addTest(component.suite())
++ test_suite.addTest(disco.suite())
++ test_suite.addTest(command.suite())
++ test_suite.addTest(message.suite())
++ test_suite.addTest(presence.suite())
++ return test_suite
++
++if __name__ == '__main__':
++ unittest.main(defaultTest='suite')
+--- /dev/null
++++ jmc-0.3b3/src/jmc/jabber/tests/message.py
+@@ -0,0 +1,256 @@
++##
++## message.py
++## Login : <dax@happycoders.org>
++## Started on Tue Nov 6 19:00:22 2007 David Rousselie
++## $Id$
++##
++## Copyright (C) 2007 David Rousselie
++## This program 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 2 of the License, or
++## (at your option) any later version.
++##
++## This program 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 this program; if not, write to the Free Software
++## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++##
++
++import unittest
++import re
++
++from pyxmpp.message import Message
++
++from jcl.tests import JCLTestCase
++from jcl.model.account import Account, User
++
++from jmc.model.account import GlobalSMTPAccount, AbstractSMTPAccount, \
++ SMTPAccount
++from jmc.jabber.message import SendMailMessageHandler, \
++ RootSendMailMessageHandler
++from jmc.lang import Lang
++
++class MockSMTPAccount(object):
++ def __init__(self):
++ self.email_sent = 0
++ self.default_from = "user1@test.com"
++ self.email = None
++
++ def send_email(self, email):
++ self.email = email
++ self.email_sent += 1
++
++ def create_email(self, from_addr, to_addr, subject, body,
++ other_headers=None):
++ return (from_addr, to_addr, subject, body, other_headers)
++
++class SendMailMessageHandler_TestCase(unittest.TestCase):
++ def setUp(self):
++ self.handler = SendMailMessageHandler(None)
++
++ def test_get_email_to_headers_from_message(self):
++ to_regexp = re.compile("^\s*(?i)to\s*:\s*(?P<to_email>.*)")
++ (message, to_header) = self.handler.get_email_headers_from_message(\
++ "To: dest@test.com\ntest body\n", [to_regexp], ["to_email"])
++ self.assertEquals(message, "test body\n")
++ self.assertEquals(to_header, ["dest@test.com"])
++
++ def test_get_email_headers_from_message(self):
++ to_regexp = re.compile("^\s*(?i)to\s*:\s*(?P<to_email>.*)")
++ cc_regexp = re.compile("^\s*(?i)cc\s*:\s*(?P<cc_email>.*)")
++ bcc_regexp = re.compile("^\s*(?i)bcc\s*:\s*(?P<bcc_email>.*)")
++ subject_regexp = re.compile("^\s*(?i)subject\s*:\s*(?P<subject_email>.*)")
++ (message, headers) = self.handler.get_email_headers_from_message(\
++ "To: dest@test.com\nCc: cc@test.com\n"
++ + "Bcc: bcc@test.com\n"
++ + "Subject: test subject\ntest body\n",
++ [to_regexp, cc_regexp, bcc_regexp, subject_regexp],
++ ["to_email", "cc_email", "bcc_email", "subject_email"])
++ self.assertEquals(message, "test body\n")
++ self.assertEquals(headers, ["dest@test.com",
++ "cc@test.com",
++ "bcc@test.com",
++ "test subject"])
++
++ def test_get_email_headers_from_message_unordered(self):
++ to_regexp = re.compile("^\s*(?i)to\s*:\s*(?P<to_email>.*)")
++ cc_regexp = re.compile("^\s*(?i)cc\s*:\s*(?P<cc_email>.*)")
++ bcc_regexp = re.compile("^\s*(?i)bcc\s*:\s*(?P<bcc_email>.*)")
++ subject_regexp = re.compile("^\s*(?i)subject\s*:\s*(?P<subject_email>.*)")
++ (message, headers) = self.handler.get_email_headers_from_message(\
++ "To: dest@test.com\nCc: cc@test.com\n"
++ + "Bcc: bcc@test.com\n"
++ + "Subject: test subject\ntest body\n",
++ [cc_regexp, to_regexp, subject_regexp, bcc_regexp],
++ ["cc_email", "to_email", "subject_email", "bcc_email"])
++ self.assertEquals(message, "test body\n")
++ self.assertEquals(headers, ["cc@test.com",
++ "dest@test.com",
++ "test subject",
++ "bcc@test.com"])
++
++ def test_handle(self):
++ mock_account = MockSMTPAccount()
++ message = Message(from_jid="user1@test.com",
++ to_jid="real_dest%test.com@jmc.test.com",
++ subject="real subject",
++ body="To: dest@test.com\nCc: cc@test.com\n" \
++ + "Bcc: bcc@test.com\n" \
++ + "Subject: test subject\ntest body\n")
++ result = self.handler.handle(\
++ message, Lang.en, [mock_account])
++ self.assertEquals(len(result), 1)
++ self.assertEquals(result[0].stanza_type, "message")
++ self.assertEquals(result[0].get_from(), "real_dest%test.com@jmc.test.com")
++ self.assertEquals(result[0].get_to(), "user1@test.com")
++ self.assertEquals(result[0].get_subject(),
++ Lang.en.send_mail_ok_subject)
++ self.assertEquals(result[0].get_body(),
++ Lang.en.send_mail_ok_body % \
++ ("real_dest@test.com, dest@test.com"))
++ self.assertEquals(mock_account.email_sent, 1)
++ self.assertEquals(mock_account.email[0], "user1@test.com")
++ self.assertEquals(mock_account.email[1], "real_dest@test.com, dest@test.com")
++ self.assertEquals(mock_account.email[2], "real subject")
++ self.assertEquals(mock_account.email[3], "test body\n")
++ self.assertEquals(mock_account.email[4], {u"Bcc": "bcc@test.com",
++ u"Cc": "cc@test.com"})
++
++class RootSendMailMessageHandler_TestCase(JCLTestCase):
++ def setUp(self):
++ JCLTestCase.setUp(self, tables=[Account, GlobalSMTPAccount,
++ AbstractSMTPAccount,
++ SMTPAccount, User])
++ self.handler = RootSendMailMessageHandler(None)
++
++ def test_filter(self):
++ user1 = User(jid="user1@test.com")
++ account11 = SMTPAccount(user=user1,
++ name="account11",
++ jid="account11@jmc.test.com")
++ account11.default_account = True
++ account12 = SMTPAccount(user=user1,
++ name="account12",
++ jid="account12@jmc.test.com")
++ message = Message(from_jid="user1@test.com",
++ to_jid="account11@jmc.test.com",
++ body="message")
++ accounts = self.handler.filter(message, None)
++ self.assertEquals(accounts.count(), 1)
++
++ def test_filter_no_default_account(self):
++ user1 = User(jid="user1@test.com")
++ account11 = SMTPAccount(user=user1,
++ name="account11",
++ jid="account11@jmc.test.com")
++ account12 = SMTPAccount(user=user1,
++ name="account12",
++ jid="account12@jmc.test.com")
++ message = Message(from_jid="user1@test.com",
++ to_jid="account11@jmc.test.com",
++ body="message")
++ accounts = self.handler.filter(message, None)
++ self.assertEquals(accounts.count(), 2)
++ self.assertEquals(accounts[0].name, "account11")
++
++ def test_filter_wrong_dest(self):
++ user1 = User(jid="user1@test.com")
++ account11 = SMTPAccount(user=user1,
++ name="account11",
++ jid="account11@jmc.test.com")
++ account12 = SMTPAccount(user=user1,
++ name="account12",
++ jid="account12@jmc.test.com")
++ message = Message(from_jid="user1@test.com",
++ to_jid="user2%test.com@jmc.test.com",
++ body="message")
++ accounts = self.handler.filter(message, None)
++ self.assertEquals(accounts.count(), 2)
++
++ def test_filter_wrong_user(self):
++ user1 = User(jid="user1@test.com")
++ account11 = SMTPAccount(user=user1,
++ name="account11",
++ jid="account11@jmc.test.com")
++ account12 = SMTPAccount(user=user1,
++ name="account12",
++ jid="account12@jmc.test.com")
++ message = Message(from_jid="user2@test.com",
++ to_jid="account11@jmc.test.com",
++ body="message")
++ accounts = self.handler.filter(message, None)
++ self.assertEquals(accounts.count(), 0)
++
++ def test_handle(self):
++ mock_account = MockSMTPAccount()
++ message = Message(from_jid="user1@test.com",
++ to_jid="jmc.test.com",
++ subject="real subject",
++ body="To: dest@test.com\nCc: cc@test.com\n" \
++ + "Bcc: bcc@test.com\n" \
++ + "Subject: test subject\ntest body\n")
++ result = self.handler.handle(\
++ message, Lang.en, [mock_account])
++ self.assertEquals(len(result), 1)
++ self.assertEquals(result[0].get_type(), None)
++ self.assertEquals(result[0].get_from(), "jmc.test.com")
++ self.assertEquals(result[0].get_to(), "user1@test.com")
++ self.assertEquals(result[0].get_subject(),
++ Lang.en.send_mail_ok_subject)
++ self.assertEquals(result[0].get_body(),
++ Lang.en.send_mail_ok_body % ("dest@test.com"))
++ self.assertEquals(mock_account.email_sent, 1)
++ self.assertEquals(mock_account.email[0], "user1@test.com")
++ self.assertEquals(mock_account.email[1], "dest@test.com")
++ self.assertEquals(mock_account.email[2], "real subject")
++ self.assertEquals(mock_account.email[3], "test body\n")
++ self.assertEquals(mock_account.email[4], {u"Bcc": "bcc@test.com",
++ u"Cc": "cc@test.com"})
++
++ def test_handle_email_not_found_in_header(self):
++ message = Message(from_jid="user1@test.com",
++ to_jid="jmc.test.com",
++ subject="message subject",
++ body="message body")
++ accounts = [MockSMTPAccount()]
++ result = self.handler.handle(message, Lang.en, accounts)
++ self.assertEquals(len(result), 1)
++ self.assertEquals(result[0].get_type(), "error")
++ self.assertEquals(result[0].get_from(), "jmc.test.com")
++ self.assertEquals(result[0].get_to(), "user1@test.com")
++ self.assertEquals(result[0].get_subject(),
++ Lang.en.send_mail_error_no_to_header_subject)
++ self.assertEquals(result[0].get_body(),
++ Lang.en.send_mail_error_no_to_header_body)
++
++ def test_handle_no_jabber_subject(self):
++ mock_account = MockSMTPAccount()
++ message = Message(from_jid="user1@test.com",
++ to_jid="jmc.test.com",
++ subject="",
++ body="To: dest@test.com\nCc: cc@test.com\n" \
++ + "Bcc: bcc@test.com\n" \
++ + "Subject: test subject\ntest body\n")
++ message_to_send = self.handler.handle(\
++ message, Lang.en, [mock_account])
++ self.assertNotEquals(message_to_send, None)
++ self.assertEquals(mock_account.email_sent, 1)
++ self.assertEquals(mock_account.email[0], "user1@test.com")
++ self.assertEquals(mock_account.email[1], "dest@test.com")
++ self.assertEquals(mock_account.email[2], "test subject")
++ self.assertEquals(mock_account.email[3], "test body\n")
++ self.assertEquals(mock_account.email[4], {u"Bcc": "bcc@test.com",
++ u"Cc": "cc@test.com"})
++
++def suite():
++ test_suite = unittest.TestSuite()
++ test_suite.addTest(unittest.makeSuite(SendMailMessageHandler_TestCase, 'test'))
++ test_suite.addTest(unittest.makeSuite(RootSendMailMessageHandler_TestCase, 'test'))
++ return test_suite
++
++if __name__ == '__main__':
++ unittest.main(defaultTest='suite')
+--- /dev/null
++++ jmc-0.3b3/src/jmc/jabber/tests/command.py
+@@ -0,0 +1,595 @@
++# -*- coding: utf-8 -*-
++##
++## command.py
++## Login : David Rousselie <dax@happycoders.org>
++## Started on Tue Oct 23 18:53:28 2007 David Rousselie
++## $Id$
++##
++## Copyright (C) 2007 David Rousselie
++## This program 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 2 of the License, or
++## (at your option) any later version.
++##
++## This program 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 this program; if not, write to the Free Software
++## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++##
++
++import unittest
++import tempfile
++from ConfigParser import ConfigParser
++import os
++import sys
++import logging
++import time
++
++from pyxmpp.iq import Iq
++from pyxmpp.jabber.dataforms import Field
++import pyxmpp.xmlextra
++
++import jcl.tests
++from jcl.tests import JCLTestCase
++from jcl.jabber.feeder import Feeder
++from jcl.model.account import User, Account, PresenceAccount
++from jcl.jabber.tests.command import JCLCommandManagerTestCase
++import jcl.jabber.command as command
++import jcl.jabber.tests.command
++
++from jmc.model.account import POP3Account, IMAPAccount, SMTPAccount, \
++ MailAccount, GlobalSMTPAccount, AbstractSMTPAccount
++from jmc.jabber.component import MailComponent
++from jmc.lang import Lang
++from jmc.jabber.tests.component import MockIMAPAccount
++from jmc.jabber.command import MailCommandManager
++
++PYXMPP_NS = pyxmpp.xmlextra.COMMON_NS
++
++class MailCommandManagerTestCase(JCLCommandManagerTestCase):
++ def setUp(self, tables=[]):
++ tables += [POP3Account, IMAPAccount, GlobalSMTPAccount,
++ AbstractSMTPAccount, SMTPAccount,
++ MailAccount, MockIMAPAccount, User, Account, PresenceAccount]
++ JCLTestCase.setUp(self, tables=tables)
++ self.config_file = tempfile.mktemp(".conf", "jmctest", jcl.tests.DB_DIR)
++ self.config = ConfigParser()
++ self.config.read(self.config_file)
++ self.comp = MailComponent("jmc.test.com",
++ "password",
++ "localhost",
++ "5347",
++ self.config,
++ self.config_file)
++ self.comp.set_admins(["admin@test.com"])
++ self.command_manager = MailCommandManager(self.comp,
++ self.comp.account_manager)
++ self.comp.account_manager.account_classes = (POP3Account, IMAPAccount,
++ GlobalSMTPAccount,
++ AbstractSMTPAccount,
++ SMTPAccount, MockIMAPAccount)
++ self.user1 = User(jid="test1@test.com")
++ self.account11 = MockIMAPAccount(user=self.user1,
++ name="account11",
++ jid="account11@" + unicode(self.comp.jid))
++ self.account12 = MockIMAPAccount(user=self.user1,
++ name="account12",
++ jid="account12@" + unicode(self.comp.jid))
++ self.user2 = User(jid="test2@test.com")
++ self.account21 = MockIMAPAccount(user=self.user2,
++ name="account21",
++ jid="account21@" + unicode(self.comp.jid))
++ self.account22 = MockIMAPAccount(user=self.user2,
++ name="account11",
++ jid="account11@" + unicode(self.comp.jid))
++ self.user3 = User(jid="test3@test.com")
++ self.account31 = MockIMAPAccount(user=self.user3,
++ name="account31",
++ jid="account31@" + unicode(self.comp.jid))
++ self.account32 = MockIMAPAccount(user=self.user3,
++ name="account32",
++ jid="account32@" + unicode(self.comp.jid))
++ self.info_query = Iq(stanza_type="set",
++ from_jid="admin@test.com",
++ to_jid=self.comp.jid)
++ self.command_node = self.info_query.set_new_content(command.COMMAND_NS,
++ "command")
++ class MockFeederHandler(Feeder):
++ def __init__(self, component):
++ Feeder.__init__(self, component)
++ self.checked_accounts = []
++
++ def feed(self, _account):
++ self.checked_accounts.append(_account)
++ assert((int(time.time()) - _account.lastcheck \
++ >= (_account.interval * self.component.time_unit)))
++ return []
++
++ self.comp.tick_handlers[0].feeder = MockFeederHandler(self.comp)
++
++ def tearDown(self):
++ JCLTestCase.tearDown(self)
++ if os.path.exists(self.config_file):
++ os.unlink(self.config_file)
++
++class MailCommandManagerForceCheckCommand_TestCase(MailCommandManagerTestCase):
++ """
++ Test 'force-check' ad-hoc command
++ """
++
++ def setUp(self, tables=[]):
++ """
++ Prepare data
++ """
++ MailCommandManagerTestCase.setUp(self, tables)
++ self.command_node.setProp("node", "jmc#force-check")
++
++ def test_execute_force_check(self):
++ self.info_query.set_from("test1@test.com")
++ self.info_query.set_to("account11@" + unicode(self.comp.jid))
++ result = self.command_manager.apply_command_action(\
++ self.info_query,
++ "jmc#force-check",
++ "execute")
++ result_iq = result[0].xmlnode
++ result_iq.setNs(None)
++ self.assertTrue(jcl.tests.is_xml_equal(\
++ u"<iq from='account11@" + unicode(self.comp.jid)
++ + "' to='test1@test.com' type='result'>"
++ + "<command xmlns='http://jabber.org/protocol/commands' "
++ + "status='completed'>"
++ + "</command></iq>",
++ result_iq, True, test_sibling=False))
++ feeder = self.comp.tick_handlers[0].feeder
++ self.assertEquals(len(feeder.checked_accounts), 1)
++ self.assertEquals(feeder.checked_accounts[0], self.account11)
++
++ def test_execute_force_check_root_node(self):
++ self.info_query.set_from("test1@test.com")
++ result = self.command_manager.apply_command_action(\
++ self.info_query,
++ "jmc#force-check",
++ "execute")
++ result_iq = result[0].xmlnode
++ result_iq.setNs(None)
++ self.assertTrue(jcl.tests.is_xml_equal(\
++ u"<iq from='jmc.test.com' to='test1@test.com' type='result'>"
++ + "<command xmlns='http://jabber.org/protocol/commands'"
++ + "status='executing'>"
++ + "<actions execute='complete'><complete/></actions>"
++ + "<x xmlns='jabber:x:data' type='form'>"
++ + "<title>" + Lang.en.command_force_check + "</title>"
++ + "<instructions>" + Lang.en.command_force_check_1_description
++ + "</instructions>"
++ + "<field var='account_names' type='list-multi' label='"
++ + Lang.en.field_accounts + "'>"
++ + "<option label=\"account11 (IMAP)\">"
++ + "<value>account11/test1@test.com</value></option>"
++ + "<option label=\"account12 (IMAP)\">"
++ + "<value>account12/test1@test.com</value></option>"
++ + "<option label=\"account11 (MockIMAP)\">"
++ + "<value>account11/test1@test.com</value></option>"
++ + "<option label=\"account12 (MockIMAP)\">"
++ + "<value>account12/test1@test.com</value></option>"
++ + "</field></x></command></iq>",
++ result_iq, True))
++ session_id = result_iq.children.prop("sessionid")
++ self.assertNotEquals(session_id, None)
++ context_session = self.command_manager.sessions[session_id][1]
++ self.assertEquals(context_session["user_jids"],
++ ["test1@test.com"])
++
++ # Second step
++ info_query = jcl.jabber.tests.command.prepare_submit(\
++ node="jmc#force-check",
++ session_id=session_id,
++ from_jid="test1@test.com",
++ to_jid=unicode(self.comp.jid),
++ fields=[Field(field_type="list-multi",
++ name="account_names",
++ values=["account11/test1@test.com",
++ "account12/test1@test.com"])],
++ action="complete")
++ result = self.command_manager.apply_command_action(\
++ info_query,
++ "jmc#force-check",
++ "execute")
++ result_iq = result[0].xmlnode
++ result_iq.setNs(None)
++ self.assertTrue(jcl.tests.is_xml_equal(\
++ u"<iq from='" + unicode(self.comp.jid)
++ + "' to='test1@test.com' type='result'>"
++ + "<command xmlns='http://jabber.org/protocol/commands' "
++ + "status='completed'>"
++ + "</command></iq>",
++ result_iq, True, test_sibling=False))
++ self.assertEquals(context_session["account_names"],
++ ["account11/test1@test.com",
++ "account12/test1@test.com"])
++ feeder = self.comp.tick_handlers[0].feeder
++ self.assertEquals(len(feeder.checked_accounts), 2)
++ self.assertEquals(feeder.checked_accounts[0], self.account11)
++ self.assertEquals(feeder.checked_accounts[1], self.account12)
++
++class MailCommandManagerGetEmailCommand_TestCase(MailCommandManagerTestCase):
++ """
++ Test 'get-email' ad-hoc command
++ """
++
++ def setUp(self, tables=[]):
++ """
++ Prepare data
++ """
++ MailCommandManagerTestCase.setUp(self, tables)
++ self.command_node.setProp("node", "jmc#get-email")
++ def get_email(email_index):
++ """
++ Mock method for IMAPAccount.get_email
++ """
++ return ("mail body " + str(email_index),
++ "from" + str(email_index) + "@test.com")
++ self.account11.__dict__["get_mail"] = get_email
++
++ def check_step_1(self, result, options="<option label=\"mail 1\">" \
++ + "<value>1</value></option>" \
++ + "<option label=\"mail 2\">" \
++ + "<value>2</value></option>" \
++ + "<option label=\"mail 3\">" \
++ + "<value>3</value></option>" \
++ + "<option label=\"mail 4\">" \
++ + "<value>4</value></option>" \
++ + "<option label=\"mail 5\">" \
++ + "<value>5</value></option>" \
++ + "<option label=\"mail 6\">" \
++ + "<value>6</value></option>" \
++ + "<option label=\"mail 7\">" \
++ + "<value>7</value></option>" \
++ + "<option label=\"mail 8\">" \
++ + "<value>8</value></option>" \
++ + "<option label=\"mail 9\">" \
++ + "<value>9</value></option>" \
++ + "<option label=\"mail 10\">" \
++ + "<value>10</value></option>",
++ last_page=False):
++ """
++ Check first step result of get-email ad-hoc command
++ """
++ result_iq = result[0].xmlnode
++ result_iq.setNs(None)
++ xml_ref = u"<iq from='account11@" + unicode(self.comp.jid) \
++ + "' to='test1@test.com' type='result'>" \
++ + "<command xmlns='http://jabber.org/protocol/commands'" \
++ + "status='executing'>" \
++ + "<actions execute='complete'><complete/></actions>" \
++ + "<x xmlns='jabber:x:data' type='form'>" \
++ + "<title>" + Lang.en.command_get_email + "</title>" \
++ + "<instructions>" + Lang.en.command_get_email_1_description \
++ + "</instructions>" \
++ + "<field var='emails' type='list-multi' label='" \
++ + Lang.en.field_email_subject + "'>" \
++ + options
++ if not last_page:
++ xml_ref += "</field><field var='fetch_more' type='boolean' label='" \
++ + Lang.en.field_select_more_emails + "'>"
++ xml_ref += "</field></x></command></iq>"
++ self.assertTrue(jcl.tests.is_xml_equal(xml_ref, result_iq, True))
++ session_id = result_iq.children.prop("sessionid")
++ self.assertNotEquals(session_id, None)
++ self.assertTrue(self.account11.has_connected)
++ self.assertFalse(self.account11.connected)
++ self.account11.has_connected = False
++ return session_id
++
++ def check_email_message(self, result_iq, index):
++ """ """
++ self.assertTrue(jcl.tests.is_xml_equal(\
++ u"<message from='account11@" + unicode(self.comp.jid)
++ + "' to='test1@test.com' "
++ + "xmlns='" + PYXMPP_NS + "'>"
++ + "<subject>" + Lang.en.mail_subject \
++ % ("from" + str(index) + "@test.com")
++ + "</subject>"
++ + "<body>mail body " + str(index) + "</body>"
++ + "<addresses xmlns='http://jabber.org/protocol/address'>"
++ + "<address type='replyto' jid='from" + str(index)
++ + "%test.com@jmc.test.com'/>"
++ + "</addresses>"
++ + "</message>",
++ result_iq, True, test_sibling=False))
++
++ def test_execute_get_email(self):
++ """
++ Test single email retrieval
++ """
++ self.info_query.set_from("test1@test.com")
++ self.info_query.set_to("account11@" + unicode(self.comp.jid))
++ result = self.command_manager.apply_command_action(\
++ self.info_query,
++ "jmc#get-email",
++ "execute")
++ session_id = self.check_step_1(result)
++
++ # Second step
++ info_query = jcl.jabber.tests.command.prepare_submit(\
++ node="jmc#get-email",
++ session_id=session_id,
++ from_jid="test1@test.com",
++ to_jid="account11@jmc.test.com",
++ fields=[Field(field_type="list-multi",
++ name="emails",
++ values=["1"]),
++ Field(field_type="boolean",
++ name="fetch_more",
++ value=False)],
++ action="complete")
++ result = self.command_manager.apply_command_action(\
++ info_query,
++ "jmc#get-email",
++ "execute")
++ self.assertTrue(self.account11.has_connected)
++ self.assertFalse(self.account11.connected)
++ self.assertEquals(len(result), 2)
++ result_iq = result[0].xmlnode
++ result_iq.setNs(None)
++ self.assertTrue(jcl.tests.is_xml_equal(\
++ u"<iq from='account11@" + unicode(self.comp.jid)
++ + "' to='test1@test.com' type='result'>"
++ + "<command xmlns='http://jabber.org/protocol/commands' "
++ + "status='completed'>"
++ + "<x xmlns='jabber:x:data' type='form'>"
++ + "<title>" + Lang.en.command_get_email + "</title>"
++ + "<instructions>" + Lang.en.command_get_email_2_description
++ % (1) + "</instructions>"
++ + "</x></command></iq>",
++ result_iq, True, test_sibling=False))
++ result_iq = result[1].xmlnode
++ self.check_email_message(result_iq, 1)
++
++ def test_execute_get_emails(self):
++ """
++ Test multiple emails retrieval
++ """
++ self.info_query.set_from("test1@test.com")
++ self.info_query.set_to("account11@" + unicode(self.comp.jid))
++ result = self.command_manager.apply_command_action(\
++ self.info_query,
++ "jmc#get-email",
++ "execute")
++ session_id = self.check_step_1(result)
++
++ # Second step
++ info_query = jcl.jabber.tests.command.prepare_submit(\
++ node="jmc#get-email",
++ session_id=session_id,
++ from_jid="test1@test.com",
++ to_jid="account11@jmc.test.com",
++ fields=[Field(field_type="list-multi",
++ name="emails",
++ values=["1", "2"]),
++ Field(field_type="boolean",
++ name="fetch_more",
++ value=False)],
++ action="complete")
++ result = self.command_manager.apply_command_action(\
++ info_query,
++ "jmc#get-email",
++ "execute")
++ self.assertTrue(self.account11.has_connected)
++ self.assertFalse(self.account11.connected)
++ self.assertEquals(len(result), 3)
++ result_iq = result[0].xmlnode
++ result_iq.setNs(None)
++ self.assertTrue(jcl.tests.is_xml_equal(\
++ u"<iq from='account11@" + unicode(self.comp.jid)
++ + "' to='test1@test.com' type='result'>"
++ + "<command xmlns='http://jabber.org/protocol/commands' "
++ + "status='completed'>"
++ + "<x xmlns='jabber:x:data' type='form'>"
++ + "<title>" + Lang.en.command_get_email + "</title>"
++ + "<instructions>" + Lang.en.command_get_email_2_description
++ % (2) + "</instructions>"
++ + "</x></command></iq>",
++ result_iq, True, test_sibling=False))
++ result_iq = result[1].xmlnode
++ self.check_email_message(result_iq, 1)
++ result_iq = result[2].xmlnode
++ self.check_email_message(result_iq, 2)
++
++ def test_execute_get_emails_multi_pages(self):
++ """
++ Test multiple emails retrieval
++ """
++ self.info_query.set_from("test1@test.com")
++ self.info_query.set_to("account11@" + unicode(self.comp.jid))
++ result = self.command_manager.apply_command_action(\
++ self.info_query,
++ "jmc#get-email",
++ "execute")
++ session_id = self.check_step_1(result)
++
++ # Second step
++ info_query = jcl.jabber.tests.command.prepare_submit(\
++ node="jmc#get-email",
++ session_id=session_id,
++ from_jid="test1@test.com",
++ to_jid="account11@jmc.test.com",
++ fields=[Field(field_type="list-multi",
++ name="emails",
++ values=["1", "2"]),
++ Field(field_type="boolean",
++ name="fetch_more",
++ value=True)],
++ action="complete")
++ result = self.command_manager.apply_command_action(\
++ info_query,
++ "jmc#get-email",
++ "execute")
++ self.check_step_1(result, options="<option label=\"mail 11\">" \
++ + "<value>11</value></option>" \
++ + "<option label=\"mail 12\">" \
++ + "<value>12</value></option>" \
++ + "<option label=\"mail 13\">" \
++ + "<value>13</value></option>" \
++ + "<option label=\"mail 14\">" \
++ + "<value>14</value></option>" \
++ + "<option label=\"mail 15\">" \
++ + "<value>15</value></option>" \
++ + "<option label=\"mail 16\">" \
++ + "<value>16</value></option>" \
++ + "<option label=\"mail 17\">" \
++ + "<value>17</value></option>" \
++ + "<option label=\"mail 18\">" \
++ + "<value>18</value></option>" \
++ + "<option label=\"mail 19\">" \
++ + "<value>19</value></option>" \
++ + "<option label=\"mail 20\">" \
++ + "<value>20</value></option>")
++
++ # Third step
++ info_query = jcl.jabber.tests.command.prepare_submit(\
++ node="jmc#get-email",
++ session_id=session_id,
++ from_jid="test1@test.com",
++ to_jid="account11@jmc.test.com",
++ fields=[Field(field_type="list-multi",
++ name="emails",
++ values=["13", "14"]),
++ Field(field_type="boolean",
++ name="fetch_more",
++ value=False)],
++ action="complete")
++ result = self.command_manager.apply_command_action(\
++ info_query,
++ "jmc#get-email",
++ "execute")
++ self.assertTrue(self.account11.has_connected)
++ self.assertFalse(self.account11.connected)
++ self.assertEquals(len(result), 5)
++ result_iq = result[0].xmlnode
++ result_iq.setNs(None)
++ self.assertTrue(jcl.tests.is_xml_equal(\
++ u"<iq from='account11@" + unicode(self.comp.jid)
++ + "' to='test1@test.com' type='result'>"
++ + "<command xmlns='http://jabber.org/protocol/commands' "
++ + "status='completed'>"
++ + "<x xmlns='jabber:x:data' type='form'>"
++ + "<title>" + Lang.en.command_get_email + "</title>"
++ + "<instructions>" + Lang.en.command_get_email_2_description
++ % (4) + "</instructions>"
++ + "</x></command></iq>",
++ result_iq, True, test_sibling=False))
++ result_iq = result[1].xmlnode
++ self.check_email_message(result_iq, 1)
++ result_iq = result[2].xmlnode
++ self.check_email_message(result_iq, 2)
++ result_iq = result[3].xmlnode
++ self.check_email_message(result_iq, 13)
++ result_iq = result[4].xmlnode
++ self.check_email_message(result_iq, 14)
++
++ def test_execute_get_emails_last_page(self):
++ """
++ Test that field fetch_more does not exist if number of emails < 10
++ """
++ class MockIMAPAccount2(MockIMAPAccount):
++ """ """
++ def get_mail_list_summary(self, start_index=1, end_index=20):
++ return [("1", "mail 1"),
++ ("2", "mail 2")]
++
++ get_email_func = self.account11.get_mail
++ MockIMAPAccount2.createTable(ifNotExists=True)
++ self.account11.destroySelf()
++ self.account11 = MockIMAPAccount2(user=self.user1,
++ name="account11",
++ jid="account11@" + unicode(self.comp.jid))
++ self.account11.__dict__["get_mail"] = get_email_func
++ self.info_query.set_from("test1@test.com")
++ self.info_query.set_to("account11@" + unicode(self.comp.jid))
++ result = self.command_manager.apply_command_action(\
++ self.info_query,
++ "jmc#get-email",
++ "execute")
++ session_id = self.check_step_1(result, options="<option label=\"mail 1\">" \
++ + "<value>1</value></option>" \
++ + "<option label=\"mail 2\">" \
++ + "<value>2</value></option>",
++ last_page=True)
++ self.assertTrue("fetch_more" in
++ self.command_manager.sessions[session_id][1])
++ self.assertEquals(\
++ self.command_manager.sessions[session_id][1]["fetch_more"][-1],
++ "0")
++
++ # Second step
++ info_query = jcl.jabber.tests.command.prepare_submit(\
++ node="jmc#get-email",
++ session_id=session_id,
++ from_jid="test1@test.com",
++ to_jid="account11@jmc.test.com",
++ fields=[Field(field_type="list-multi",
++ name="emails",
++ values=["1"])],
++ action="complete")
++ result = self.command_manager.apply_command_action(\
++ info_query,
++ "jmc#get-email",
++ "execute")
++ self.assertTrue(self.account11.has_connected)
++ self.assertFalse(self.account11.connected)
++ self.assertEquals(len(result), 2)
++ result_iq = result[0].xmlnode
++ result_iq.setNs(None)
++ self.assertTrue(jcl.tests.is_xml_equal(\
++ u"<iq from='account11@" + unicode(self.comp.jid)
++ + "' to='test1@test.com' type='result'>"
++ + "<command xmlns='http://jabber.org/protocol/commands' "
++ + "status='completed'>"
++ + "<x xmlns='jabber:x:data' type='form'>"
++ + "<title>" + Lang.en.command_get_email + "</title>"
++ + "<instructions>" + Lang.en.command_get_email_2_description
++ % (1) + "</instructions>"
++ + "</x></command></iq>",
++ result_iq, True, test_sibling=False))
++ result_iq = result[1].xmlnode
++ self.check_email_message(result_iq, 1)
++ MockIMAPAccount2.dropTable(ifExists=True)
++
++ def test_execute_get_email_error(self):
++ """
++ Test single email retrieval
++ """
++ self.info_query.set_from("test1@test.com")
++ self.info_query.set_to("unknown@" + unicode(self.comp.jid))
++ result = self.command_manager.apply_command_action(\
++ self.info_query,
++ "jmc#get-email",
++ "execute")
++ result_iq = result[0].xmlnode
++ self.assertTrue(jcl.tests.is_xml_equal(\
++ u"<iq from='unknown@" + unicode(self.comp.jid)
++ + "' to='test1@test.com' type='error' "
++ + "xmlns='" + PYXMPP_NS + "'>"
++ + "<command xmlns='http://jabber.org/protocol/commands' "
++ + "node='jmc#get-email' />"
++ + "<error type='cancel'>"
++ + "<item-not-found xmlns='urn:ietf:params:xml:ns:xmpp-stanzas' />"
++ + "</error></iq>",
++ result_iq, True))
++
++def suite():
++ test_suite = unittest.TestSuite()
++ test_suite.addTest(unittest.makeSuite(MailCommandManagerForceCheckCommand_TestCase, 'test'))
++ test_suite.addTest(unittest.makeSuite(MailCommandManagerGetEmailCommand_TestCase, 'test'))
++ return test_suite
++
++if __name__ == '__main__':
++ if '-v' in sys.argv:
++ logger = logging.getLogger()
++ logger.addHandler(logging.StreamHandler())
++ logger.setLevel(logging.INFO)
++ unittest.main(defaultTest='suite')
diff --git a/debian/patches/series b/debian/patches/series
new file mode 100644
index 0000000..b7098f6
--- /dev/null
+++ b/debian/patches/series
@@ -0,0 +1 @@
+debian-changes-0.3b3
diff --git a/debian/source/format b/debian/source/format
new file mode 100644
index 0000000..163aaf8
--- /dev/null
+++ b/debian/source/format
@@ -0,0 +1 @@
+3.0 (quilt)