Show More
@@ -28,3 +28,4 b' List of contributors to RhodeCode projec' | |||
|
28 | 28 | Vincent Caron <vcaron@bearstech.com> |
|
29 | 29 | Zachary Auclair <zach101@gmail.com> |
|
30 | 30 | Stefan Engel <mail@engel-stefan.de> |
|
31 | Andrew Shadura <bugzilla@tut.by> No newline at end of file |
@@ -438,21 +438,6 b' OUTPUT::' | |||
|
438 | 438 | "users_group_id" : "<id>", |
|
439 | 439 | "group_name" : "<groupname>", |
|
440 | 440 | "active": "<bool>", |
|
441 | "members" : [ | |
|
442 | { | |
|
443 | "user_id" : "<user_id>", | |
|
444 | "username" : "<username>", | |
|
445 | "firstname": "<firstname>", | |
|
446 | "lastname" : "<lastname>", | |
|
447 | "email" : "<email>", | |
|
448 | "emails": "<list_of_all_additional_emails>", | |
|
449 | "active" : "<bool>", | |
|
450 | "admin" : "<bool>", | |
|
451 | "ldap_dn" : "<ldap_dn>", | |
|
452 | "last_login": "<last_login>", | |
|
453 | }, | |
|
454 | … | |
|
455 | ] | |
|
456 | 441 | }, |
|
457 | 442 | … |
|
458 | 443 | ] |
@@ -485,21 +470,6 b' OUTPUT::' | |||
|
485 | 470 | "users_group_id" : "<id>", |
|
486 | 471 | "group_name" : "<groupname>", |
|
487 | 472 | "active": "<bool>", |
|
488 | "members" : [ | |
|
489 | { | |
|
490 | "user_id" : "<user_id>", | |
|
491 | "username" : "<username>", | |
|
492 | "firstname": "<firstname>", | |
|
493 | "lastname" : "<lastname>", | |
|
494 | "email" : "<email>", | |
|
495 | "emails": "<list_of_all_additional_emails>", | |
|
496 | "active" : "<bool>", | |
|
497 | "admin" : "<bool>", | |
|
498 | "ldap_dn" : "<ldap_dn>", | |
|
499 | "last_login": "<last_login>", | |
|
500 | }, | |
|
501 | … | |
|
502 | ] | |
|
503 | 473 | }, |
|
504 | 474 | } |
|
505 | 475 | error: null |
@@ -14,6 +14,7 b' news' | |||
|
14 | 14 | - #574 Show pull request status also in shortlog (if any) |
|
15 | 15 | - remember selected tab in my account page |
|
16 | 16 | - Bumped mercurial version to 2.3.2 |
|
17 | - #595 rcextension hook for repository delete | |
|
17 | 18 | |
|
18 | 19 | fixes |
|
19 | 20 | +++++ |
@@ -30,6 +31,8 b' fixes' | |||
|
30 | 31 | status. Checks now are made also for the repository. |
|
31 | 32 | - fixes #591 git backend was causing encoding errors when handling binary |
|
32 | 33 | files - added a test case for VCS lib tests |
|
34 | - fixed #597 commits in future get negative age. | |
|
35 | - fixed #598 API docs methods had wrong members parameter as returned data | |
|
33 | 36 | |
|
34 | 37 | 1.4.3 (**2012-09-28**) |
|
35 | 38 | ---------------------- |
@@ -71,8 +71,8 b' functionality. To do this simply execute' | |||
|
71 | 71 | |
|
72 | 72 | This will create `rcextensions` package in the same place that your `ini` file |
|
73 | 73 | lives. With `rcextensions` it's possible to add additional mapping for whoosh, |
|
74 |
stats and add additional code into the push/pull/create repo hooks. |
|
|
75 | for sending signals to build-bots such as jenkins. | |
|
74 | stats and add additional code into the push/pull/create/delete repo hooks. | |
|
75 | For example for sending signals to build-bots such as jenkins. | |
|
76 | 76 | Please see the `__init__.py` file inside `rcextensions` package |
|
77 | 77 | for more details. |
|
78 | 78 |
@@ -40,12 +40,38 b' def _crhook(*args, **kwargs):' | |||
|
40 | 40 | :param group_id: |
|
41 | 41 | :param created_by: |
|
42 | 42 | """ |
|
43 | ||
|
44 | 43 | return 0 |
|
45 | 44 | CREATE_REPO_HOOK = _crhook |
|
46 | 45 | |
|
47 | 46 | |
|
48 | 47 | #============================================================================== |
|
48 | # POST DELETE REPOSITORY HOOK | |
|
49 | #============================================================================== | |
|
50 | # this function will be executed after each repository deletion | |
|
51 | def _dlhook(*args, **kwargs): | |
|
52 | """ | |
|
53 | Post create repository HOOK | |
|
54 | kwargs available: | |
|
55 | :param repo_name: | |
|
56 | :param repo_type: | |
|
57 | :param description: | |
|
58 | :param private: | |
|
59 | :param created_on: | |
|
60 | :param enable_downloads: | |
|
61 | :param repo_id: | |
|
62 | :param user_id: | |
|
63 | :param enable_statistics: | |
|
64 | :param clone_uri: | |
|
65 | :param fork_id: | |
|
66 | :param group_id: | |
|
67 | :param deleted_by: | |
|
68 | :param deleted_on: | |
|
69 | """ | |
|
70 | return 0 | |
|
71 | DELETE_REPO_HOOK = _dlhook | |
|
72 | ||
|
73 | ||
|
74 | #============================================================================== | |
|
49 | 75 | # POST PUSH HOOK |
|
50 | 76 | #============================================================================== |
|
51 | 77 |
@@ -188,4 +188,3 b' class SettingsController(BaseRepoControl' | |||
|
188 | 188 | h.flash(_('An error occurred during unlocking'), |
|
189 | 189 | category='error') |
|
190 | 190 | return redirect(url('summary_home', repo_name=repo_name)) |
|
191 |
@@ -667,4 +667,4 b' class DbManage(object):' | |||
|
667 | 667 | if not __py_version__ >= (2, 6): |
|
668 | 668 | notify('Python2.5 detected, please switch ' |
|
669 | 669 | 'egg:waitress#main -> egg:Paste#http ' |
|
670 | 'in your .ini file') No newline at end of file | |
|
670 | 'in your .ini file') |
@@ -24,6 +24,7 b'' | |||
|
24 | 24 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
25 | 25 | import os |
|
26 | 26 | import sys |
|
27 | import time | |
|
27 | 28 | import binascii |
|
28 | 29 | from inspect import isfunction |
|
29 | 30 | |
@@ -38,6 +39,7 b' from rhodecode.lib.exceptions import HTT' | |||
|
38 | 39 | from rhodecode.lib.utils2 import safe_str |
|
39 | 40 | from rhodecode.model.db import Repository, User |
|
40 | 41 | |
|
42 | ||
|
41 | 43 | def _get_scm_size(alias, root_path): |
|
42 | 44 | |
|
43 | 45 | if not alias.startswith('.'): |
@@ -262,7 +264,6 b' def log_create_repository(repository_dic' | |||
|
262 | 264 | |
|
263 | 265 | :param repository: dict dump of repository object |
|
264 | 266 | :param created_by: username who created repository |
|
265 | :param created_date: date of creation | |
|
266 | 267 | |
|
267 | 268 | available keys of repository_dict: |
|
268 | 269 | |
@@ -291,6 +292,45 b' def log_create_repository(repository_dic' | |||
|
291 | 292 | |
|
292 | 293 | return 0 |
|
293 | 294 | |
|
295 | ||
|
296 | def log_delete_repository(repository_dict, deleted_by, **kwargs): | |
|
297 | """ | |
|
298 | Post delete repository Hook. This is a dummy function for admins to re-use | |
|
299 | if needed. It's taken from rhodecode-extensions module and executed | |
|
300 | if present | |
|
301 | ||
|
302 | :param repository: dict dump of repository object | |
|
303 | :param deleted_by: username who deleted the repository | |
|
304 | ||
|
305 | available keys of repository_dict: | |
|
306 | ||
|
307 | 'repo_type', | |
|
308 | 'description', | |
|
309 | 'private', | |
|
310 | 'created_on', | |
|
311 | 'enable_downloads', | |
|
312 | 'repo_id', | |
|
313 | 'user_id', | |
|
314 | 'enable_statistics', | |
|
315 | 'clone_uri', | |
|
316 | 'fork_id', | |
|
317 | 'group_id', | |
|
318 | 'repo_name' | |
|
319 | ||
|
320 | """ | |
|
321 | from rhodecode import EXTENSIONS | |
|
322 | callback = getattr(EXTENSIONS, 'DELETE_REPO_HOOK', None) | |
|
323 | if isfunction(callback): | |
|
324 | kw = {} | |
|
325 | kw.update(repository_dict) | |
|
326 | kw.update({'deleted_by': deleted_by, | |
|
327 | 'deleted_on': time.time()}) | |
|
328 | kw.update(kwargs) | |
|
329 | return callback(**kw) | |
|
330 | ||
|
331 | return 0 | |
|
332 | ||
|
333 | ||
|
294 | 334 | handle_git_pre_receive = (lambda repo_path, revs, env: |
|
295 | 335 | handle_git_receive(repo_path, revs, env, hook_type='pre')) |
|
296 | 336 | handle_git_post_receive = (lambda repo_path, revs, env: |
@@ -136,7 +136,7 b' def action_logger(user, action, repo, ip' | |||
|
136 | 136 | elif isinstance(user, basestring): |
|
137 | 137 | user_obj = User.get_by_username(user) |
|
138 | 138 | else: |
|
139 | raise Exception('You have to provide user object or username') | |
|
139 | raise Exception('You have to provide a user object or a username') | |
|
140 | 140 | |
|
141 | 141 | if hasattr(repo, 'repo_id'): |
|
142 | 142 | repo_obj = Repository.get(repo.repo_id) |
@@ -255,7 +255,7 b' def is_valid_repos_group(repos_group_nam' | |||
|
255 | 255 | return False |
|
256 | 256 | |
|
257 | 257 | |
|
258 |
def ask_ok(prompt, retries=4, complaint='Yes or no |
|
|
258 | def ask_ok(prompt, retries=4, complaint='Yes or no please!'): | |
|
259 | 259 | while True: |
|
260 | 260 | ok = raw_input(prompt) |
|
261 | 261 | if ok in ('y', 'ye', 'yes'): |
@@ -299,7 +299,7 b" def make_ui(read_from='file', path=None," | |||
|
299 | 299 | |
|
300 | 300 | if read_from == 'file': |
|
301 | 301 | if not os.path.isfile(path): |
|
302 | log.debug('hgrc file is not present at %s skipping...' % path) | |
|
302 | log.debug('hgrc file is not present at %s, skipping...' % path) | |
|
303 | 303 | return False |
|
304 | 304 | log.debug('reading hgrc from %s' % path) |
|
305 | 305 | cfg = config.config() |
@@ -410,7 +410,7 b' def repo2db_mapper(initial_repo_list, re' | |||
|
410 | 410 | rm = RepoModel() |
|
411 | 411 | user = sa.query(User).filter(User.admin == True).first() |
|
412 | 412 | if user is None: |
|
413 |
raise Exception('Missing administrative account |
|
|
413 | raise Exception('Missing administrative account!') | |
|
414 | 414 | added = [] |
|
415 | 415 | |
|
416 | 416 | # # clear cache keys |
@@ -423,7 +423,7 b' def repo2db_mapper(initial_repo_list, re' | |||
|
423 | 423 | db_repo = rm.get_by_repo_name(name) |
|
424 | 424 | # found repo that is on filesystem not in RhodeCode database |
|
425 | 425 | if not db_repo: |
|
426 | log.info('repository %s not found creating now' % name) | |
|
426 | log.info('repository %s not found, creating now' % name) | |
|
427 | 427 | added.append(name) |
|
428 | 428 | desc = (repo.description |
|
429 | 429 | if repo.description != 'unknown' |
@@ -446,7 +446,7 b' def repo2db_mapper(initial_repo_list, re' | |||
|
446 | 446 | # during starting install all cache keys for all repositories in the |
|
447 | 447 | # system, this will register all repos and multiple instances |
|
448 | 448 | key, _prefix, _org_key = CacheInvalidation._get_key(name) |
|
449 | log.debug("Creating cache key for %s instance_id:`%s`" % (name, _prefix)) | |
|
449 | log.debug("Creating a cache key for %s instance_id:`%s`" % (name, _prefix)) | |
|
450 | 450 | CacheInvalidation._get_or_create_key(key, _prefix, _org_key, commit=False) |
|
451 | 451 | sa.commit() |
|
452 | 452 | removed = [] |
@@ -454,7 +454,7 b' def repo2db_mapper(initial_repo_list, re' | |||
|
454 | 454 | # remove from database those repositories that are not in the filesystem |
|
455 | 455 | for repo in sa.query(Repository).all(): |
|
456 | 456 | if repo.repo_name not in initial_repo_list.keys(): |
|
457 |
log.debug("Removing non |
|
|
457 | log.debug("Removing non-existing repository found in db `%s`" % | |
|
458 | 458 | repo.repo_name) |
|
459 | 459 | try: |
|
460 | 460 | sa.delete(repo) |
@@ -677,7 +677,7 b' class BasePasterCommand(Command):' | |||
|
677 | 677 | def check_git_version(): |
|
678 | 678 | """ |
|
679 | 679 | Checks what version of git is installed in system, and issues a warning |
|
680 | if it's to old for RhodeCode to properly work. | |
|
680 | if it's too old for RhodeCode to properly work. | |
|
681 | 681 | """ |
|
682 | 682 | import subprocess |
|
683 | 683 | from distutils.version import StrictVersion |
@@ -703,7 +703,7 b' def check_git_version():' | |||
|
703 | 703 | if stderr: |
|
704 | 704 | log.warning('Unable to detect git version org error was:%r' % stderr) |
|
705 | 705 | elif to_old_git: |
|
706 | log.warning('RhodeCode detected git version %s, which is to old ' | |
|
707 |
'for the system to function properly |
|
|
708 |
'it is at least |
|
|
709 | return _ver No newline at end of file | |
|
706 | log.warning('RhodeCode detected git version %s, which is too old ' | |
|
707 | 'for the system to function properly. Make sure ' | |
|
708 | 'its version is at least %s' % (ver, req_ver)) | |
|
709 | return _ver |
@@ -314,9 +314,14 b' def age(prevdate):' | |||
|
314 | 314 | |
|
315 | 315 | order = ['year', 'month', 'day', 'hour', 'minute', 'second'] |
|
316 | 316 | deltas = {} |
|
317 | future = False | |
|
317 | 318 | |
|
318 | 319 | # Get date parts deltas |
|
319 | 320 | now = datetime.datetime.now() |
|
321 | if prevdate > now: | |
|
322 | now, prevdate = prevdate, now | |
|
323 | future = True | |
|
324 | ||
|
320 | 325 | for part in order: |
|
321 | 326 | deltas[part] = getattr(now, part) - getattr(prevdate, part) |
|
322 | 327 | |
@@ -369,10 +374,16 b' def age(prevdate):' | |||
|
369 | 374 | sub_value = 0 |
|
370 | 375 | |
|
371 | 376 | if sub_value == 0: |
|
372 | return _(u'%s ago') % fmt_funcs[part](value) | |
|
373 | ||
|
374 | return _(u'%s and %s ago') % (fmt_funcs[part](value), | |
|
375 |
fmt_funcs[ |
|
|
377 | if future: | |
|
378 | return _(u'in %s') % fmt_funcs[part](value) | |
|
379 | else: | |
|
380 | return _(u'%s ago') % fmt_funcs[part](value) | |
|
381 | if future: | |
|
382 | return _(u'in %s and %s') % (fmt_funcs[part](value), | |
|
383 | fmt_funcs[sub_part](sub_value)) | |
|
384 | else: | |
|
385 | return _(u'%s and %s ago') % (fmt_funcs[part](value), | |
|
386 | fmt_funcs[sub_part](sub_value)) | |
|
376 | 387 | |
|
377 | 388 | return _(u'just now') |
|
378 | 389 | |
@@ -504,4 +515,4 b' def obfuscate_url_pw(engine):' | |||
|
504 | 515 | url = url.make_url(engine) |
|
505 | 516 | if url.password: |
|
506 | 517 | url.password = 'XXXXX' |
|
507 | return str(url) No newline at end of file | |
|
518 | return str(url) |
@@ -33,7 +33,7 b' from rhodecode.lib.vcs.backends import g' | |||
|
33 | 33 | from rhodecode.lib.compat import json |
|
34 | 34 | from rhodecode.lib.utils2 import LazyProperty, safe_str, safe_unicode |
|
35 | 35 | from rhodecode.lib.caching_query import FromCache |
|
36 | from rhodecode.lib.hooks import log_create_repository | |
|
36 | from rhodecode.lib.hooks import log_create_repository, log_delete_repository | |
|
37 | 37 | |
|
38 | 38 | from rhodecode.model import BaseModel |
|
39 | 39 | from rhodecode.model.db import Repository, UserRepoToPerm, User, Permission, \ |
@@ -336,9 +336,13 b' class RepoModel(BaseModel):' | |||
|
336 | 336 | def delete(self, repo): |
|
337 | 337 | repo = self._get_repo(repo) |
|
338 | 338 | if repo: |
|
339 | old_repo_dict = repo.get_dict() | |
|
340 | owner = repo.user | |
|
339 | 341 | try: |
|
340 | 342 | self.sa.delete(repo) |
|
341 | 343 | self.__delete_repo(repo) |
|
344 | log_delete_repository(old_repo_dict, | |
|
345 | deleted_by=owner.username) | |
|
342 | 346 | except: |
|
343 | 347 | log.error(traceback.format_exc()) |
|
344 | 348 | raise |
@@ -118,7 +118,7 b' var show_perms = function(e){' | |||
|
118 | 118 | YUD.setStyle('my','display','none'); |
|
119 | 119 | YUD.setStyle('pullrequests','display','none'); |
|
120 | 120 | YUD.setStyle('perms','display',''); |
|
121 |
YUD.setStyle('q_filter','display','none'); |
|
|
121 | YUD.setStyle('q_filter','display','none'); | |
|
122 | 122 | } |
|
123 | 123 | YUE.on('show_perms','click',function(e){ |
|
124 | 124 | show_perms(); |
@@ -134,12 +134,12 b' var show_my = function(e){' | |||
|
134 | 134 | YUD.setStyle('my','display',''); |
|
135 | 135 | YUD.setStyle('q_filter','display',''); |
|
136 | 136 | |
|
137 | ||
|
137 | ||
|
138 | 138 | var url = "${h.url('admin_settings_my_repos')}"; |
|
139 | 139 | ypjax(url, 'my', function(){ |
|
140 | 140 | table_sort(); |
|
141 | 141 | filter_activate(); |
|
142 |
}); |
|
|
142 | }); | |
|
143 | 143 | } |
|
144 | 144 | YUE.on('show_my','click',function(e){ |
|
145 | 145 | show_my(e); |
@@ -154,9 +154,9 b' var show_pullrequests = function(e){' | |||
|
154 | 154 | YUD.setStyle('perms','display','none'); |
|
155 | 155 | YUD.setStyle('pullrequests','display',''); |
|
156 | 156 | YUD.setStyle('q_filter','display','none'); |
|
157 | ||
|
157 | ||
|
158 | 158 | var url = "${h.url('admin_settings_my_pullrequests')}"; |
|
159 |
ypjax(url, 'pullrequests'); |
|
|
159 | ypjax(url, 'pullrequests'); | |
|
160 | 160 | } |
|
161 | 161 | YUE.on('show_pullrequests','click',function(e){ |
|
162 | 162 | show_pullrequests(e) |
@@ -167,12 +167,12 b' var tabs = {' | |||
|
167 | 167 | 'my': show_my, |
|
168 | 168 | 'pullrequests': show_pullrequests |
|
169 | 169 | } |
|
170 |
var url = location.href.split('#'); |
|
|
171 |
if (url[1]) { |
|
|
172 |
//We have a hash |
|
|
170 | var url = location.href.split('#'); | |
|
171 | if (url[1]) { | |
|
172 | //We have a hash | |
|
173 | 173 | var tabHash = url[1]; |
|
174 | 174 | console.log(tabs, tabHash) |
|
175 |
tabs[tabHash](); |
|
|
175 | tabs[tabHash](); | |
|
176 | 176 | } |
|
177 | 177 | |
|
178 | 178 | // main table sorting |
@@ -133,7 +133,7 b'' | |||
|
133 | 133 | PullRequestAutoComplete('user', 'reviewers_container', _USERS_AC_DATA, _GROUPS_AC_DATA); |
|
134 | 134 | |
|
135 | 135 | var other_repos_info = ${c.other_repos_info|n}; |
|
136 | ||
|
136 | ||
|
137 | 137 | var loadPreview = function(){ |
|
138 | 138 | YUD.setStyle(YUD.get('pull_request_overview_url').parentElement,'display','none'); |
|
139 | 139 | var url = "${h.url('compare_url', |
@@ -150,18 +150,18 b'' | |||
|
150 | 150 | var select_ref_data = select_ref.value.split(':'); |
|
151 | 151 | var key = null; |
|
152 | 152 | var val = null; |
|
153 | ||
|
153 | ||
|
154 | 154 | if(select_ref_data.length>1){ |
|
155 | 155 | key = select_ref.name+"_type"; |
|
156 | 156 | val = select_ref_data[0]; |
|
157 | 157 | url = url.replace(key,val); |
|
158 | 158 | rev_data[key] = val; |
|
159 | ||
|
159 | ||
|
160 | 160 | key = select_ref.name; |
|
161 | 161 | val = select_ref_data[1]; |
|
162 | 162 | url = url.replace(key,val); |
|
163 | 163 | rev_data[key] = val; |
|
164 | ||
|
164 | ||
|
165 | 165 | }else{ |
|
166 | 166 | key = select_ref.name; |
|
167 | 167 | val = select_ref.value; |
@@ -175,7 +175,7 b'' | |||
|
175 | 175 | // replace the <select> of changed repo |
|
176 | 176 | YUD.get('other_ref').innerHTML = other_repos_info[repo_name]['revs']; |
|
177 | 177 | }); |
|
178 | ||
|
178 | ||
|
179 | 179 | ypjax(url,'pull_request_overview', function(data){ |
|
180 | 180 | var sel_box = YUQ('#pull_request_form #other_repo')[0]; |
|
181 | 181 | var repo_name = sel_box.options[sel_box.selectedIndex].value; |
@@ -47,7 +47,7 b'' | |||
|
47 | 47 | % if len(c.pull_request_pending_reviewers) > 0: |
|
48 | 48 | <div class="tooltip" title="${h.tooltip(','.join([x.username for x in c.pull_request_pending_reviewers]))}">${ungettext('%d reviewer', '%d reviewers',len(c.pull_request_pending_reviewers)) % len(c.pull_request_pending_reviewers)}</div> |
|
49 | 49 | %else: |
|
50 |
<div>${_('pull request was reviewed by all reviewers')}</div> |
|
|
50 | <div>${_('pull request was reviewed by all reviewers')}</div> | |
|
51 | 51 | %endif |
|
52 | 52 | </div> |
|
53 | 53 | </div> |
@@ -25,7 +25,7 b'' | |||
|
25 | 25 | %endif |
|
26 | 26 | </div> |
|
27 | 27 | %endif |
|
28 |
</div> |
|
|
28 | </div> | |
|
29 | 29 | <pre><a href="${h.url('files_home',repo_name=c.repo_name,revision=cs.raw_id)}">r${cs.revision}:${h.short_id(cs.raw_id)}</a></pre> |
|
30 | 30 | </div> |
|
31 | 31 | </td> |
@@ -400,4 +400,4 b' class TestCompareController(TestControll' | |||
|
400 | 400 | self.assertFalse("""line1-from-new-parent""" in response.body) |
|
401 | 401 | finally: |
|
402 | 402 | RepoModel().delete(r2_id) |
|
403 | RepoModel().delete(r1_id) No newline at end of file | |
|
403 | RepoModel().delete(r1_id) |
@@ -129,10 +129,25 b' class TestLibs(unittest.TestCase):' | |||
|
129 | 129 | self.assertEqual(age(n - delt(hours=1)), u'1 hour ago') |
|
130 | 130 | self.assertEqual(age(n - delt(hours=24)), u'1 day ago') |
|
131 | 131 | self.assertEqual(age(n - delt(hours=24 * 5)), u'5 days ago') |
|
132 | self.assertEqual(age(n - delt(hours=24 * (calendar.mdays[n.month-1] + 2))), | |
|
132 | self.assertEqual(age(n - delt(hours=24 * (calendar.mdays[n.month - 1] + 2))), | |
|
133 | 133 | u'1 month and 2 days ago') |
|
134 | 134 | self.assertEqual(age(n - delt(hours=24 * 400)), u'1 year and 1 month ago') |
|
135 | 135 | |
|
136 | def test_age_in_future(self): | |
|
137 | import calendar | |
|
138 | from rhodecode.lib.utils2 import age | |
|
139 | n = datetime.datetime.now() | |
|
140 | delt = lambda *args, **kwargs: datetime.timedelta(*args, **kwargs) | |
|
141 | self.assertEqual(age(n), u'just now') | |
|
142 | self.assertEqual(age(n + delt(seconds=1)), u'in 1 second') | |
|
143 | self.assertEqual(age(n + delt(seconds=60 * 2)), u'in 2 minutes') | |
|
144 | self.assertEqual(age(n + delt(hours=1)), u'in 1 hour') | |
|
145 | self.assertEqual(age(n + delt(hours=24)), u'in 1 day') | |
|
146 | self.assertEqual(age(n + delt(hours=24 * 5)), u'in 5 days') | |
|
147 | self.assertEqual(age(n + delt(hours=24 * (calendar.mdays[n.month - 1] + 2))), | |
|
148 | u'in 1 month and 1 day') | |
|
149 | self.assertEqual(age(n + delt(hours=24 * 400)), u'in 1 year and 1 month') | |
|
150 | ||
|
136 | 151 | def test_tag_exctrator(self): |
|
137 | 152 | sample = ( |
|
138 | 153 | "hello pta[tag] gog [[]] [[] sda ero[or]d [me =>>< sa]" |
@@ -195,4 +210,3 b' class TestLibs(unittest.TestCase):' | |||
|
195 | 210 | em = 'test@foo.com' |
|
196 | 211 | grav = gravatar_url(email_address=em, size=24) |
|
197 | 212 | assert grav == 'https://server.com/%s/%s' % (_md5(em), 24) |
|
198 |
@@ -10,7 +10,7 b' from rhodecode.model.users_group import ' | |||
|
10 | 10 | from rhodecode.model.meta import Session |
|
11 | 11 | from rhodecode.model.repos_group import ReposGroupModel |
|
12 | 12 | from rhodecode.config.routing import ADMIN_PREFIX |
|
13 | from rhodecode.model.db import ChangesetStatus | |
|
13 | from rhodecode.model.db import ChangesetStatus, Repository | |
|
14 | 14 | from rhodecode.model.changeset_status import ChangesetStatusModel |
|
15 | 15 | from rhodecode.model.comment import ChangesetCommentsModel |
|
16 | 16 | |
@@ -227,7 +227,8 b' class TestReposGroups(unittest.TestCase)' | |||
|
227 | 227 | self.assertRaises(formencode.Invalid, validator.to_python, 123) |
|
228 | 228 | |
|
229 | 229 | def test_NotReviewedRevisions(self): |
|
230 | validator = v.NotReviewedRevisions() | |
|
230 | repo_id = Repository.get_by_repo_name(HG_REPO).repo_id | |
|
231 | validator = v.NotReviewedRevisions(repo_id) | |
|
231 | 232 | rev = '0' * 40 |
|
232 | 233 | # add status for a rev, that should throw an error because it is already |
|
233 | 234 | # reviewed |
General Comments 0
You need to be logged in to leave comments.
Login now