Merge branch 'edge' of github.com:webnotes/wnframework into edge

This commit is contained in:
Rushabh Mehta 2013-02-13 05:18:27 +01:00
commit 269b69a69c
15 changed files with 182 additions and 107 deletions

View file

@ -160,7 +160,7 @@ DROP TABLE IF EXISTS `tabSeries`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `tabSeries` (
`name` varchar(40) DEFAULT NULL,
`name` varchar(100) DEFAULT NULL,
`current` int(10) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;

View file

@ -25,8 +25,6 @@ import webnotes
sql = webnotes.conn.sql
test_records = []
class DocType:
def __init__(self, doc, doclist=[]):
self.doc = doc

View file

@ -0,0 +1 @@
test_records = []

View file

@ -277,16 +277,4 @@ def get_perm_info(arg=None):
def get_defaults(arg=None):
return webnotes.conn.sql("""select defkey, defvalue from tabDefaultValue where
parent=%s and parenttype = 'Profile'""", webnotes.form_dict['profile'])
test_records = [[{
"doctype":"Profile",
"email": "test@erpnext.com",
"first_name": "_Test",
"new_password": "testpassword"
}],
[{
"doctype":"Profile",
"email": "test1@erpnext.com",
"first_name": "_Test1",
"new_password": "testpassword"
}]]

View file

@ -0,0 +1,12 @@
test_records = [[{
"doctype":"Profile",
"email": "test@erpnext.com",
"first_name": "_Test",
"new_password": "testpassword"
}],
[{
"doctype":"Profile",
"email": "test1@erpnext.com",
"first_name": "_Test1",
"new_password": "testpassword"
}]]

View file

@ -0,0 +1 @@
test_records = []

View file

@ -22,8 +22,6 @@
from __future__ import unicode_literals
import webnotes
test_records = []
class DocType:
def __init__(self, d, dl):
self.doc, self.doclist = d, dl

View file

@ -55,9 +55,17 @@ wn.views.CommunicationList = Class.extend({
},
add_reply: function() {
var subject = this.doc.subject;
if(!subject && this.list.length) {
// get subject from previous message
subject = this.list[0].subject;
if(strip(subject.toLowerCase().split(":")[0])!="re") {
subject = "Re: " + subject;
}
}
new wn.views.CommunicationComposer({
doc: this.doc,
subject: this.doc.subject,
subject: subject,
recipients: this.recipients
})
},

View file

@ -72,7 +72,8 @@ debug_log = []
message_log = []
mute_emails = False
test_objects = {}
request_method = None
print_messages = False
user_lang = False
lang = 'en'
@ -114,20 +115,20 @@ def getTraceback():
return utils.getTraceback()
def errprint(msg):
"""
Append to the :data:`debug log`
"""
if not request_method:
print repr(msg)
from utils import cstr
debug_log.append(cstr(msg or ''))
def msgprint(msg, small=0, raise_exception=0, as_table=False):
"""
Append to the :data:`message_log`
"""
from utils import cstr
if as_table and type(msg) in (list, tuple):
msg = '<table border="1px" style="border-collapse: collapse" cellpadding="2px">' + ''.join(['<tr>'+''.join(['<td>%s</td>' % c for c in r])+'</tr>' for r in msg]) + '</table>'
if print_messages:
print "Message: " + repr(msg)
message_log.append((small and '__small:' or '')+cstr(msg or ''))
if raise_exception:
import inspect
@ -137,11 +138,7 @@ def msgprint(msg, small=0, raise_exception=0, as_table=False):
raise ValidationError, msg
def create_folder(path):
"""
Wrapper function for os.makedirs (does not throw exception if directory exists)
"""
import os
try:
os.makedirs(path)
except OSError, e:
@ -149,11 +146,7 @@ def create_folder(path):
raise e
def create_symlink(source_path, link_path):
"""
Wrapper function for os.symlink (does not throw exception if directory exists)
"""
import os
try:
os.symlink(source_path, link_path)
except OSError, e:
@ -161,11 +154,7 @@ def create_symlink(source_path, link_path):
raise e
def remove_file(path):
"""
Wrapper function for os.remove (does not throw exception if file/symlink does not exists)
"""
import os
try:
os.remove(path)
except OSError, e:
@ -173,9 +162,6 @@ def remove_file(path):
raise e
def connect(db_name=None, password=None):
"""
Connect to this db (or db), if called from command prompt
"""
import webnotes.db
global conn
conn = webnotes.db.Database(user=db_name, password=password)
@ -185,7 +171,7 @@ def connect(db_name=None, password=None):
import webnotes.profile
global user
user = webnotes.profile.Profile('Administrator')
user = webnotes.profile.Profile('Administrator')
def get_env_vars(env_var):
import os
@ -391,4 +377,5 @@ def get_application_home_page(user='Guest'):
if hpl:
return hpl[0][0]
else:
return conn.get_value('Control Panel',None,'home_page') or 'Login Page'
from startup import application_home_page
return application_home_page

View file

@ -97,7 +97,11 @@ class Database:
if values!=():
if isinstance(values, dict):
values = dict(values)
if debug: webnotes.errprint(query % values)
if debug:
try:
webnotes.errprint(query % values)
except TypeError:
webnotes.errprint([query, values])
self._cursor.execute(query, values)
else:
@ -126,11 +130,15 @@ class Database:
else:
return self._cursor.fetchall()
def sql_list(self, query, values=()):
return [r[0] for r in self.sql(query, values)]
def sql_list(self, query, values=(), debug=False):
return [r[0] for r in self.sql(query, values, debug=debug)]
def sql_ddl(self, query, values=()):
self.commit()
self.sql(query)
def check_transaction_status(self, query):
if self.in_transaction and query and query.strip().split()[0].lower() in ['start', 'alter', 'drop', 'create']:
if self.in_transaction and query and query.strip().split()[0].lower() in ['start', 'alter', 'drop', 'create', "begin"]:
raise Exception, 'This statement can cause implicit commit'
if query and query.strip().lower()=='start transaction':
@ -240,15 +248,23 @@ class Database:
return " and ".join(conditions), filters
def get(self, doctype, filters=None, as_dict=False):
return self.get_value(doctype, filters, "*", as_dict=as_dict)
def get_value(self, doctype, filters=None, fieldname="name", ignore=None, as_dict=False):
"""Get a single / multiple value from a record.
For Single DocType, let filters be = None"""
if fieldname!="*" and isinstance(fieldname, basestring):
fieldname = "`" + fieldname + "`"
if filters is not None and (filters!=doctype or filters=='DocType'):
fl = isinstance(fieldname, basestring) and fieldname or "`, `".join(fieldname)
fl = isinstance(fieldname, basestring) and fieldname or \
("`" + "`, `".join(fieldname) + "`")
conditions, filters = self.build_conditions(filters)
try:
r = self.sql("select `%s` from `tab%s` where %s" % (fl, doctype,
r = self.sql("select %s from `tab%s` where %s" % (fl, doctype,
conditions), filters, as_dict)
except Exception, e:
if e.args[0]==1054 and ignore:
@ -360,7 +376,8 @@ class Database:
self.sql("start transaction")
def commit(self):
self.sql("commit")
if self.in_transaction:
self.sql("commit")
def rollback(self):
self.sql("ROLLBACK")

View file

@ -134,11 +134,16 @@ def get_doctype_class(doctype, module):
return DocType
def get_module_name(doctype, module, prefix):
from webnotes.modules import scrub
_doctype, _module = scrub(doctype), scrub(module)
return '%s.doctype.%s.%s%s' % (_module, _doctype, prefix, _doctype)
def load_doctype_module(doctype, module, prefix=""):
from webnotes.modules import scrub
_doctype, _module = scrub(doctype), scrub(module)
try:
module = __import__('%s.doctype.%s.%s%s' % (_module, _doctype, prefix, _doctype), fromlist=[''])
module = __import__(get_module_name(doctype, module, prefix), fromlist=[''])
return module
except ImportError, e:
return None

View file

@ -25,8 +25,6 @@
from __future__ import unicode_literals
import webnotes
#=================================================================================
def get_dt_values(doctype, fields, as_dict = 0):
return webnotes.conn.sql('SELECT %s FROM tabDocType WHERE name="%s"' % (fields, doctype), as_dict = as_dict)
@ -39,21 +37,15 @@ def is_single(doctype):
except IndexError, e:
raise Exception, 'Cannot determine whether %s is single' % doctype
#=================================================================================
def get_parent_dt(dt):
parent_dt = webnotes.conn.sql("""select parent from tabDocField
where fieldtype="Table" and options="%s" and (parent not like "old_parent:%%")
limit 1""" % dt)
return parent_dt and parent_dt[0][0] or ''
#=================================================================================
def set_fieldname(field_id, fieldname):
webnotes.conn.set_value('DocField', field_id, 'fieldname', fieldname)
#=================================================================================
def get_link_fields(doctype):
"""
Returns list of link fields for a doctype in tuple (fieldname, options, label)
@ -71,8 +63,6 @@ def get_link_fields(doctype):
)
]
#=================================================================================
def get_table_fields(doctype):
child_tables = [[d[0], d[1]] for d in webnotes.conn.sql("select options, fieldname from tabDocField \
where parent='%s' and fieldtype='Table'" % doctype, as_list=1)]
@ -81,3 +71,8 @@ def get_table_fields(doctype):
where dt='%s' and fieldtype='Table'" % doctype, as_list=1)]
return child_tables + custom_child_tables
def has_field(doctype, fieldname):
doclist = webnotes.model.doctype.get(doctype)
return doclist.get({"parent":doctype, "doctype":"DocField", "fieldname":fieldname})

View file

@ -106,6 +106,7 @@ class ModelWrapper:
from webnotes.model.code import get_obj
self.obj = get_obj(doc=self.doc, doclist=self.doclist)
self.controller = self.obj
return self.obj
def to_dict(self):
@ -195,6 +196,10 @@ class ModelWrapper:
self.set_doclist(self.obj.doclist)
def get_method(self, method):
self.make_obj()
return getattr(self.obj, method, None)
def save_main(self):
try:
self.doc.save(cint(self.doc.fields.get('__islocal')))

View file

@ -5,65 +5,78 @@ if __name__=="__main__":
sys.path.extend([".", "app", "lib"])
import webnotes
from webnotes.model.meta import get_link_fields
from webnotes.model.code import load_doctype_module
import unittest
from webnotes.model.meta import get_link_fields, has_field
from webnotes.model.code import load_doctype_module, get_module_name
def make_test_records(doctype, verbose=0):
webnotes.mute_emails = True
if not webnotes.conn:
webnotes.connect()
# also include doctype itself
options_list = list(set([options for fieldname, options, label
in get_link_fields(doctype)] + [doctype]))
for options in options_list:
for options in get_dependencies(doctype):
if options.startswith("link:"):
options = options[5:]
if options == "[Select]":
continue
if options not in webnotes.test_objects:
webnotes.test_objects[options] = []
make_test_records(options, verbose)
load_module_and_make_records(options, verbose)
def load_module_and_make_records(options, verbose=0):
module = webnotes.conn.get_value("DocType", options, "module")
make_test_records_for_doctype(options, verbose)
# get methods for either [doctype].py or test_[doctype].py
doctype_module = load_doctype_module(options, module)
test_module = load_doctype_module(options, module, "test_")
def get_modules(doctype):
module = webnotes.conn.get_value("DocType", doctype, "module")
test_module = load_doctype_module(doctype, module, "test_")
return module, test_module
def get_dependencies(doctype):
module, test_module = get_modules(doctype)
options_list = list(set([options for fieldname, options, label
in get_link_fields(doctype)] + [doctype]))
if hasattr(test_module, "test_dependencies"):
options_list += test_module.test_dependencies
if hasattr(test_module, "test_ignore"):
for doctype_name in test_module.test_ignore:
if doctype_name in options_list:
options_list.remove(doctype_name)
return options_list
def make_test_records_for_doctype(doctype, verbose=0):
module, test_module = get_modules(doctype)
if hasattr(test_module, "make_test_records"):
webnotes.test_objects[options] += test_module.make_test_records(verbose)
elif hasattr(doctype_module, "make_test_records"):
webnotes.test_objects[options] += doctype_module.make_test_records(verbose)
webnotes.test_objects[doctype] += test_module.make_test_records(verbose)
elif hasattr(test_module, "test_records"):
webnotes.test_objects[options] += make_test_objects(test_module)
elif hasattr(doctype_module, "test_records"):
webnotes.test_objects[options] += make_test_objects(doctype_module)
webnotes.test_objects[doctype] += make_test_objects(doctype, test_module.test_records)
elif verbose:
print_mandatory_fields(options)
print_mandatory_fields(doctype)
def make_test_objects(obj):
if isinstance(obj, list):
test_records = obj
else:
# obj is a module object
test_records = obj.test_records
def make_test_objects(doctype, test_records):
records = []
for doclist in test_records:
if not "doctype" in doclist[0]:
doclist[0]["doctype"] = doctype
d = webnotes.model_wrapper((webnotes.doclist(doclist)).copy())
if webnotes.test_objects.get(d.doc.doctype):
# do not create test records, if already exists
return []
if has_field(d.doc.doctype, "naming_series"):
if not d.doc.naming_series:
d.doc.naming_series = "_T-" + d.doc.doctype + "-"
d.insert()
records.append(d.doc.name)
return records
@ -78,6 +91,52 @@ def print_mandatory_fields(doctype):
print d.parent + ":" + d.fieldname + " | " + d.fieldtype + " | " + (d.options or "")
print
if __name__=="__main__":
make_test_records(sys.argv[1], verbose=1)
def run_unittest(doctype):
module = webnotes.conn.get_value("DocType", doctype, "module")
test_module = get_module_name(doctype, module, "test_")
make_test_records(args.doctype[0], verbose=True)
try:
exec ('from %s import *' % test_module) in globals()
del sys.argv[1:]
unittest.main()
except ImportError, e:
print "No test module."
def run_all_tests(verbose):
import os, imp
from webnotes.modules.utils import peval_doclist
for path, folders, files in os.walk("."):
for filename in files:
if filename.startswith("test_") and filename.endswith(".py"):
test_suite = unittest.TestSuite()
if os.path.basename(os.path.dirname(path))=="doctype":
txt_file = os.path.join(path, filename[5:].replace(".py", ".txt"))
with open(txt_file, 'r') as f:
doctype_doclist = peval_doclist(f.read())
doctype = doctype_doclist[0]["name"]
make_test_records(doctype, verbose)
module = imp.load_source('test', os.path.join(path, filename))
test_suite.addTest(unittest.TestLoader().loadTestsFromModule(module))
unittest.TextTestRunner(verbosity=2).run(test_suite)
if __name__=="__main__":
import argparse
parser = argparse.ArgumentParser(description='Run tests.')
parser.add_argument('-d', '--doctype', nargs=1, metavar = "DOCTYPE",
help="test for doctype")
parser.add_argument('-v', '--verbose', default=False, action="store_true")
args = parser.parse_args()
webnotes.print_messages = args.verbose
if args.doctype:
run_unittest(args.doctype[0])
else:
run_all_tests(args.verbose)

View file

@ -30,13 +30,10 @@ def send(recipients=None, sender=None, doctype='Profile', email_field='email',
subject='[No Subject]', message='[No Content]'):
"""send bulk mail if not unsubscribed and within conf.bulk_mail_limit"""
import webnotes
if webnotes.mute_emails:
return
def is_unsubscribed(rdata):
if not rdata: return 1
return rdata[0]['unsubscribed']
return rdata.unsubscribed
def check_bulk_limit(new_mails):
import conf, startup
@ -53,20 +50,22 @@ def send(recipients=None, sender=None, doctype='Profile', email_field='email',
webnotes.msgprint("""Monthly Bulk Mail Limit (%s) Crossed""" % monthly_bulk_mail_limit,
raise_exception=BulkLimitCrossedError)
def add_unsubscribe_link(email):
def update_message(doc):
from webnotes.utils import get_request_site_address
import urllib
return message + """<div style="padding: 7px; border-top: 1px solid #aaa;
updated = message + """<div style="padding: 7px; border-top: 1px solid #aaa;
margin-top: 17px;">
<small><a href="%s/server.py?%s">
Unsubscribe</a> from this list.</small></div>""" % (get_request_site_address(),
urllib.urlencode({
"cmd": "webnotes.utils.email_lib.bulk.unsubscribe",
"email": email,
"email": doc.get(email_field),
"type": doctype,
"email_field": email_field
}))
return updated
if not recipients: recipients = []
if not sender or sender == "Administrator":
sender = webnotes.conn.get_value('Email Settings', None, 'auto_mail_id')
@ -85,9 +84,11 @@ def send(recipients=None, sender=None, doctype='Profile', email_field='email',
rdata = webnotes.conn.sql("""select * from `tab%s` where %s=%s""" % (doctype,
email_field, '%s'), r, as_dict=1)
if not is_unsubscribed(rdata):
doc = rdata and rdata[0] or {}
if not is_unsubscribed(doc):
# add to queue
add(r, sender, subject, add_unsubscribe_link(r), text_content)
add(r, sender, subject, update_message(doc), text_content)
def add(email, sender, subject, message, text_content = None):
"""add to bulk mail queue"""