Parent: [ddf08c] (diff)

Download this file

test_globals_model.py    139 lines (117 with data), 5.7 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
from datetime import datetime, timedelta
import mock
from nose.tools import assert_equal
from pylons import tmpl_context as c
from ming.orm.ormsession import ThreadLocalORMSession
from bson import ObjectId
import forgetracker
from forgetracker.model import Globals
from forgetracker.tests.unit import TrackerTestWithModel
from allura.lib import helpers as h
class TestGlobalsModel(TrackerTestWithModel):
def setUp(self):
super(TestGlobalsModel, self).setUp()
c.project.install_app('Tickets', 'doc-bugs')
ThreadLocalORMSession.flush_all()
def test_it_has_current_tracker_globals(self):
bugs_globals = Globals.query.get(app_config_id=c.app.config._id)
assert c.app.globals == bugs_globals
h.set_context('test', 'doc-bugs', neighborhood='Projects')
assert c.app.globals != bugs_globals
def test_next_ticket_number_increments(self):
gl = Globals()
assert_equal(gl.next_ticket_num(), 1)
assert_equal(gl.next_ticket_num(), 2)
def test_ticket_numbers_are_independent(self):
with h.push_context('test', 'doc-bugs', neighborhood='Projects'):
assert_equal(c.app.globals.next_ticket_num(), 1)
with h.push_context('test', 'bugs', neighborhood='Projects'):
assert_equal(c.app.globals.next_ticket_num(), 1)
@mock.patch('forgetracker.model.ticket.datetime')
def test_bin_count(self, mock_dt):
now = datetime.utcnow()
mock_dt.utcnow.return_value = now
gbl = Globals()
gbl._bin_counts_data = [{'summary': 'foo', 'hits': 1}, {'summary': 'bar', 'hits': 2}]
gbl.invalidate_bin_counts = mock.Mock()
# not expired, finds bin
gbl._bin_counts_expire = now + timedelta(minutes=5)
bin = gbl.bin_count('bar')
assert_equal(bin['hits'], 2)
assert not gbl.invalidate_bin_counts.called
# expired, returns value for missing bin
gbl._bin_counts_expire = now - timedelta(minutes=5)
bin = gbl.bin_count('qux')
assert_equal(bin['hits'], 0)
assert gbl.invalidate_bin_counts.called
@mock.patch('forgetracker.tasks.update_bin_counts')
@mock.patch('forgetracker.model.ticket.datetime')
def test_invalidate_bin_counts(self, mock_dt, mock_task):
now = datetime.utcnow().replace(microsecond=0)
mock_dt.utcnow.return_value = now
gbl = Globals()
# invalidated recently, don't dog-pile
gbl._bin_counts_invalidated = now - timedelta(minutes=1)
gbl.invalidate_bin_counts()
assert not mock_task.post.called
# invalidated too long ago, call again
gbl._bin_counts_invalidated = now - timedelta(minutes=6)
gbl.invalidate_bin_counts()
assert mock_task.post.called
assert_equal(gbl._bin_counts_invalidated, now)
# never invalidated
mock_task.reset_mock()
gbl._bin_counts_invalidated = None
gbl.invalidate_bin_counts()
assert mock_task.post.called
assert_equal(gbl._bin_counts_invalidated, now)
@mock.patch('forgetracker.model.ticket.Bin')
@mock.patch('forgetracker.model.ticket.search_artifact')
@mock.patch('forgetracker.model.ticket.datetime')
def test_update_bin_counts(self, mock_dt, mock_search, mock_bin):
now = datetime.utcnow().replace(microsecond=0)
mock_dt.utcnow.return_value = now
gbl = Globals()
gbl._bin_counts_invalidated = now - timedelta(minutes=1)
mock_bin.query.find.return_value = [mock.Mock(summary='foo', terms='bar')]
mock_search().hits = 5
assert_equal(gbl._bin_counts_data, []) # sanity pre-check
gbl.update_bin_counts()
assert mock_bin.query.find.called
mock_search.assert_called_with(forgetracker.model.Ticket, 'bar', rows=0, short_timeout=False)
assert_equal(gbl._bin_counts_data, [{'summary': 'foo', 'hits': 5}])
assert_equal(gbl._bin_counts_expire, now + timedelta(minutes=60))
assert_equal(gbl._bin_counts_invalidated, None)
class TestCustomFields(TrackerTestWithModel):
def test_it_has_sortable_custom_fields(self):
tracker_globals = globals_with_custom_fields(
[dict(label='Iteration Number',
name='_iteration_number',
show_in_search=False),
dict(label='Point Estimate',
name='_point_estimate',
show_in_search=True)])
expected = [dict(sortable_name='_point_estimate_s',
name='_point_estimate',
label='Point Estimate')]
assert tracker_globals.sortable_custom_fields_shown_in_search() == expected
def globals_with_custom_fields(custom_fields):
c.app.globals.custom_fields = custom_fields
ThreadLocalORMSession.flush_all()
return c.app.globals