Compare commits
285 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1fb556c483 | ||
|
|
b993a3efd1 | ||
|
|
215d9df0fb | ||
|
|
2f8acf4f51 | ||
|
|
ca45fb39e5 | ||
|
|
0000c3d2fd | ||
|
|
dbbb4c08d9 | ||
|
|
bef233d0ae | ||
|
|
e5f3aa77be | ||
|
|
5548c3c7ec | ||
|
|
524d1fe407 | ||
|
|
e71dc0cb13 | ||
|
|
f39861a6ab | ||
|
|
29f0a03a3f | ||
|
|
e725aed6f7 | ||
|
|
44070687d3 | ||
|
|
ec0c3c874e | ||
|
|
86d5b8823e | ||
|
|
0192619979 | ||
|
|
b8f9873041 | ||
|
|
09ba66ed1e | ||
|
|
ae39d0b189 | ||
|
|
d4b12f4650 | ||
|
|
5412c0b02c | ||
|
|
4ab133075a | ||
|
|
763fbd63d2 | ||
|
|
aa4e8b2c8f | ||
|
|
620384476b | ||
|
|
686bb74fea | ||
|
|
b73085525f | ||
|
|
c6ca66c3e0 | ||
|
|
0bb341cb7e | ||
|
|
6c122e046b | ||
|
|
57c2dad0a3 | ||
|
|
faefd529b4 | ||
|
|
1481a12035 | ||
|
|
2bf0635e0d | ||
|
|
2211274bc5 | ||
|
|
c229c42838 | ||
|
|
a3c71f6558 | ||
|
|
db8b85f767 | ||
|
|
f1664c3841 | ||
|
|
151c298056 | ||
|
|
38f51ce6b2 | ||
|
|
434f3e963e | ||
|
|
b853dd1597 | ||
|
|
3b5b6f612f | ||
|
|
962043c520 | ||
|
|
8394be87ed | ||
|
|
5b547ceb3c | ||
|
|
789ee08485 | ||
|
|
490937859a | ||
|
|
dfc306a2ac | ||
|
|
dea06015a1 | ||
|
|
2711e3392d | ||
|
|
f5e1fe0c2f | ||
|
|
dbbb4ac7a1 | ||
|
|
8ec2ffdde1 | ||
|
|
b76664e7ae | ||
|
|
704c537749 | ||
|
|
633c99bb72 | ||
|
|
44051d8023 | ||
|
|
50dc143c1b | ||
|
|
6d44275869 | ||
|
|
b1b3bf6d3c | ||
|
|
77081ecd4d | ||
|
|
b823b960d8 | ||
|
|
e08f634125 | ||
|
|
ab5e8d9338 | ||
|
|
9a29ea8f14 | ||
|
|
cf87e00b21 | ||
|
|
6233b0a9ec | ||
|
|
04b1bc638c | ||
|
|
a78938f7c2 | ||
|
|
1d23308454 | ||
|
|
6bc9c00ab8 | ||
|
|
bc131742be | ||
|
|
5a12aa0167 | ||
|
|
b3ab9d0055 | ||
|
|
1bde8f91bc | ||
|
|
47ef1b7e5d | ||
|
|
88c7816f5c | ||
|
|
82339c6c18 | ||
|
|
04a609c3a8 | ||
|
|
60430139aa | ||
|
|
7d1c655ee3 | ||
|
|
e34c1c9b79 | ||
|
|
3c430b35ef | ||
|
|
7ad3c70311 | ||
|
|
c270bc1e67 | ||
|
|
3d19bfdcf7 | ||
|
|
dc4a55cc5c | ||
|
|
6e8886277d | ||
|
|
74e96e92b2 | ||
|
|
287b1f0d01 | ||
|
|
feee46e29b | ||
|
|
991efe36e4 | ||
|
|
a2aacb20fa | ||
|
|
592e978062 | ||
|
|
a4769c8bc7 | ||
|
|
d1378d53f1 | ||
|
|
f0b91d3269 | ||
|
|
48c77dd688 | ||
|
|
d86d904395 | ||
|
|
5efc455f0c | ||
|
|
be3bbeba20 | ||
|
|
31ab1b614c | ||
|
|
4bc5fa4693 | ||
|
|
418a64f401 | ||
|
|
abe46270a6 | ||
|
|
1249a77150 | ||
|
|
cfa6b9ed16 | ||
|
|
aa2303f999 | ||
|
|
d5616684f8 | ||
|
|
0f75ba57bd | ||
|
|
c83675bbba | ||
|
|
17d16d405c | ||
|
|
76795ca302 | ||
|
|
5d145bd09f | ||
|
|
82471552a8 | ||
|
|
dc60574129 | ||
|
|
d33a96dee2 | ||
|
|
0098d4ab82 | ||
|
|
bb03b5eab8 | ||
|
|
17eb0f84ec | ||
|
|
56d0523c1f | ||
|
|
9fa18758bc | ||
|
|
d2f2c55b06 | ||
|
|
f4a409bd6e | ||
|
|
971b724d4c | ||
|
|
3263c6f2ba | ||
|
|
359b026535 | ||
|
|
c63518fd3e | ||
|
|
24ba3cff44 | ||
|
|
f7066e1995 | ||
|
|
6844499309 | ||
|
|
afa3e47eab | ||
|
|
5f3e9298f1 | ||
|
|
e4dd303357 | ||
|
|
2fa06eee3d | ||
|
|
dc0ac03334 | ||
|
|
c5a1d69ec5 | ||
|
|
9891981f92 | ||
|
|
2c721f71e7 | ||
|
|
0b4a4be0b7 | ||
|
|
b13bb2fcaf | ||
|
|
d9ba369fcf | ||
|
|
3adece0db5 | ||
|
|
7101ffc277 | ||
|
|
19a7a439b8 | ||
|
|
e728320241 | ||
|
|
1bc17afc53 | ||
|
|
ee5c58f53a | ||
|
|
9bdf6d7b81 | ||
|
|
5754fdccdd | ||
|
|
4901050d57 | ||
|
|
7980c8cb93 | ||
|
|
7e7088388d | ||
|
|
2f6e52d63d | ||
|
|
bde8babb43 | ||
|
|
d6d68fb363 | ||
|
|
814ffed0f0 | ||
|
|
b013fb8cbc | ||
|
|
fbd8e63592 | ||
|
|
e8ad3965d7 | ||
|
|
e00981ee23 | ||
|
|
4e74c6beda | ||
|
|
2d09e556d7 | ||
|
|
8cd39398d6 | ||
|
|
94c616ffe3 | ||
|
|
57649bb888 | ||
|
|
7e9442ec4a | ||
|
|
521e6265fd | ||
|
|
a42a9689fc | ||
|
|
d9ffb8001d | ||
|
|
ec86d26ae6 | ||
|
|
e00efc821a | ||
|
|
f04be8ca93 | ||
|
|
c7ff6a323a | ||
|
|
34833416bc | ||
|
|
d7a6e28d81 | ||
|
|
c13531d720 | ||
|
|
4a40cced7d | ||
|
|
450de10cc7 | ||
|
|
5e587a455c | ||
|
|
04aef9b258 | ||
|
|
9b72557d13 | ||
|
|
a5e0bc30c1 | ||
|
|
458c166e9f | ||
|
|
3373e5d141 | ||
|
|
8f6b8de617 | ||
|
|
22b21a82e7 | ||
|
|
b4151b299f | ||
|
|
e969fca8c4 | ||
|
|
e59993a5d6 | ||
|
|
3adc9d4cf1 | ||
|
|
c1153250cb | ||
|
|
7718dc28d3 | ||
|
|
1894580ae6 | ||
|
|
11df714bbf | ||
|
|
72adee37a8 | ||
|
|
0e8f460d73 | ||
|
|
4e62d5d0d2 | ||
|
|
004e5ba457 | ||
|
|
f1a8a8da6f | ||
|
|
bfb44d1189 | ||
|
|
d64afd8d97 | ||
|
|
97cfdb9c4c | ||
|
|
bb336f63f1 | ||
|
|
80da08f447 | ||
|
|
a6db2b7c90 | ||
|
|
e1c3f83324 | ||
|
|
8545a44ad1 | ||
|
|
cfbe7510a2 | ||
|
|
1479c32edb | ||
|
|
a9d428bf5a | ||
|
|
3a62eb11da | ||
|
|
2df5f81029 | ||
|
|
b88c23bc92 | ||
|
|
4144fbaf5b | ||
|
|
86ddc93f52 | ||
|
|
8a1b583535 | ||
|
|
7623628b86 | ||
|
|
f753bc203f | ||
|
|
ff9ba10705 | ||
|
|
fdc25bdc26 | ||
|
|
d154a587ad | ||
|
|
a9cc4f037b | ||
|
|
50d6679189 | ||
|
|
b82cf4e1d6 | ||
|
|
fa6eaa6710 | ||
|
|
2ca17ac1bd | ||
|
|
862ecd7d36 | ||
|
|
e38b72593b | ||
|
|
81883cae8f | ||
|
|
63770c9cbf | ||
|
|
aaf5da55a0 | ||
|
|
8455d9ae17 | ||
|
|
839a8e8eb4 | ||
|
|
7aa3f6eaee | ||
|
|
219abc69a3 | ||
|
|
595822c928 | ||
|
|
32112937b1 | ||
|
|
a0889c5b99 | ||
|
|
4bc281bfb0 | ||
|
|
e12ec607d7 | ||
|
|
545f393293 | ||
|
|
4efa152e93 | ||
|
|
0ebda4f32a | ||
|
|
b94f54799f | ||
|
|
99f0b4e2e2 | ||
|
|
53cb906733 | ||
|
|
2c31fe8a84 | ||
|
|
6c5e673a2c | ||
|
|
574b891a33 | ||
|
|
9ef1d3f58b | ||
|
|
8b3f432746 | ||
|
|
14a9df261e | ||
|
|
5620a2847b | ||
|
|
13aaae3835 | ||
|
|
2d4fcd3a4f | ||
|
|
f4f70b0bc2 | ||
|
|
1d279bb88f | ||
|
|
fe4757cbf9 | ||
|
|
1d476f163e | ||
|
|
513701b6d2 | ||
|
|
1a1b661714 | ||
|
|
6081a98279 | ||
|
|
157991c33d | ||
|
|
ef67be9170 | ||
|
|
39f3819303 | ||
|
|
7a676bd563 | ||
|
|
80c54daa03 | ||
|
|
99c88cde62 | ||
|
|
17d113ca20 | ||
|
|
2fbf4324a7 | ||
|
|
b46c390d30 | ||
|
|
3c3651bc52 | ||
|
|
abeeb5e66d | ||
|
|
09d61ce4c8 | ||
|
|
cc1c4495b2 | ||
|
|
7b1ec4d17f | ||
|
|
99b3201ccf | ||
|
|
d4205d9ba6 | ||
|
|
8d57633390 |
@@ -79,6 +79,8 @@ test:unit:mysql:
|
||||
- rake db:seed
|
||||
- rake test:units
|
||||
- rake test:controllers
|
||||
- ruby -I test/ test/integration/object_manager_test.rb
|
||||
- ruby -I test/ test/integration/package_test.rb
|
||||
- rake db:drop
|
||||
|
||||
test:unit:postgresql:
|
||||
@@ -93,6 +95,8 @@ test:unit:postgresql:
|
||||
- rake db:seed
|
||||
- rake test:units
|
||||
- rake test:controllers
|
||||
- ruby -I test/ test/integration/object_manager_test.rb
|
||||
- ruby -I test/ test/integration/package_test.rb
|
||||
- rake db:drop
|
||||
|
||||
test:integration:autowizard:
|
||||
|
||||
@@ -18,7 +18,7 @@ targets:
|
||||
dependencies:
|
||||
- elasticsearch
|
||||
- nginx|apache2
|
||||
- postgresql|mariadb-server|sqlite
|
||||
- postgresql|mariadb-server|sqlite
|
||||
ubuntu-16.04:
|
||||
dependencies:
|
||||
- elasticsearch
|
||||
|
||||
@@ -41,6 +41,8 @@ script:
|
||||
- rake db:seed
|
||||
- rake test:units
|
||||
- rake test:controllers
|
||||
- ruby -I test/ test/integration/object_manager_test.rb
|
||||
- ruby -I test/ test/integration/package_test.rb
|
||||
- rake assets:precompile
|
||||
- rake db:drop
|
||||
- rake db:create
|
||||
|
||||
50
CHANGELOG.md
50
CHANGELOG.md
@@ -1,16 +1,58 @@
|
||||
# Change Log
|
||||
|
||||
## [2.1.0](https://github.com/zammad/zammad/tree/2.1.0) (2017-xx-xx)
|
||||
[Full Changelog](https://github.com/zammad/zammad/compare/2.0.0...2.1.0)
|
||||
## [2.1.1](https://github.com/zammad/zammad/tree/2.1.1) (2017-12-06)
|
||||
[Full Changelog](https://github.com/zammad/zammad/compare/2.1.0...2.1.1)
|
||||
|
||||
**Implemented enhancements:**
|
||||
|
||||
|
||||
- Improve i-doit filtering \(without type\) [\#1571](https://github.com/zammad/zammad/issues/1571) [[enhancement](https://github.com/zammad/zammad/labels/enhancement)]
|
||||
- Reset customer selection in ticket create screen if input field cleared [\#1670](https://github.com/zammad/zammad/issues/1670) [[enhancement](https://github.com/zammad/zammad/labels/enhancement)]
|
||||
- Add config option for intelligent customer selection of incoming emails of agents [\#1671](https://github.com/zammad/zammad/issues/1671) [[enhancement](https://github.com/zammad/zammad/labels/enhancement)]
|
||||
- Translation for form widget in Dutch [\#1623](https://github.com/zammad/zammad/issues/1623) [[enhancement](https://github.com/zammad/zammad/labels/enhancement)]
|
||||
- Twitter: Allow tweet articles to be 280 chars long [\#1628](https://github.com/zammad/zammad/issues/1628) [[enhancement](https://github.com/zammad/zammad/labels/enhancement)]
|
||||
- Chat language setting or behaviour in dutch [\#1618](https://github.com/zammad/zammad/issues/1618) [[enhancement](https://github.com/zammad/zammad/labels/enhancement)]
|
||||
|
||||
|
||||
**Fixed bugs:**
|
||||
- Webform isn´t available | 401 Unauthorized [\#1604](https://github.com/zammad/zammad/issues/1604) [[bug](https://github.com/zammad/zammad/labels/bug)]
|
||||
- Unable to re-order overviews in admin interface with over 100 overviews [\#1681](https://github.com/zammad/zammad/issues/1681) [[bug](https://github.com/zammad/zammad/labels/bug)]
|
||||
- TimeAccounting ticket condition prevents submit of Zoom [\#1513](https://github.com/zammad/zammad/issues/1513) [[bug](https://github.com/zammad/zammad/labels/bug)]
|
||||
- Unable to open trigger in admin interface [\#1666](https://github.com/zammad/zammad/issues/1666) [[bug](https://github.com/zammad/zammad/labels/bug)]
|
||||
- Users mail\_delivery\_failed is not removed after changing the email address [\#1661](https://github.com/zammad/zammad/issues/1661) [[bug](https://github.com/zammad/zammad/labels/bug)]
|
||||
- Tickets are deleted but database is still the same size [\#1649](https://github.com/zammad/zammad/issues/1649) [[bug](https://github.com/zammad/zammad/labels/bug)]
|
||||
- Ignore Twitter search key with only \# [\#1606](https://github.com/zammad/zammad/issues/1606) [[bug](https://github.com/zammad/zammad/labels/bug)]
|
||||
- Unable to sort overview by priority [\#1595](https://github.com/zammad/zammad/issues/1595) [[bug](https://github.com/zammad/zammad/labels/bug)]
|
||||
|
||||
|
||||
## [2.1.0](https://github.com/zammad/zammad/tree/2.1.0) (2017-10-25)
|
||||
[Full Changelog](https://github.com/zammad/zammad/compare/2.0.0...2.1.0)
|
||||
|
||||
**Implemented enhancements:**
|
||||
- Added reporting feature.
|
||||
- Added Minit support.
|
||||
- Added Check_MK support.
|
||||
- Moved to Ruby on Rails 5.1.
|
||||
- leading and tailing utf8 spaces are not removed for email addresses are not removed [\#1579](https://github.com/zammad/zammad/issues/1579) [[enhancement](https://github.com/zammad/zammad/labels/enhancement)]
|
||||
- Import emails with same message\_id but target was different channels [\#1578](https://github.com/zammad/zammad/issues/1578) [[enhancement](https://github.com/zammad/zammad/labels/enhancement)]
|
||||
- Allow cti log entries to check done \(also if no hangup state is available\) [\#1478](https://github.com/zammad/zammad/issues/1478) [[enhancement](https://github.com/zammad/zammad/labels/enhancement)]
|
||||
- Selecting specific users for overviews [\#1418](https://github.com/zammad/zammad/issues/1418) [[enhancement](https://github.com/zammad/zammad/labels/enhancement)] [[UX/UI](https://github.com/zammad/zammad/labels/UX/UI)]
|
||||
- support Weibo OAuth2 login [\#1465](https://github.com/zammad/zammad/issues/1465) [[enhancement](https://github.com/zammad/zammad/labels/enhancement)]
|
||||
|
||||
|
||||
**Fixed bugs:**
|
||||
- prevent admin from locking out [\#1563](https://github.com/zammad/zammad/issues/1563) [[bug](https://github.com/zammad/zammad/labels/bug)]
|
||||
- Unable to reindex tickets / elasticsearch error "MapperParsingException\[failed to parse \[article.ticket\]\]; nested: JsonParseException\[Current token \(START\_OBJECT\) not of boolean type" [\#1538](https://github.com/zammad/zammad/issues/1538) [[bug](https://github.com/zammad/zammad/labels/bug)]
|
||||
- Unable to show overview if selected order by attribute is not show in header [\#1528](https://github.com/zammad/zammad/issues/1528) [[bug](https://github.com/zammad/zammad/labels/bug)]
|
||||
- Cannot update notification preferences when nothing is selected [\#1276](https://github.com/zammad/zammad/issues/1276) [[bug](https://github.com/zammad/zammad/labels/bug)] [[notification](https://github.com/zammad/zammad/labels/notification)]
|
||||
- ReplyAll - moves recipients from "To" to "CC" [\#1303](https://github.com/zammad/zammad/issues/1303) [[bug](https://github.com/zammad/zammad/labels/bug)]
|
||||
- Zammad sends reply to itself [\#986](https://github.com/zammad/zammad/issues/986) [[bug](https://github.com/zammad/zammad/labels/bug)]
|
||||
- Exchange Integration SSL Error with self-signed root certificate authority [\#1442](https://github.com/zammad/zammad/issues/1442) [[bug](https://github.com/zammad/zammad/labels/bug)]
|
||||
- Exchange Feature - URL? [\#1406](https://github.com/zammad/zammad/issues/1406) [[bug](https://github.com/zammad/zammad/labels/bug)]
|
||||
- Tickets sent by agent via email into Zammad have state open \(not new\) [\#1482](https://github.com/zammad/zammad/issues/1482) [[bug](https://github.com/zammad/zammad/labels/bug)]
|
||||
- Scheduler not running because of Bad file descriptor in PGConsumeInput\(\) [\#1405](https://github.com/zammad/zammad/issues/1405) [[bug](https://github.com/zammad/zammad/labels/bug)]
|
||||
- Icinga/Nagios Integration: No longer accepts regex in "Sender" [\#1439](https://github.com/zammad/zammad/issues/1439) [[bug](https://github.com/zammad/zammad/labels/bug)]
|
||||
- Invalidate cache when switching users [\#1280](https://github.com/zammad/zammad/issues/1280) [[bug](https://github.com/zammad/zammad/labels/bug)]
|
||||
- Job BackgroundJobSearchIndex NoMethodError: undefined method `lookup' for User::Permission:Module [\#1424](https://github.com/zammad/zammad/issues/1424) [[bug](https://github.com/zammad/zammad/labels/bug)]
|
||||
- Profile not clickable on browsers with touch events or on some Chrome for Windows [\#1398](https://github.com/zammad/zammad/issues/1398) [[bug](https://github.com/zammad/zammad/labels/bug)]
|
||||
|
||||
|
||||
\* *This Change Log was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)*
|
||||
@@ -1,6 +1,6 @@
|
||||
GIT
|
||||
remote: https://github.com/thorsteneckel/autodiscover.git
|
||||
revision: 29d713ee0c8c25fcf74c4292ff13fe1fa4d0d827
|
||||
revision: ee9b53dfa797ce6d4f970b82beea7fbdd2df56bb
|
||||
specs:
|
||||
autodiscover (1.0.2)
|
||||
httpclient
|
||||
@@ -221,7 +221,7 @@ GEM
|
||||
mime-types (2.99.3)
|
||||
mini_portile2 (2.3.0)
|
||||
minitest (5.10.3)
|
||||
multi_json (1.12.1)
|
||||
multi_json (1.12.2)
|
||||
multi_xml (0.6.0)
|
||||
multipart-post (2.0.0)
|
||||
mysql2 (0.4.9)
|
||||
|
||||
@@ -148,24 +148,26 @@ class App.ControllerGenericIndex extends App.Controller
|
||||
return item
|
||||
)
|
||||
|
||||
# show description button, only if content exists
|
||||
showDescription = false
|
||||
if App[ @genericObject ].description && !_.isEmpty(objects)
|
||||
showDescription = true
|
||||
if !@table
|
||||
|
||||
@html App.view('generic/admin/index')(
|
||||
head: @pageData.objects
|
||||
notes: @pageData.notes
|
||||
buttons: @pageData.buttons
|
||||
menus: @pageData.menus
|
||||
showDescription: showDescription
|
||||
)
|
||||
# show description button, only if content exists
|
||||
showDescription = false
|
||||
if App[ @genericObject ].description && !_.isEmpty(objects)
|
||||
showDescription = true
|
||||
|
||||
# show description in content if no no content exists
|
||||
if _.isEmpty(objects) && App[ @genericObject ].description
|
||||
description = marked(App[ @genericObject ].description)
|
||||
@$('.table-overview').html(description)
|
||||
return
|
||||
@html App.view('generic/admin/index')(
|
||||
head: @pageData.objects
|
||||
notes: @pageData.notes
|
||||
buttons: @pageData.buttons
|
||||
menus: @pageData.menus
|
||||
showDescription: showDescription
|
||||
)
|
||||
|
||||
# show description in content if no no content exists
|
||||
if _.isEmpty(objects) && App[ @genericObject ].description
|
||||
description = marked(App[ @genericObject ].description)
|
||||
@$('.table-overview').html(description)
|
||||
return
|
||||
|
||||
# append content table
|
||||
params = _.extend(
|
||||
@@ -184,7 +186,10 @@ class App.ControllerGenericIndex extends App.Controller
|
||||
},
|
||||
@pageData.tableExtend
|
||||
)
|
||||
new App.ControllerTable(params)
|
||||
if !@table
|
||||
@table = new App.ControllerTable(params)
|
||||
else
|
||||
@table.update(objects: objects)
|
||||
|
||||
edit: (id, e) =>
|
||||
e.preventDefault()
|
||||
@@ -1170,7 +1175,6 @@ class App.ObserverController extends App.Controller
|
||||
if @globalRerender
|
||||
@bind('ui:rerender', =>
|
||||
@lastAttributres = undefined
|
||||
console.log('aaaa', @model, @template)
|
||||
@maybeRender(App[@model].fullLocal(@object_id))
|
||||
)
|
||||
|
||||
|
||||
@@ -499,7 +499,6 @@ class App.ControllerTable extends App.Controller
|
||||
orderBy = @customOrderBy || @orderBy
|
||||
orderDirection = @customOrderDirection || @orderDirection
|
||||
|
||||
#console.log('LLL', @lastOrderBy, @orderBy, @lastOrderDirection, @orderDirection, @overviewAttributes, @lastOverview)
|
||||
if @headers && @lastOrderBy is orderBy && @lastOrderDirection is orderDirection && !@tableHeadersHasChanged()
|
||||
#console.log('tableHeaders: same overviewAttributes just return headers', @headers)
|
||||
return ['headers are the same', @headers]
|
||||
@@ -609,9 +608,10 @@ class App.ControllerTable extends App.Controller
|
||||
@lastOrderDirection = orderDirection
|
||||
@lastOrderBy = orderBy
|
||||
|
||||
localObjects is undefined
|
||||
if orderBy
|
||||
for header in @headers
|
||||
if header.name is orderBy || "#{header.name}_id" is orderBy
|
||||
if header.name is orderBy || "#{header.name}_id" is orderBy || header.name is "#{orderBy}_id"
|
||||
localObjects = _.sortBy(
|
||||
@objects
|
||||
(item) ->
|
||||
@@ -649,7 +649,7 @@ class App.ControllerTable extends App.Controller
|
||||
# in case order by is not in show column, use orderBy attribute
|
||||
if !localObjects
|
||||
for attributeName, attribute of @attributesList
|
||||
if attributeName is orderBy || "#{attributeName}_id" is orderBy
|
||||
if attributeName is orderBy || "#{attributeName}_id" is orderBy || attributeName is "#{orderBy}_id"
|
||||
|
||||
# order by
|
||||
localObjects = _.sortBy(
|
||||
@@ -722,6 +722,7 @@ class App.ControllerTable extends App.Controller
|
||||
localObjects = localObjects.concat groupObjects[group]
|
||||
groupObjects[group] = [] # release old array
|
||||
|
||||
return if localObjects is undefined
|
||||
@objects = localObjects
|
||||
@lastSortedobjects = localObjects
|
||||
|
||||
|
||||
@@ -67,11 +67,15 @@ class App.ChannelForm extends App.ControllerSubContent
|
||||
# rebuild preview
|
||||
params.test = true
|
||||
if params.modal
|
||||
@$('.js-modal').removeClass('hide')
|
||||
@$('.js-inlineForm').addClass('hide')
|
||||
@$('.js-formInline').addClass('hide')
|
||||
@$('.js-formBtn').removeClass('hide')
|
||||
@$('.js-formBtn').ZammadForm(params)
|
||||
@$('.js-formBtn').text('Feedback')
|
||||
else
|
||||
@$('.js-modal').addClass('hide')
|
||||
@$('.js-inlineForm').removeClass('hide')
|
||||
@$('.js-formBtn').addClass('hide')
|
||||
@$('.js-formInline').removeClass('hide')
|
||||
@$('.js-formInline').ZammadForm(params)
|
||||
|
||||
@@ -174,17 +174,18 @@ class ConnectionWizard extends App.WizardModal
|
||||
'js-mapping': 'mappingShow'
|
||||
|
||||
events:
|
||||
'submit form.js-discover': 'discover'
|
||||
'submit form.js-discoverSsl': 'discover'
|
||||
'submit form.js-bind': 'folders'
|
||||
'submit form.js-folders': 'mapping'
|
||||
'click .js-cancelSsl': 'showSlideDiscover'
|
||||
'click .js-mapping .js-submitTry': 'mappingChange'
|
||||
'click .js-try .js-submitSave': 'save'
|
||||
'click .js-close': 'hide'
|
||||
'click .js-remove': 'removeRow'
|
||||
'click .js-userMappingForm .js-add': 'addUserMapping'
|
||||
'click .js-goToSlide': 'goToSlide'
|
||||
'submit form.js-discover': 'discover'
|
||||
'submit form.js-discoverCertificateIssue': 'discover'
|
||||
'submit form.js-bind': 'folders'
|
||||
'submit form.js-bindCertificateIssue': 'folders'
|
||||
'submit form.js-folders': 'mapping'
|
||||
'click .js-cancelSsl': 'showSlideDiscover'
|
||||
'click .js-mapping .js-submitTry': 'mappingChange'
|
||||
'click .js-try .js-submitSave': 'save'
|
||||
'click .js-close': 'hide'
|
||||
'click .js-remove': 'removeRow'
|
||||
'click .js-userMappingForm .js-add': 'addUserMapping'
|
||||
'click .js-goToSlide': 'goToSlide'
|
||||
|
||||
elements:
|
||||
'.modal-body': 'body'
|
||||
@@ -261,20 +262,17 @@ class ConnectionWizard extends App.WizardModal
|
||||
processData: true
|
||||
success: (data, status, xhr) =>
|
||||
if data.result isnt 'ok'
|
||||
|
||||
if data.message.indexOf('certificate verify failed') is -1
|
||||
@showSlide('js-discover')
|
||||
@showAlert('js-discover', data.message)
|
||||
else
|
||||
@$('.js-discoverSsl input[name="user"]').val(params.user)
|
||||
@$('.js-discoverSsl input[name="password"]').val(params.password)
|
||||
@showSlide('js-discoverSsl')
|
||||
|
||||
@handleCertificateIssue(
|
||||
message: data.message
|
||||
wizardClass: 'js-discover'
|
||||
user: params.user
|
||||
password: params.password
|
||||
)
|
||||
return
|
||||
|
||||
@wizardConfig.endpoint = data.endpoint
|
||||
@wizardConfig.user = params.user
|
||||
@wizardConfig.password = params.password
|
||||
@wizardConfig.disable_ssl_verify = params.disable_ssl_verify
|
||||
@wizardConfig.user = params.user
|
||||
@wizardConfig.password = params.password
|
||||
|
||||
@showSlide('js-bind')
|
||||
@showBindDetails()
|
||||
@@ -300,13 +298,19 @@ class ConnectionWizard extends App.WizardModal
|
||||
processData: true
|
||||
success: (data, status, xhr) =>
|
||||
if data.result isnt 'ok'
|
||||
@showSlide('js-bind')
|
||||
@showAlert('js-bind', data.message)
|
||||
@handleCertificateIssue(
|
||||
message: data.message
|
||||
wizardClass: 'js-bind'
|
||||
endpoint: params.endpoint
|
||||
user: params.user
|
||||
password: params.password
|
||||
)
|
||||
return
|
||||
|
||||
@wizardConfig.endpoint = params.endpoint
|
||||
@wizardConfig.user = params.user
|
||||
@wizardConfig.password = params.password
|
||||
@wizardConfig.disable_ssl_verify = params.disable_ssl_verify
|
||||
@wizardConfig.endpoint = params.endpoint
|
||||
@wizardConfig.user = params.user
|
||||
@wizardConfig.password = params.password
|
||||
|
||||
# update wizard data
|
||||
@wizardConfig.wizardData = {}
|
||||
@@ -341,6 +345,45 @@ class ConnectionWizard extends App.WizardModal
|
||||
@foldersSelectSubmit.addClass('is-disabled')
|
||||
)
|
||||
|
||||
handleCertificateIssue: (params) =>
|
||||
if params.message.indexOf('certificate') is -1
|
||||
@showSlide(params.wizardClass)
|
||||
@showAlert(params.wizardClass, params.message)
|
||||
else
|
||||
wizardClass = "#{params.wizardClass}CertificateIssue"
|
||||
|
||||
domain = @domainFromMessageOrEmail(
|
||||
message: params.message
|
||||
user: params.user
|
||||
)
|
||||
|
||||
wizardSlide = App.view('integration/exchange_certificate_issue')(
|
||||
wizardClass: wizardClass
|
||||
endpoint: params.endpoint
|
||||
user: params.user
|
||||
password: params.password
|
||||
domain: domain
|
||||
)
|
||||
|
||||
@$('.js-certificateIssuePlaceholder').html(wizardSlide)
|
||||
|
||||
@showSlide(wizardClass)
|
||||
|
||||
domainFromMessageOrEmail: (params) ->
|
||||
|
||||
# try to extract the hostname from the error message
|
||||
hostname = params.message.match(/hostname[ ]\"([^\"]+)"/i)
|
||||
if hostname
|
||||
return hostname[1]
|
||||
|
||||
# try to extract it from the given user
|
||||
emailDomain = params.user.match(/@(.*)$/)
|
||||
if emailDomain
|
||||
return emailDomain[1]
|
||||
|
||||
# fallback to user - better than no value?!
|
||||
return user
|
||||
|
||||
mapping: (e) =>
|
||||
e.preventDefault()
|
||||
@showSlide('js-analyze')
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
class SidebarCustomer extends App.Controller
|
||||
sidebarItem: =>
|
||||
return if !@permissionCheck('ticket.agent')
|
||||
return if !@params.customer_id
|
||||
return if _.isEmpty(@params.customer_id)
|
||||
{
|
||||
head: 'Customer'
|
||||
name: 'customer'
|
||||
@@ -18,6 +18,7 @@ class SidebarCustomer extends App.Controller
|
||||
|
||||
showCustomer: (el) =>
|
||||
@el = el
|
||||
return if _.isEmpty(@params.customer_id)
|
||||
new App.WidgetUser(
|
||||
el: @el
|
||||
user_id: @params.customer_id
|
||||
|
||||
@@ -44,6 +44,8 @@ class App.IdoitObjectSelector extends App.ControllerModal
|
||||
''
|
||||
|
||||
search: (filter) =>
|
||||
if _.isEmpty(filter.type)
|
||||
delete filter.type
|
||||
if _.isEmpty(filter.title)
|
||||
delete filter.title
|
||||
else
|
||||
|
||||
@@ -2121,7 +2121,7 @@ class TwitterConversationRef extends App.ControllerContent
|
||||
open: 88
|
||||
closed: 20
|
||||
|
||||
maxTextLength: 140
|
||||
maxTextLength: 280
|
||||
warningTextLength: 10
|
||||
|
||||
constructor: ->
|
||||
|
||||
@@ -23,17 +23,22 @@ class Index extends App.ControllerSubContent
|
||||
]
|
||||
container: @el.closest('.content')
|
||||
large: true
|
||||
dndCallback: =>
|
||||
dndCallback: (e, item) =>
|
||||
items = @el.find('table > tbody > tr')
|
||||
order = []
|
||||
prios = []
|
||||
prio = 0
|
||||
for item in items
|
||||
prio += 1
|
||||
id = $(item).data('id')
|
||||
overview = App.Overview.find(id)
|
||||
if overview.prio isnt prio
|
||||
overview.prio = prio
|
||||
overview.save()
|
||||
prios.push [id, prio]
|
||||
|
||||
@ajax(
|
||||
id: 'overview_prio'
|
||||
type: 'POST'
|
||||
url: "#{@apiPath}/overviews_prio"
|
||||
processData: true
|
||||
data: JSON.stringify(prios: prios)
|
||||
)
|
||||
)
|
||||
|
||||
App.Config.set('Overview', { prio: 2300, name: 'Overviews', parent: '#manage', target: '#manage/overviews', controller: Index, permission: ['admin.overview'] }, 'NavBarAdmin')
|
||||
|
||||
@@ -18,8 +18,19 @@ class App.TicketCustomer extends App.ControllerModal
|
||||
onSubmit: (e) =>
|
||||
params = @formParam(e.target)
|
||||
|
||||
@customer_id = params['customer_id']
|
||||
ticket = App.Ticket.find(@ticket_id)
|
||||
ticket.customer_id = params['customer_id']
|
||||
errors = ticket.validate()
|
||||
|
||||
if !_.isEmpty(errors)
|
||||
@log 'error', errors
|
||||
@formValidate(
|
||||
form: e.target
|
||||
errors: errors
|
||||
)
|
||||
return
|
||||
|
||||
@customer_id = params['customer_id']
|
||||
callback = =>
|
||||
|
||||
# close modal
|
||||
|
||||
@@ -144,7 +144,7 @@ class App.TicketZoomArticleNew extends App.Controller
|
||||
attributes: []
|
||||
internal: false,
|
||||
features: ['body:limit', 'body:initials']
|
||||
maxTextLength: 140
|
||||
maxTextLength: 280
|
||||
warningTextLength: 30
|
||||
}
|
||||
if possibleArticleType['twitter direct-message']
|
||||
|
||||
@@ -77,7 +77,7 @@ class App._CollectionSingletonBase
|
||||
|
||||
callback: (data) =>
|
||||
for counter, attr of @callbacks
|
||||
callback = ->
|
||||
callback = =>
|
||||
attr.callback(data)
|
||||
if attr.one
|
||||
delete @callbacks[counter]
|
||||
|
||||
@@ -71,7 +71,7 @@ class App.ObjectOrganizationAutocompletion extends App.Controller
|
||||
@open()
|
||||
|
||||
focusInput: =>
|
||||
@objectSelect.focus() if not @formControl.hasClass 'focus'
|
||||
@objectSelect.focus() if not @formControl.hasClass('focus')
|
||||
|
||||
onBlur: =>
|
||||
selectObject = @objectSelect.val()
|
||||
@@ -85,6 +85,9 @@ class App.ObjectOrganizationAutocompletion extends App.Controller
|
||||
@objectId.val("guess:#{selectObject}")
|
||||
@formControl.removeClass 'focus'
|
||||
|
||||
resetObjectSelection: =>
|
||||
@objectId.val('').trigger('change')
|
||||
|
||||
onObjectClick: (e) =>
|
||||
objectId = $(e.currentTarget).data('object-id')
|
||||
@selectObject(objectId)
|
||||
@@ -103,23 +106,23 @@ class App.ObjectOrganizationAutocompletion extends App.Controller
|
||||
# Only work with the last one since its the newest one
|
||||
objectId = @objectId.val().split(',').pop()
|
||||
|
||||
return if !objectId
|
||||
return if !App[@objectSingle].exists(objectId)
|
||||
object = App[@objectSingle].find(objectId)
|
||||
name = object.displayName()
|
||||
if objectId && App[@objectSingle].exists(objectId)
|
||||
object = App[@objectSingle].find(objectId)
|
||||
name = object.displayName()
|
||||
|
||||
if @attribute.multiple
|
||||
# create token
|
||||
@createToken name, objectId
|
||||
else
|
||||
if object.email
|
||||
if @attribute.multiple
|
||||
|
||||
# quote name for special character
|
||||
if name.match(/\@|,|;|\^|\+|#|§|\$|%|&|\/|\(|\)|=|\?|!|\*|\[|\]/)
|
||||
name = "\"#{name}\""
|
||||
name += " <#{object.email}>"
|
||||
# create token
|
||||
@createToken(name, objectId)
|
||||
else
|
||||
if object.email
|
||||
|
||||
@objectSelect.val(name)
|
||||
# quote name for special character
|
||||
if name.match(/\@|,|;|\^|\+|#|§|\$|%|&|\/|\(|\)|=|\?|!|\*|\[|\]/)
|
||||
name = "\"#{name}\""
|
||||
name += " <#{object.email}>"
|
||||
|
||||
@objectSelect.val(name)
|
||||
|
||||
if @callback
|
||||
@callback(objectId)
|
||||
@@ -321,12 +324,16 @@ class App.ObjectOrganizationAutocompletion extends App.Controller
|
||||
@hideOrganizationMembers()
|
||||
|
||||
# hide dropdown
|
||||
if !query
|
||||
if _.isEmpty(query)
|
||||
@emptyResultList()
|
||||
|
||||
if !@attribute.disableCreateObject
|
||||
@recipientList.append(@buildObjectNew())
|
||||
|
||||
# reset object selection
|
||||
@resetObjectSelection()
|
||||
return
|
||||
|
||||
# show dropdown
|
||||
if query && ( !@attribute.minLengt || @attribute.minLengt <= query.length )
|
||||
@lazySearch(query)
|
||||
|
||||
@@ -196,7 +196,7 @@ set new attributes of model (remove already available attributes)
|
||||
for attribute in attributes
|
||||
App[@.className].attributes.push attribute.name
|
||||
attributesNew.push attribute
|
||||
App[ @.className ].configure_attributes = attributesNew
|
||||
App[@.className].configure_attributes = attributesNew
|
||||
|
||||
###
|
||||
|
||||
@@ -226,7 +226,7 @@ set new attributes of model (remove already available attributes)
|
||||
|
||||
@attributesGet: (screen = undefined, attributes = false, noDefaultAttributes = false) ->
|
||||
if !attributes
|
||||
attributes = clone(App[ @.className ].configure_attributes, true)
|
||||
attributes = clone(App[@.className].configure_attributes, true)
|
||||
else
|
||||
attributes = clone(attributes, true)
|
||||
|
||||
@@ -387,15 +387,17 @@ set new attributes of model (remove already available attributes)
|
||||
=>
|
||||
return if _.isEmpty(@SUBSCRIPTION_COLLECTION)
|
||||
App.Log.debug('Model', "server notify collection change #{@className}")
|
||||
@fetchFull(
|
||||
->
|
||||
clear: true
|
||||
)
|
||||
callback = =>
|
||||
@fetchFull(
|
||||
->
|
||||
clear: true
|
||||
)
|
||||
App.Delay.set(callback, 200, "full-#{@className}")
|
||||
|
||||
"Collection::Subscribe::#{@className}"
|
||||
)
|
||||
|
||||
key = @className + '-' + Math.floor( Math.random() * 99999 )
|
||||
key = "#{@className}-#{Math.floor(Math.random() * 99999)}"
|
||||
@SUBSCRIPTION_COLLECTION[key] = callback
|
||||
|
||||
# fetch init collection
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
class App.Overview extends App.Model
|
||||
@configure 'Overview', 'name', 'prio', 'condition', 'order', 'group_by', 'view', 'user_ids', 'organization_shared', 'role_ids', 'order', 'group_by', 'active', 'updated_at'
|
||||
@configure 'Overview', 'name', 'prio', 'condition', 'order', 'group_by', 'view', 'user_ids', 'organization_shared', 'role_ids', 'active'
|
||||
@extend Spine.Model.Ajax
|
||||
@url: @apiPath + '/overviews'
|
||||
@configure_attributes = [
|
||||
|
||||
@@ -200,6 +200,26 @@ class App.Ticket extends App.Model
|
||||
result = true if objectValue.toString().match(contains_regex)
|
||||
else if condition.operator == 'contains not'
|
||||
result = true if !objectValue.toString().match(contains_regex)
|
||||
else if condition.operator == 'contains all'
|
||||
result = true
|
||||
for loopConditionValue in conditionValue
|
||||
if !_.contains(objectValue, loopConditionValue)
|
||||
result = false
|
||||
else if condition.operator == 'contains one'
|
||||
result = false
|
||||
for loopConditionValue in conditionValue
|
||||
if _.contains(objectValue, loopConditionValue)
|
||||
result = true
|
||||
else if condition.operator == 'contains all not'
|
||||
result = true
|
||||
for loopObjectValue in objectValue
|
||||
if _.contains(conditionValue, loopObjectValue)
|
||||
result = false
|
||||
else if condition.operator == 'contains one not'
|
||||
result = false
|
||||
for loopObjectValue in objectValue
|
||||
if !_.contains(conditionValue, loopObjectValue)
|
||||
result = true
|
||||
else if condition.operator == 'is'
|
||||
result = true if objectValue.toString().trim().toLowerCase() is loopConditionValue.toString().trim().toLowerCase()
|
||||
else if condition.operator == 'is not'
|
||||
|
||||
@@ -132,7 +132,7 @@
|
||||
|
||||
<p><%- @T('You need to add the following Javascript code snippet to your web page') %>:</p>
|
||||
|
||||
<pre><code class="language-html js-paramsBlock"><button id="feedback-form">Feedback</button>
|
||||
<pre class="js-modal"><code class="language-html js-code js-paramsBlock"><button id="feedback-form">Feedback</button>
|
||||
|
||||
<script id="zammad_form_script" src="<%= @baseurl %>/assets/form/form.js"></script>
|
||||
|
||||
@@ -144,3 +144,16 @@ $(function() {
|
||||
});
|
||||
</script></code></pre>
|
||||
</div>
|
||||
|
||||
<pre class="js-inlineForm"><code class="language-html js-code js-paramsBlock"><div id="feedback-form">form will be placed in here</div>
|
||||
|
||||
<script id="zammad_form_script" src="<%= @baseurl %>/assets/form/form.js"></script>
|
||||
|
||||
<script>
|
||||
$(function() {
|
||||
$('#feedback-form').ZammadForm({
|
||||
<span class="js-modal-params"></span>
|
||||
});
|
||||
});
|
||||
</script></code></pre>
|
||||
</div>
|
||||
@@ -0,0 +1,25 @@
|
||||
<form class="modal-content setup wizard hide <%= @wizardClass %>">
|
||||
<input type="hidden" name="disable_ssl_verify" value="1">
|
||||
<input type="hidden" name="endpoint" value="<%= @endpoint %>">
|
||||
<input type="hidden" name="user" value="<%= @user %>">
|
||||
<input type="hidden" name="password" value="<%= @password %>">
|
||||
<div class="modal-header">
|
||||
<div class="modal-close js-close">
|
||||
<%- @Icon('diagonal-cross') %>
|
||||
</div>
|
||||
<h1 class="modal-title"><%- @T('Your connection is not private') %></h1>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="wizard-body vertical">
|
||||
<p><%- @T('The certificate of the domain |%s| could not be verified. This may allow hackers to steal your credentials. If you are sure that you are using a self-signed certificate, you can press "Proceed". Otherwise, please "Cancel".', @domain) %></p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<div class="modal-leftFooter">
|
||||
<button class="btn btn--text btn--danger btn--secondary js-submit"><%- @T('Proceed') %></button>
|
||||
</div>
|
||||
<div class="modal-rightFooter">
|
||||
<a class="btn btn--primary align-right js-cancelSsl"><%- @T('Cancel') %></a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
@@ -19,7 +19,7 @@
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="settings-list-row-control"><%- @T('User') %>
|
||||
<td class="settings-list-control-cell"><input type="text" name="user" class="form-control form-control--small js-user" value="" placeholder="" autocomplete="off" required>
|
||||
<td class="settings-list-control-cell"><input type="text" name="user" class="form-control form-control--small js-user" value="" placeholder="user@your-exchange.tld" autocomplete="off" required>
|
||||
<tr>
|
||||
<td class="settings-list-row-control"><%- @T('Password') %>
|
||||
<td class="settings-list-control-cell"><input type="password" name="password" class="form-control form-control--small js-password" value="" placeholder="" autocomplete="new-password" required>
|
||||
@@ -34,30 +34,7 @@
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<form class="modal-content setup wizard hide js-discoverSsl">
|
||||
<input type="hidden" name="disable_ssl_verify" value="1">
|
||||
<input type="hidden" name="user" value="">
|
||||
<input type="hidden" name="password" value="">
|
||||
<div class="modal-header">
|
||||
<div class="modal-close js-close">
|
||||
<%- @Icon('diagonal-cross') %>
|
||||
</div>
|
||||
<h1 class="modal-title"><%- @T('Your connection is not private') %></h1>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="wizard-body vertical">
|
||||
<p><%- @T('The certificate of the domain could not be verified. Hackers could steal the credentials or redirect the connection. Or maybe you are using a self-signed certificate.') %></p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<div class="modal-leftFooter">
|
||||
<button class="btn btn--text btn--danger btn--secondary js-submit"><%- @T('Proceed') %></button>
|
||||
</div>
|
||||
<div class="modal-rightFooter">
|
||||
<a class="btn btn--primary align-right js-cancelSsl"><%- @T('Cancel') %></a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<div class="js-certificateIssuePlaceholder"></div>
|
||||
|
||||
<form class="modal-content setup wizard hide js-connect">
|
||||
<div class="modal-header">
|
||||
|
||||
@@ -440,7 +440,7 @@
|
||||
</div>
|
||||
<div class="textBubble-footer">
|
||||
<div class="textBubble-signatur"><span class="js-signature">/je</span></div>
|
||||
<div class="textBubble-letterCount js-letterCount">140</div>
|
||||
<div class="textBubble-letterCount js-letterCount">280</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -241,7 +241,7 @@ class FormController < ApplicationController
|
||||
|
||||
def enabled?
|
||||
return true if params[:test] && current_user && current_user.permissions?('admin.channel_formular')
|
||||
return true if Setting.get('form_ticket_create') && Setting.get('customer_ticket_create')
|
||||
return true if Setting.get('form_ticket_create')
|
||||
response_access_deny
|
||||
false
|
||||
end
|
||||
|
||||
@@ -26,11 +26,7 @@ class Integration::ExchangeController < ApplicationController
|
||||
answer_with do
|
||||
Sequencer.process('Import::Exchange::AvailableFolders',
|
||||
parameters: {
|
||||
ews_config: {
|
||||
endpoint: params[:endpoint],
|
||||
user: params[:user],
|
||||
password: params[:password],
|
||||
}
|
||||
ews_config: ews_config
|
||||
})
|
||||
end
|
||||
end
|
||||
@@ -42,11 +38,7 @@ class Integration::ExchangeController < ApplicationController
|
||||
examples = Sequencer.process('Import::Exchange::AttributesExamples',
|
||||
parameters: {
|
||||
ews_folder_ids: params[:folders],
|
||||
ews_config: {
|
||||
endpoint: params[:endpoint],
|
||||
user: params[:user],
|
||||
password: params[:password],
|
||||
}
|
||||
ews_config: ews_config
|
||||
})
|
||||
examples.tap do |result|
|
||||
raise 'No entries found in selected folder(s).' if result[:attributes].blank?
|
||||
@@ -61,15 +53,20 @@ class Integration::ExchangeController < ApplicationController
|
||||
{
|
||||
ews_attributes: params[:attributes].permit!.to_h,
|
||||
ews_folder_ids: params[:folders],
|
||||
ews_config: {
|
||||
endpoint: params[:endpoint],
|
||||
user: params[:user],
|
||||
password: params[:password],
|
||||
}
|
||||
ews_config: ews_config
|
||||
}
|
||||
end
|
||||
|
||||
def payload_import
|
||||
nil
|
||||
end
|
||||
|
||||
def ews_config
|
||||
{
|
||||
disable_ssl_verify: params[:disable_ssl_verify],
|
||||
endpoint: params[:endpoint],
|
||||
user: params[:user],
|
||||
password: params[:password],
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
@@ -30,7 +30,7 @@ Example:
|
||||
=begin
|
||||
|
||||
Resource:
|
||||
GET /api/v1/overviews.json
|
||||
GET /api/v1/overviews
|
||||
|
||||
Response:
|
||||
[
|
||||
@@ -47,7 +47,7 @@ Response:
|
||||
]
|
||||
|
||||
Test:
|
||||
curl http://localhost/api/v1/overviews.json -v -u #{login}:#{password}
|
||||
curl http://localhost/api/v1/overviews -v -u #{login}:#{password}
|
||||
|
||||
=end
|
||||
|
||||
@@ -58,7 +58,7 @@ curl http://localhost/api/v1/overviews.json -v -u #{login}:#{password}
|
||||
=begin
|
||||
|
||||
Resource:
|
||||
GET /api/v1/overviews/#{id}.json
|
||||
GET /api/v1/overviews/#{id}
|
||||
|
||||
Response:
|
||||
{
|
||||
@@ -68,7 +68,7 @@ Response:
|
||||
}
|
||||
|
||||
Test:
|
||||
curl http://localhost/api/v1/overviews/#{id}.json -v -u #{login}:#{password}
|
||||
curl http://localhost/api/v1/overviews/#{id} -v -u #{login}:#{password}
|
||||
|
||||
=end
|
||||
|
||||
@@ -79,7 +79,7 @@ curl http://localhost/api/v1/overviews/#{id}.json -v -u #{login}:#{password}
|
||||
=begin
|
||||
|
||||
Resource:
|
||||
POST /api/v1/overviews.json
|
||||
POST /api/v1/overviews
|
||||
|
||||
Payload:
|
||||
{
|
||||
@@ -101,7 +101,7 @@ Response:
|
||||
}
|
||||
|
||||
Test:
|
||||
curl http://localhost/api/v1/overviews.json -v -u #{login}:#{password} -H "Content-Type: application/json" -X POST -d '{"name": "some_name","active": true, "note": "some note"}'
|
||||
curl http://localhost/api/v1/overviews -v -u #{login}:#{password} -H "Content-Type: application/json" -X POST -d '{"name": "some_name","active": true, "note": "some note"}'
|
||||
|
||||
=end
|
||||
|
||||
@@ -112,7 +112,7 @@ curl http://localhost/api/v1/overviews.json -v -u #{login}:#{password} -H "Conte
|
||||
=begin
|
||||
|
||||
Resource:
|
||||
PUT /api/v1/overviews/{id}.json
|
||||
PUT /api/v1/overviews/{id}
|
||||
|
||||
Payload:
|
||||
{
|
||||
@@ -134,7 +134,7 @@ Response:
|
||||
}
|
||||
|
||||
Test:
|
||||
curl http://localhost/api/v1/overviews.json -v -u #{login}:#{password} -H "Content-Type: application/json" -X PUT -d '{"name": "some_name","active": true, "note": "some note"}'
|
||||
curl http://localhost/api/v1/overviews -v -u #{login}:#{password} -H "Content-Type: application/json" -X PUT -d '{"name": "some_name","active": true, "note": "some note"}'
|
||||
|
||||
=end
|
||||
|
||||
@@ -145,17 +145,55 @@ curl http://localhost/api/v1/overviews.json -v -u #{login}:#{password} -H "Conte
|
||||
=begin
|
||||
|
||||
Resource:
|
||||
DELETE /api/v1/overviews/{id}.json
|
||||
DELETE /api/v1/overviews/{id}
|
||||
|
||||
Response:
|
||||
{}
|
||||
|
||||
Test:
|
||||
curl http://localhost/api/v1/overviews/#{id}.json -v -u #{login}:#{password} -H "Content-Type: application/json" -X DELETE
|
||||
curl http://localhost/api/v1/overviews/#{id} -v -u #{login}:#{password} -H "Content-Type: application/json" -X DELETE
|
||||
|
||||
=end
|
||||
|
||||
def destroy
|
||||
model_destroy_render(Overview, params)
|
||||
end
|
||||
|
||||
=begin
|
||||
|
||||
Resource:
|
||||
POST /api/v1/overviews_prio
|
||||
|
||||
Payload:
|
||||
{
|
||||
"prios": [
|
||||
[overview_id, prio],
|
||||
[overview_id, prio],
|
||||
[overview_id, prio],
|
||||
[overview_id, prio],
|
||||
[overview_id, prio]
|
||||
]
|
||||
}
|
||||
|
||||
Response:
|
||||
{
|
||||
"success": true,
|
||||
}
|
||||
|
||||
Test:
|
||||
curl http://localhost/api/v1/overviews_prio -v -u #{login}:#{password} -H "Content-Type: application/json" -X POST -d '{"prios": [ [1,1], [44,2] ]}'
|
||||
|
||||
=end
|
||||
|
||||
def prio
|
||||
Overview.without_callback(:update, :before, :rearrangement) do
|
||||
params[:prios].each do |overview_prio|
|
||||
overview = Overview.find(overview_prio[0])
|
||||
next if overview.prio == overview_prio[1]
|
||||
overview.prio = overview_prio[1]
|
||||
overview.save!
|
||||
end
|
||||
end
|
||||
render json: { success: true }, status: :ok
|
||||
end
|
||||
end
|
||||
|
||||
@@ -75,12 +75,12 @@ get assets and record_ids of selector
|
||||
attribute_ref_class = models[attribute_class][:reflections][reflection].klass
|
||||
if content['value'].instance_of?(Array)
|
||||
content['value'].each do |item_id|
|
||||
attribute_object = attribute_ref_class.find_by(id: item_id)
|
||||
if attribute_object
|
||||
assets = attribute_object.assets(assets)
|
||||
end
|
||||
next if item_id.blank?
|
||||
attribute_object = attribute_ref_class.lookup(id: item_id)
|
||||
next if !attribute_object
|
||||
assets = attribute_object.assets(assets)
|
||||
end
|
||||
else
|
||||
elsif content['value'].present?
|
||||
attribute_object = attribute_ref_class.find_by(id: content['value'])
|
||||
if attribute_object
|
||||
assets = attribute_object.assets(assets)
|
||||
@@ -138,11 +138,11 @@ get assets of object list
|
||||
require item['object'].to_filename
|
||||
record = Kernel.const_get(item['object']).find(item['o_id'])
|
||||
assets = record.assets(assets)
|
||||
if item['created_by_id']
|
||||
if item['created_by_id'].present?
|
||||
user = User.find(item['created_by_id'])
|
||||
assets = user.assets(assets)
|
||||
end
|
||||
if item['updated_by_id']
|
||||
if item['updated_by_id'].present?
|
||||
user = User.find(item['updated_by_id'])
|
||||
assets = user.assets(assets)
|
||||
end
|
||||
|
||||
@@ -223,6 +223,7 @@ returns
|
||||
hashtags = []
|
||||
sync['search'].each do |item|
|
||||
next if item['term'].blank?
|
||||
next if item['term'] == '#'
|
||||
next if item['group_id'].blank?
|
||||
hashtags.push item['term']
|
||||
end
|
||||
@@ -275,6 +276,7 @@ returns
|
||||
hit = false
|
||||
sync['search'].each do |item|
|
||||
next if item['term'].blank?
|
||||
next if item['term'] == '#'
|
||||
next if item['group_id'].blank?
|
||||
tweet.hashtags.each do |hashtag|
|
||||
next if item['term'] !~ /^#/
|
||||
@@ -295,6 +297,7 @@ returns
|
||||
body = tweet.text
|
||||
sync['search'].each do |item|
|
||||
next if item['term'].blank?
|
||||
next if item['term'] == '#'
|
||||
next if item['group_id'].blank?
|
||||
if body =~ /#{item['term']}/
|
||||
hit = item
|
||||
@@ -314,6 +317,7 @@ returns
|
||||
return if @sync[:search].blank?
|
||||
@sync[:search].each do |search|
|
||||
next if search[:term].blank?
|
||||
next if search[:term] == '#'
|
||||
next if search[:group_id].blank?
|
||||
result_type = search[:type] || 'mixed'
|
||||
Rails.logger.debug " - searching for '#{search[:term]}'"
|
||||
|
||||
@@ -22,9 +22,9 @@ module Channel::Filter::IdentifySender
|
||||
if !customer_user && mail[ 'x-zammad-customer-email'.to_sym ].present?
|
||||
customer_user = User.find_by(email: mail[ 'x-zammad-customer-email'.to_sym ])
|
||||
end
|
||||
if !customer_user
|
||||
|
||||
# get correct customer
|
||||
# get correct customer
|
||||
if !customer_user && Setting.get('postmaster_sender_is_agent_search_for_customer') == true
|
||||
if mail[ 'x-zammad-ticket-create-article-sender'.to_sym ] == 'Agent'
|
||||
|
||||
# get first recipient and set customer
|
||||
@@ -46,18 +46,21 @@ module Channel::Filter::IdentifySender
|
||||
end
|
||||
end
|
||||
rescue => e
|
||||
Rails.logger.error 'ERROR: SenderIsSystemAddress: ' + e.inspect
|
||||
Rails.logger.error "SenderIsSystemAddress: ##{e.inspect}"
|
||||
end
|
||||
end
|
||||
if !customer_user
|
||||
customer_user = user_create(
|
||||
login: mail[ 'x-zammad-customer-login'.to_sym ] || mail[ 'x-zammad-customer-email'.to_sym ] || mail[:from_email],
|
||||
firstname: mail[ 'x-zammad-customer-firstname'.to_sym ] || mail[:from_display_name],
|
||||
lastname: mail[ 'x-zammad-customer-lastname'.to_sym ],
|
||||
email: mail[ 'x-zammad-customer-email'.to_sym ] || mail[:from_email],
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
# take regular from as customer
|
||||
if !customer_user
|
||||
customer_user = user_create(
|
||||
login: mail[ 'x-zammad-customer-login'.to_sym ] || mail[ 'x-zammad-customer-email'.to_sym ] || mail[:from_email],
|
||||
firstname: mail[ 'x-zammad-customer-firstname'.to_sym ] || mail[:from_display_name],
|
||||
lastname: mail[ 'x-zammad-customer-lastname'.to_sym ],
|
||||
email: mail[ 'x-zammad-customer-email'.to_sym ] || mail[:from_email],
|
||||
)
|
||||
end
|
||||
|
||||
create_recipients(mail)
|
||||
mail[ 'x-zammad-ticket-customer_id'.to_sym ] = customer_user.id
|
||||
|
||||
|
||||
@@ -4,31 +4,48 @@ class Observer::Ticket::LastOwnerUpdate < ActiveRecord::Observer
|
||||
observe 'ticket'
|
||||
|
||||
def before_create(record)
|
||||
_check('create', record)
|
||||
_check(record)
|
||||
end
|
||||
|
||||
def before_update(record)
|
||||
_check('update', record)
|
||||
_check(record)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def _check(type, record)
|
||||
def _check(record)
|
||||
|
||||
# return if we run import mode
|
||||
return true if Setting.get('import_mode')
|
||||
|
||||
# check if owner has changed
|
||||
if type == 'update'
|
||||
return true if record.changes_to_save['owner_id'].blank?
|
||||
end
|
||||
# check if owner, state or group has changed
|
||||
return true if record.changes_to_save['owner_id'].blank? && record.changes_to_save['state_id'].blank? && record.changes_to_save['group_id'].blank? && record.changes_to_save['last_contact_agent_at'].blank?
|
||||
|
||||
# check if owner is nobody
|
||||
if record.owner_id.blank? || record.owner_id == 1
|
||||
if record.changes_to_save['owner_id'].present? && record.changes_to_save['owner_id'][1] == 1
|
||||
record.last_owner_update_at = nil
|
||||
return true
|
||||
end
|
||||
|
||||
# check if group is change
|
||||
if record.changes_to_save['group_id'].present?
|
||||
group = Group.lookup(id: record.changes_to_save['group_id'][1])
|
||||
return true if !group
|
||||
if group.assignment_timeout.blank? || group.assignment_timeout.zero?
|
||||
record.last_owner_update_at = nil
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
# check if state is not new/open
|
||||
if record.changes_to_save['state_id'].present?
|
||||
state_ids = Ticket::State.by_category(:work_on).pluck(:id)
|
||||
if !state_ids.include?(record.changes_to_save['state_id'][1])
|
||||
record.last_owner_update_at = nil
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
record.last_owner_update_at = Time.zone.now
|
||||
end
|
||||
end
|
||||
|
||||
@@ -17,26 +17,47 @@ class Overview < ApplicationModel
|
||||
validates :name, presence: true
|
||||
|
||||
before_create :fill_link_on_create, :fill_prio
|
||||
before_update :fill_link_on_update
|
||||
before_update :fill_link_on_update, :rearrangement
|
||||
|
||||
private
|
||||
|
||||
def rearrangement
|
||||
return true if !changes['prio']
|
||||
prio = 0
|
||||
Overview.all.order(prio: :asc, updated_at: :desc).pluck(:id).each do |overview_id|
|
||||
prio += 1
|
||||
next if id == overview_id
|
||||
Overview.without_callback(:update, :before, :rearrangement) do
|
||||
overview = Overview.find(overview_id)
|
||||
next if overview.prio == prio
|
||||
overview.prio = prio
|
||||
overview.save!
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def fill_prio
|
||||
return true if prio
|
||||
self.prio = 9999
|
||||
return true if prio.present?
|
||||
self.prio = Overview.count + 1
|
||||
true
|
||||
end
|
||||
|
||||
def fill_link_on_create
|
||||
return true if link.present?
|
||||
self.link = link_name(name)
|
||||
self.link = if link.present?
|
||||
link_name(link)
|
||||
else
|
||||
link_name(name)
|
||||
end
|
||||
true
|
||||
end
|
||||
|
||||
def fill_link_on_update
|
||||
return true if !changes['name']
|
||||
return true if changes['link']
|
||||
self.link = link_name(name)
|
||||
return true if !changes['name'] && !changes['link']
|
||||
self.link = if link.present?
|
||||
link_name(link)
|
||||
else
|
||||
link_name(name)
|
||||
end
|
||||
true
|
||||
end
|
||||
|
||||
@@ -50,12 +71,16 @@ class Overview < ApplicationModel
|
||||
local_link = id || rand(999)
|
||||
end
|
||||
check = true
|
||||
count = 0
|
||||
local_lookup_link = local_link
|
||||
while check
|
||||
exists = Overview.find_by(link: local_link)
|
||||
count += 1
|
||||
exists = Overview.find_by(link: local_lookup_link)
|
||||
if exists && exists.id != id
|
||||
local_link = "#{local_link}_#{rand(999)}"
|
||||
local_lookup_link = "#{local_link}_#{count}"
|
||||
else
|
||||
check = false
|
||||
local_link = local_lookup_link
|
||||
end
|
||||
end
|
||||
local_link
|
||||
|
||||
@@ -42,9 +42,7 @@ returns
|
||||
data = user.assets(data)
|
||||
end
|
||||
end
|
||||
|
||||
data = assets_of_selector('condition', data)
|
||||
|
||||
end
|
||||
%w(created_by_id updated_by_id).each do |local_user_id|
|
||||
next if !self[ local_user_id ]
|
||||
|
||||
@@ -47,7 +47,7 @@ returns
|
||||
data.delete('object')
|
||||
|
||||
# store meta data
|
||||
store = Store.create(data)
|
||||
store = Store.create!(data)
|
||||
|
||||
store
|
||||
end
|
||||
@@ -123,17 +123,18 @@ remove one attachment from storage
|
||||
=end
|
||||
|
||||
def self.remove_item(store_id)
|
||||
|
||||
store = Store.find(store_id)
|
||||
file_id = store.store_file_id
|
||||
store.destroy
|
||||
|
||||
# check backend for references
|
||||
files = Store.where(store_file_id: file_id)
|
||||
return if files.count != 1
|
||||
return if files.first.id != store.id
|
||||
if files.count > 1 || files.first.id != store.id
|
||||
store.destroy!
|
||||
return true
|
||||
end
|
||||
|
||||
Store::File.find(file_id).destroy
|
||||
store.destroy!
|
||||
Store::File.find(file_id).destroy!
|
||||
end
|
||||
|
||||
=begin
|
||||
|
||||
@@ -249,7 +249,7 @@ returns
|
||||
return [] if groups.blank?
|
||||
groups.each do |group|
|
||||
next if group.assignment_timeout.blank?
|
||||
ticket_ids = Ticket.where('state_id IN (?) AND owner_id != 1 AND group_id = ?', state_ids, group.id).limit(600).pluck(:id)
|
||||
ticket_ids = Ticket.where('state_id IN (?) AND owner_id != 1 AND group_id = ? AND last_owner_update_at IS NOT NULL', state_ids, group.id).limit(600).pluck(:id)
|
||||
ticket_ids.each do |ticket_id|
|
||||
ticket = Ticket.find_by(id: ticket_id)
|
||||
next if !ticket
|
||||
@@ -922,7 +922,7 @@ perform changes on ticket
|
||||
ticket_id: id,
|
||||
sender: Ticket::Article::Sender.find_by(name: 'System'),
|
||||
type: Ticket::Article::Type.find_by(name: 'email'),
|
||||
).where("ticket_articles.created_at > ? AND ticket_articles.to LIKE '%#{recipient_email.strip}%'", Time.zone.now - minutes.minutes).count
|
||||
).where('ticket_articles.created_at > ? AND ticket_articles.to LIKE ?', Time.zone.now - minutes.minutes, "%#{recipient_email.strip}%").count
|
||||
next if already_sent < count
|
||||
logger.info "Send no trigger based notification to #{recipient_email} because already sent #{count} for this ticket within last #{minutes} minutes (loop protection)"
|
||||
skip = true
|
||||
@@ -941,7 +941,7 @@ perform changes on ticket
|
||||
already_sent = Ticket::Article.where(
|
||||
sender: Ticket::Article::Sender.find_by(name: 'System'),
|
||||
type: Ticket::Article::Type.find_by(name: 'email'),
|
||||
).where("ticket_articles.created_at > ? AND ticket_articles.to LIKE '%#{recipient_email.strip}%'", Time.zone.now - minutes.minutes).count
|
||||
).where('ticket_articles.created_at > ? AND ticket_articles.to LIKE ?', Time.zone.now - minutes.minutes, "%#{recipient_email.strip}%").count
|
||||
next if already_sent < count
|
||||
logger.info "Send no trigger based notification to #{recipient_email} because already sent #{count} in total within last #{minutes} minutes (loop protection)"
|
||||
skip = true
|
||||
|
||||
@@ -18,6 +18,7 @@ class Ticket::Article < ApplicationModel
|
||||
store :preferences
|
||||
before_create :check_subject, :check_body, :check_message_id_md5
|
||||
before_update :check_subject, :check_body, :check_message_id_md5
|
||||
after_destroy :store_delete
|
||||
|
||||
sanitized_html :body
|
||||
|
||||
@@ -316,6 +317,18 @@ returns
|
||||
}
|
||||
end
|
||||
|
||||
# delete attachments and mails of article
|
||||
def store_delete
|
||||
Store.remove(
|
||||
object: 'Ticket::Article',
|
||||
o_id: id,
|
||||
)
|
||||
Store.remove(
|
||||
object: 'Ticket::Article::Mail',
|
||||
o_id: id,
|
||||
)
|
||||
end
|
||||
|
||||
class Flag < ApplicationModel
|
||||
end
|
||||
|
||||
|
||||
@@ -4,6 +4,9 @@ class Trigger < ApplicationModel
|
||||
include ChecksConditionValidation
|
||||
include CanSeed
|
||||
|
||||
load 'trigger/assets.rb'
|
||||
include Trigger::Assets
|
||||
|
||||
store :condition
|
||||
store :perform
|
||||
validates :name, presence: true
|
||||
|
||||
50
app/models/trigger/assets.rb
Normal file
50
app/models/trigger/assets.rb
Normal file
@@ -0,0 +1,50 @@
|
||||
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
||||
|
||||
class Trigger
|
||||
module Assets
|
||||
|
||||
=begin
|
||||
|
||||
get all assets / related models for this trigger
|
||||
|
||||
trigger = Trigger.find(123)
|
||||
result = trigger.assets(assets_if_exists)
|
||||
|
||||
returns
|
||||
|
||||
result = {
|
||||
:triggers => {
|
||||
123 => trigger_model_123,
|
||||
1234 => trigger_model_1234,
|
||||
}
|
||||
}
|
||||
|
||||
=end
|
||||
|
||||
def assets(data)
|
||||
|
||||
app_model_overview = Trigger.to_app_model
|
||||
app_model_user = User.to_app_model
|
||||
|
||||
if !data[ app_model_overview ]
|
||||
data[ app_model_overview ] = {}
|
||||
end
|
||||
if !data[ app_model_user ]
|
||||
data[ app_model_user ] = {}
|
||||
end
|
||||
if !data[ app_model_overview ][ id ]
|
||||
data[ app_model_overview ][ id ] = attributes_with_association_ids
|
||||
data = assets_of_selector('condition', data)
|
||||
data = assets_of_selector('perform', data)
|
||||
end
|
||||
%w(created_by_id updated_by_id).each do |local_user_id|
|
||||
next if !self[ local_user_id ]
|
||||
next if data[ app_model_user ][ self[ local_user_id ] ]
|
||||
user = User.lookup(id: self[ local_user_id ])
|
||||
next if !user
|
||||
data = user.assets(data)
|
||||
end
|
||||
data
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -38,7 +38,7 @@ class User < ApplicationModel
|
||||
load 'user/search_index.rb'
|
||||
include User::SearchIndex
|
||||
|
||||
before_validation :check_name, :check_email, :check_login, :ensure_uniq_email, :ensure_password, :ensure_roles, :ensure_identifier
|
||||
before_validation :check_name, :check_email, :check_login, :check_mail_delivery_failed, :ensure_uniq_email, :ensure_password, :ensure_roles, :ensure_identifier
|
||||
before_create :check_preferences_default, :validate_ooo, :domain_based_assignment, :set_locale
|
||||
before_update :check_preferences_default, :validate_ooo, :reset_login_failed, :validate_agent_limit_by_attributes, :last_admin_check_by_attribute
|
||||
after_create :avatar_for_email_check
|
||||
@@ -945,6 +945,12 @@ returns
|
||||
true
|
||||
end
|
||||
|
||||
def check_mail_delivery_failed
|
||||
return true if !changes || !changes['email']
|
||||
preferences.delete(:mail_delivery_failed)
|
||||
true
|
||||
end
|
||||
|
||||
def ensure_roles
|
||||
return true if role_ids.present?
|
||||
self.role_ids = Role.signup_role_ids
|
||||
|
||||
@@ -7,5 +7,6 @@ Zammad::Application.routes.draw do
|
||||
match api_path + '/overviews', to: 'overviews#create', via: :post
|
||||
match api_path + '/overviews/:id', to: 'overviews#update', via: :put
|
||||
match api_path + '/overviews/:id', to: 'overviews#destroy', via: :delete
|
||||
match api_path + '/overviews_prio', to: 'overviews#prio', via: :post
|
||||
|
||||
end
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
class LastOwnerUpdate < ActiveRecord::Migration[4.2]
|
||||
def up
|
||||
|
||||
# return if it's a new setup
|
||||
return if !Setting.find_by(name: 'system_init_done')
|
||||
|
||||
# reset assignment_timeout to prevent unwanted things happen
|
||||
Group.all.each do |group|
|
||||
group.assignment_timeout = nil
|
||||
group.save!
|
||||
end
|
||||
|
||||
add_column :tickets, :last_owner_update_at, :timestamp, limit: 3, null: true
|
||||
add_index :tickets, [:last_owner_update_at]
|
||||
Ticket.reset_column_information
|
||||
|
||||
Scheduler.create_if_not_exists(
|
||||
name: 'Process auto unassign tickets',
|
||||
method: 'Ticket.process_auto_unassign',
|
||||
period: 10.minutes,
|
||||
prio: 1,
|
||||
active: true,
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
)
|
||||
|
||||
state_ids = Ticket::State.by_category(:work_on).pluck(:id)
|
||||
if state_ids.present?
|
||||
ticket_ids = Ticket.where('tickets.state_id IN (?) AND tickets.owner_id != 1', state_ids).order(created_at: :desc).limit(1000).pluck(:id)
|
||||
ticket_ids.each do |ticket_id|
|
||||
ticket = Ticket.find_by(id: ticket_id)
|
||||
next if !ticket
|
||||
ticket.last_owner_update_at = last_owner_update_at(ticket)
|
||||
ticket.save!
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def last_owner_update_at(ticket)
|
||||
type = History::Type.lookup(name: 'updated')
|
||||
if type
|
||||
object = History::Object.lookup(name: 'Ticket')
|
||||
if object
|
||||
attribute = History::Attribute.lookup(name: 'owner')
|
||||
if attribute
|
||||
history = History.where(o_id: ticket.id, history_type_id: type.id, history_object_id: object.id, history_attribute_id: attribute.id).where.not(id_to: 1).order(created_at: :desc).limit(1)
|
||||
if history.present?
|
||||
return history.first.created_at
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return nil if ticket.owner_id == 1
|
||||
ticket.created_at
|
||||
end
|
||||
|
||||
end
|
||||
32
db/migrate/20171102000001_last_owner_update2.rb
Normal file
32
db/migrate/20171102000001_last_owner_update2.rb
Normal file
@@ -0,0 +1,32 @@
|
||||
class LastOwnerUpdate2 < ActiveRecord::Migration[5.1]
|
||||
def up
|
||||
|
||||
# return if it's a new setup
|
||||
return if !Setting.find_by(name: 'system_init_done')
|
||||
|
||||
# reset assignment_timeout to prevent unwanted things happen
|
||||
Group.all.each do |group|
|
||||
group.assignment_timeout = nil
|
||||
group.save!
|
||||
end
|
||||
|
||||
# check if column already exists
|
||||
if !ActiveRecord::Base.connection.column_exists?(:tickets, :last_owner_update_at)
|
||||
add_column :tickets, :last_owner_update_at, :timestamp, limit: 3, null: true
|
||||
add_index :tickets, [:last_owner_update_at]
|
||||
Ticket.reset_column_information
|
||||
end
|
||||
|
||||
Scheduler.create_if_not_exists(
|
||||
name: 'Process auto unassign tickets',
|
||||
method: 'Ticket.process_auto_unassign',
|
||||
period: 10.minutes,
|
||||
prio: 1,
|
||||
active: true,
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
)
|
||||
Cache.clear
|
||||
end
|
||||
|
||||
end
|
||||
@@ -0,0 +1,34 @@
|
||||
class EmailProcessCustomerSelectionBasedOnSenderRecipient < ActiveRecord::Migration[4.2]
|
||||
def up
|
||||
|
||||
# return if it's a new setup
|
||||
return if !Setting.find_by(name: 'system_init_done')
|
||||
|
||||
Setting.create_if_not_exists(
|
||||
title: 'Customer selection based on sender and receiver list',
|
||||
name: 'postmaster_sender_is_agent_search_for_customer',
|
||||
area: 'Email::Base',
|
||||
description: 'If the sender is an agent, set the first user in the recipient list as a customer.',
|
||||
options: {
|
||||
form: [
|
||||
{
|
||||
display: '',
|
||||
null: true,
|
||||
name: 'postmaster_sender_is_agent_search_for_customer',
|
||||
tag: 'boolean',
|
||||
options: {
|
||||
true => 'yes',
|
||||
false => 'no',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
state: true,
|
||||
preferences: {
|
||||
permission: ['admin.channel_email'],
|
||||
},
|
||||
frontend: false
|
||||
)
|
||||
end
|
||||
|
||||
end
|
||||
@@ -2022,6 +2022,32 @@ Setting.create_if_not_exists(
|
||||
frontend: false
|
||||
)
|
||||
|
||||
Setting.create_if_not_exists(
|
||||
title: 'Customer selection based on sender and receiver list',
|
||||
name: 'postmaster_sender_is_agent_search_for_customer',
|
||||
area: 'Email::Base',
|
||||
description: 'If the sender is an agent, set the first user in the recipient list as a customer.',
|
||||
options: {
|
||||
form: [
|
||||
{
|
||||
display: '',
|
||||
null: true,
|
||||
name: 'postmaster_sender_is_agent_search_for_customer',
|
||||
tag: 'boolean',
|
||||
options: {
|
||||
true => 'yes',
|
||||
false => 'no',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
state: true,
|
||||
preferences: {
|
||||
permission: ['admin.channel_email'],
|
||||
},
|
||||
frontend: false
|
||||
)
|
||||
|
||||
Setting.create_if_not_exists(
|
||||
title: 'Notification Sender',
|
||||
name: 'notification_sender',
|
||||
|
||||
@@ -10,7 +10,8 @@ fill your database with demo records
|
||||
customers: 1000,
|
||||
groups: 20,
|
||||
organizations: 40,
|
||||
tickets: 100
|
||||
overviews: 5,
|
||||
tickets: 100,
|
||||
)
|
||||
|
||||
or if you only want to create 100 tickets
|
||||
@@ -25,6 +26,7 @@ or if you only want to create 100 tickets
|
||||
customers = params[:customers] || 0
|
||||
groups = params[:groups] || 0
|
||||
organizations = params[:organizations] || 0
|
||||
overviews = params[:overviews] || 0
|
||||
tickets = params[:tickets] || 0
|
||||
|
||||
puts 'load db with:'
|
||||
@@ -32,6 +34,7 @@ or if you only want to create 100 tickets
|
||||
puts " customers:#{customers}"
|
||||
puts " groups:#{groups}"
|
||||
puts " organizations:#{organizations}"
|
||||
puts " overviews:#{overviews}"
|
||||
puts " tickets:#{tickets}"
|
||||
|
||||
# set current user
|
||||
@@ -39,7 +42,7 @@ or if you only want to create 100 tickets
|
||||
|
||||
# organizations
|
||||
organization_pool = []
|
||||
if organizations && !organizations.zero?
|
||||
if !organizations.zero?
|
||||
(1..organizations).each do
|
||||
ActiveRecord::Base.transaction do
|
||||
organization = Organization.create!(name: "FillOrganization::#{rand(999_999)}", active: true)
|
||||
@@ -53,7 +56,7 @@ or if you only want to create 100 tickets
|
||||
|
||||
# create agents
|
||||
agent_pool = []
|
||||
if agents && !agents.zero?
|
||||
if !agents.zero?
|
||||
roles = Role.where(name: [ 'Agent'])
|
||||
groups_all = Group.all
|
||||
|
||||
@@ -81,7 +84,7 @@ or if you only want to create 100 tickets
|
||||
|
||||
# create customer
|
||||
customer_pool = []
|
||||
if customers && !customers.zero?
|
||||
if !customers.zero?
|
||||
roles = Role.where(name: [ 'Customer'])
|
||||
groups_all = Group.all
|
||||
|
||||
@@ -113,7 +116,7 @@ or if you only want to create 100 tickets
|
||||
|
||||
# create groups
|
||||
group_pool = []
|
||||
if groups && !groups.zero?
|
||||
if !groups.zero?
|
||||
|
||||
(1..groups).each do
|
||||
ActiveRecord::Base.transaction do
|
||||
@@ -133,6 +136,35 @@ or if you only want to create 100 tickets
|
||||
puts " take #{group_pool.length} groups"
|
||||
end
|
||||
|
||||
# create overviews
|
||||
if !overviews.zero?
|
||||
(1..overviews).each do
|
||||
ActiveRecord::Base.transaction do
|
||||
overview = Overview.create!(
|
||||
name: "Filloverview::#{rand(999_999)}",
|
||||
role_ids: [Role.find_by(name: 'Agent').id],
|
||||
condition: {
|
||||
'ticket.state_id' => {
|
||||
operator: 'is',
|
||||
value: Ticket::State.by_category(:work_on_all).pluck(:id),
|
||||
},
|
||||
},
|
||||
order: {
|
||||
by: 'created_at',
|
||||
direction: 'ASC',
|
||||
},
|
||||
view: {
|
||||
d: %w(title customer group state owner created_at),
|
||||
s: %w(title customer group state owner created_at),
|
||||
m: %w(number title customer group state owner created_at),
|
||||
view_mode_default: 's',
|
||||
},
|
||||
active: true
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# create tickets
|
||||
priority_pool = Ticket::Priority.all
|
||||
state_pool = Ticket::State.all
|
||||
|
||||
@@ -151,6 +151,12 @@ class Ldap
|
||||
params[:encryption] = @encryption
|
||||
end
|
||||
|
||||
# special workaround for IBM bluepages
|
||||
# see issue #1422 for more details
|
||||
if @host == 'bluepages.ibm.com'
|
||||
params[:force_no_page] = true
|
||||
end
|
||||
|
||||
params
|
||||
end
|
||||
|
||||
|
||||
@@ -11,12 +11,37 @@ class Sequencer
|
||||
return if state.provided?(:ews_connection)
|
||||
|
||||
state.provide(:ews_connection) do
|
||||
config = ews_config
|
||||
config ||= ::Import::Exchange.config
|
||||
|
||||
Viewpoint::EWSClient.new(config[:endpoint], config[:user], config[:password])
|
||||
Viewpoint::EWSClient.new(
|
||||
config[:endpoint],
|
||||
config[:user],
|
||||
config[:password],
|
||||
additional_opts
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def config
|
||||
@config ||= begin
|
||||
ews_config || ::Import::Exchange.config
|
||||
end
|
||||
end
|
||||
|
||||
def additional_opts
|
||||
@additional_opts ||= begin
|
||||
http_opts
|
||||
end
|
||||
end
|
||||
|
||||
def http_opts
|
||||
return {} if config[:disable_ssl_verify].blank?
|
||||
{
|
||||
http_opts: {
|
||||
ssl_verify_mode: OpenSSL::SSL::VERIFY_NONE
|
||||
}
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -579,7 +579,7 @@ remove all session and spool messages
|
||||
next if !session_data
|
||||
next if !session_data[:user]
|
||||
next if !session_data[:user]['id']
|
||||
user = User.lookup( id: session_data[:user]['id'] )
|
||||
user = User.lookup(id: session_data[:user]['id'])
|
||||
next if !user
|
||||
|
||||
# start client thread
|
||||
@@ -590,7 +590,9 @@ remove all session and spool messages
|
||||
thread_client(client_id)
|
||||
@@client_threads[client_id] = nil
|
||||
log('debug', "close client (#{client_id}) thread")
|
||||
ActiveRecord::Base.connection.close
|
||||
if ActiveRecord::Base.connection.owner == Thread.current
|
||||
ActiveRecord::Base.connection.close
|
||||
end
|
||||
end
|
||||
sleep 0.5
|
||||
end
|
||||
|
||||
@@ -228,6 +228,22 @@ do($ = window.jQuery, window) ->
|
||||
'Since you didn\'t respond in the last %s minutes your conversation with <strong>%s</strong> got closed.': 'Si vous ne répondez pas dans les <strong>%s</strong> minutes, votre conversation avec %s va être fermée.'
|
||||
'Since you didn\'t respond in the last %s minutes your conversation got closed.': 'Si vous ne répondez pas dans les %s minutes, votre conversation va être fermée.'
|
||||
'We are sorry, it takes longer as expected to get an empty slot. Please try again later or send us an email. Thank you!': 'Nous sommes désolés, il faut plus de temps que prévu pour obtenir un emplacement vide. Veuillez réessayer ultérieurement ou nous envoyer un courriel. Je vous remercie!'
|
||||
'nl':
|
||||
'<strong>Chat</strong> with us!': '<strong>Chat</strong> met ons!'
|
||||
'Scroll down to see new messages': 'Scrol naar beneden om nieuwe berichten te zien'
|
||||
'Online': 'Online'
|
||||
'Offline': 'Offline'
|
||||
'Connecting': 'Verbinden'
|
||||
'Connection re-established': 'Verbinding herstelt'
|
||||
'Today': 'Vandaag'
|
||||
'Send': 'Verzenden'
|
||||
'Compose your message...': 'Typ uw bericht...'
|
||||
'All colleagues are busy.': 'Alle medewerkers zijn bezet.'
|
||||
'You are on waiting list position <strong>%s</strong>.': 'U bent <strong>%s</strong> in de wachtrij.'
|
||||
'Start new conversation': 'Nieuwe conversatie starten'
|
||||
'Since you didn\'t respond in the last %s minutes your conversation with <strong>%s</strong> got closed.': 'Omdat u in de laatste %s minuten niets geschreven heeft wordt de conversatie met <strong>%s</strong> gesloten.'
|
||||
'Since you didn\'t respond in the last %s minutes your conversation got closed.': 'Omdat u in de laatste %s minuten niets geschreven heeft is de conversatie gesloten.'
|
||||
'We are sorry, it takes longer as expected to get an empty slot. Please try again later or send us an email. Thank you!': 'Het spijt ons, het duurt langer dan verwacht om te antwoorden. Alstublieft probeer het later nogmaals of stuur ons een email. Hartelijk dank!'
|
||||
'zh-cn':
|
||||
'<strong>Chat</strong> with us!': '发起<strong>即时对话</strong>!'
|
||||
'Scroll down to see new messages': '向下滚动以查看新消息'
|
||||
|
||||
@@ -1,64 +1,3 @@
|
||||
if (!window.zammadChatTemplates) {
|
||||
window.zammadChatTemplates = {};
|
||||
}
|
||||
window.zammadChatTemplates["agent"] = function (__obj) {
|
||||
if (!__obj) __obj = {};
|
||||
var __out = [], __capture = function(callback) {
|
||||
var out = __out, result;
|
||||
__out = [];
|
||||
callback.call(this);
|
||||
result = __out.join('');
|
||||
__out = out;
|
||||
return __safe(result);
|
||||
}, __sanitize = function(value) {
|
||||
if (value && value.ecoSafe) {
|
||||
return value;
|
||||
} else if (typeof value !== 'undefined' && value != null) {
|
||||
return __escape(value);
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}, __safe, __objSafe = __obj.safe, __escape = __obj.escape;
|
||||
__safe = __obj.safe = function(value) {
|
||||
if (value && value.ecoSafe) {
|
||||
return value;
|
||||
} else {
|
||||
if (!(typeof value !== 'undefined' && value != null)) value = '';
|
||||
var result = new String(value);
|
||||
result.ecoSafe = true;
|
||||
return result;
|
||||
}
|
||||
};
|
||||
if (!__escape) {
|
||||
__escape = __obj.escape = function(value) {
|
||||
return ('' + value)
|
||||
.replace(/&/g, '&')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>')
|
||||
.replace(/"/g, '"');
|
||||
};
|
||||
}
|
||||
(function() {
|
||||
(function() {
|
||||
if (this.agent.avatar) {
|
||||
__out.push('\n<img class="zammad-chat-agent-avatar" src="');
|
||||
__out.push(__sanitize(this.agent.avatar));
|
||||
__out.push('">\n');
|
||||
}
|
||||
|
||||
__out.push('\n<span class="zammad-chat-agent-sentence">\n <span class="zammad-chat-agent-name">');
|
||||
|
||||
__out.push(__sanitize(this.agent.name));
|
||||
|
||||
__out.push('</span>\n</span>');
|
||||
|
||||
}).call(this);
|
||||
|
||||
}).call(__obj);
|
||||
__obj.safe = __objSafe, __obj.escape = __escape;
|
||||
return __out.join('');
|
||||
};
|
||||
|
||||
var bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
|
||||
slice = [].slice,
|
||||
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
|
||||
@@ -418,6 +357,23 @@ var bind = function(fn, me){ return function(){ return fn.apply(me, arguments);
|
||||
'Since you didn\'t respond in the last %s minutes your conversation got closed.': 'Si vous ne répondez pas dans les %s minutes, votre conversation va être fermée.',
|
||||
'We are sorry, it takes longer as expected to get an empty slot. Please try again later or send us an email. Thank you!': 'Nous sommes désolés, il faut plus de temps que prévu pour obtenir un emplacement vide. Veuillez réessayer ultérieurement ou nous envoyer un courriel. Je vous remercie!'
|
||||
},
|
||||
'nl': {
|
||||
'<strong>Chat</strong> with us!': '<strong>Chat</strong> met ons!',
|
||||
'Scroll down to see new messages': 'Scrol naar beneden om nieuwe berichten te zien',
|
||||
'Online': 'Online',
|
||||
'Offline': 'Offline',
|
||||
'Connecting': 'Verbinden',
|
||||
'Connection re-established': 'Verbinding herstelt',
|
||||
'Today': 'Vandaag',
|
||||
'Send': 'Verzenden',
|
||||
'Compose your message...': 'Typ uw bericht...',
|
||||
'All colleagues are busy.': 'Alle medewerkers zijn bezet.',
|
||||
'You are on waiting list position <strong>%s</strong>.': 'U bent <strong>%s</strong> in de wachtrij.',
|
||||
'Start new conversation': 'Nieuwe conversatie starten',
|
||||
'Since you didn\'t respond in the last %s minutes your conversation with <strong>%s</strong> got closed.': 'Omdat u in de laatste %s minuten niets geschreven heeft wordt de conversatie met <strong>%s</strong> gesloten.',
|
||||
'Since you didn\'t respond in the last %s minutes your conversation got closed.': 'Omdat u in de laatste %s minuten niets geschreven heeft is de conversatie gesloten.',
|
||||
'We are sorry, it takes longer as expected to get an empty slot. Please try again later or send us an email. Thank you!': 'Het spijt ons, het duurt langer dan verwacht om te antwoorden. Alstublieft probeer het later nogmaals of stuur ons een email. Hartelijk dank!'
|
||||
},
|
||||
'zh-cn': {
|
||||
'<strong>Chat</strong> with us!': '发起<strong>即时对话</strong>!',
|
||||
'Scroll down to see new messages': '向下滚动以查看新消息',
|
||||
@@ -666,7 +622,7 @@ var bind = function(fn, me){ return function(){ return fn.apply(me, arguments);
|
||||
})(this));
|
||||
this.input.on('paste', (function(_this) {
|
||||
return function(e) {
|
||||
var clipboardData, docType, error, html, htmlTmp, imageFile, imageInserted, item, match, reader, regex, replacementTag, text;
|
||||
var clipboardData, docType, html, htmlTmp, imageFile, imageInserted, item, match, reader, regex, replacementTag, text;
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
clipboardData;
|
||||
@@ -1818,6 +1774,67 @@ var bind = function(fn, me){ return function(){ return fn.apply(me, arguments);
|
||||
return window.ZammadChat = ZammadChat;
|
||||
})(window.jQuery, window);
|
||||
|
||||
if (!window.zammadChatTemplates) {
|
||||
window.zammadChatTemplates = {};
|
||||
}
|
||||
window.zammadChatTemplates["agent"] = function (__obj) {
|
||||
if (!__obj) __obj = {};
|
||||
var __out = [], __capture = function(callback) {
|
||||
var out = __out, result;
|
||||
__out = [];
|
||||
callback.call(this);
|
||||
result = __out.join('');
|
||||
__out = out;
|
||||
return __safe(result);
|
||||
}, __sanitize = function(value) {
|
||||
if (value && value.ecoSafe) {
|
||||
return value;
|
||||
} else if (typeof value !== 'undefined' && value != null) {
|
||||
return __escape(value);
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}, __safe, __objSafe = __obj.safe, __escape = __obj.escape;
|
||||
__safe = __obj.safe = function(value) {
|
||||
if (value && value.ecoSafe) {
|
||||
return value;
|
||||
} else {
|
||||
if (!(typeof value !== 'undefined' && value != null)) value = '';
|
||||
var result = new String(value);
|
||||
result.ecoSafe = true;
|
||||
return result;
|
||||
}
|
||||
};
|
||||
if (!__escape) {
|
||||
__escape = __obj.escape = function(value) {
|
||||
return ('' + value)
|
||||
.replace(/&/g, '&')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>')
|
||||
.replace(/"/g, '"');
|
||||
};
|
||||
}
|
||||
(function() {
|
||||
(function() {
|
||||
if (this.agent.avatar) {
|
||||
__out.push('\n<img class="zammad-chat-agent-avatar" src="');
|
||||
__out.push(__sanitize(this.agent.avatar));
|
||||
__out.push('">\n');
|
||||
}
|
||||
|
||||
__out.push('\n<span class="zammad-chat-agent-sentence">\n <span class="zammad-chat-agent-name">');
|
||||
|
||||
__out.push(__sanitize(this.agent.name));
|
||||
|
||||
__out.push('</span>\n</span>');
|
||||
|
||||
}).call(this);
|
||||
|
||||
}).call(__obj);
|
||||
__obj.safe = __objSafe, __obj.escape = __escape;
|
||||
return __out.join('');
|
||||
};
|
||||
|
||||
if (!window.zammadChatTemplates) {
|
||||
window.zammadChatTemplates = {};
|
||||
}
|
||||
|
||||
3
public/assets/chat/chat.min.js
vendored
3
public/assets/chat/chat.min.js
vendored
File diff suppressed because one or more lines are too long
@@ -124,6 +124,15 @@ $(function() {
|
||||
'Attachments': 'Pièces jointes',
|
||||
'Your Message...': 'Votre message...',
|
||||
},
|
||||
'nl': {
|
||||
'Name': 'Naam',
|
||||
'Your Name': 'Uw naam',
|
||||
'Email': 'Email adres',
|
||||
'Your Email': 'Uw Email adres',
|
||||
'Message': 'Bericht',
|
||||
'Attachments': 'Bijlage',
|
||||
'Your Message...': 'Uw bericht.......',
|
||||
},
|
||||
'zh-cn': {
|
||||
'Name': '联系人',
|
||||
'Your Name': '您的尊姓大名',
|
||||
|
||||
@@ -1321,7 +1321,7 @@ test('table new - initial list', function() {
|
||||
equal(el.find('.js-pager').first().find('.js-page.is-selected').length, 1)
|
||||
equal(el.find('.js-pager').first().find('.js-page.is-selected').text(), '1')
|
||||
|
||||
$('#table').append('<hr><h1>table with data</h1><div id="table-new7"></div>')
|
||||
$('#table').append('<hr><h1>table with data 7</h1><div id="table-new7"></div>')
|
||||
var el = $('#table-new7')
|
||||
|
||||
App.TicketPriority.refresh([
|
||||
@@ -1421,4 +1421,229 @@ test('table new - initial list', function() {
|
||||
equal(el.find('tbody > tr:nth-child(3) > td:nth-child(2)').text().trim(), '10.06.2014', 'check row 3')
|
||||
equal(el.find('tbody > tr:nth-child(4) > td').length, 0, 'check row 3')
|
||||
|
||||
$('#table').append('<hr><h1>table with data 8</h1><div id="table-new8"></div>')
|
||||
var el = $('#table-new8')
|
||||
App.TicketPriority.refresh([
|
||||
{
|
||||
id: 1,
|
||||
name: '1 low',
|
||||
note: 'some note',
|
||||
active: true,
|
||||
created_at: '2014-06-12T11:17:34.000Z',
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: '2 normal',
|
||||
note: 'some note 2',
|
||||
active: false,
|
||||
created_at: '2014-06-10T10:17:34.000Z',
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: '3 high',
|
||||
note: 'some note 3',
|
||||
active: false,
|
||||
created_at: '2014-06-10T10:17:38.000Z',
|
||||
},
|
||||
], {clear: true})
|
||||
|
||||
var table = new App.ControllerTable({
|
||||
el: el,
|
||||
overviewAttributes: ['name', 'created_at', 'active'],
|
||||
model: App.TicketPriority,
|
||||
objects: App.TicketPriority.all(),
|
||||
checkbox: false,
|
||||
radio: false,
|
||||
orderBy: 'not_existing',
|
||||
orderDirection: 'DESC',
|
||||
})
|
||||
|
||||
equal(el.find('table > thead > tr').length, 1, 'row count')
|
||||
equal(el.find('table > thead > tr > th:nth-child(1)').text().trim(), 'Name', 'check header')
|
||||
equal(el.find('table > thead > tr > th:nth-child(2)').text().trim(), 'Erstellt', 'check header')
|
||||
equal(el.find('table > thead > tr > th:nth-child(3)').text().trim(), 'Aktiv', 'check header')
|
||||
equal(el.find('tbody > tr:nth-child(1) > td').length, 3, 'check row 1')
|
||||
equal(el.find('tbody > tr:nth-child(1) > td:first').text().trim(), '1 niedrig', 'check row 1')
|
||||
equal(el.find('tbody > tr:nth-child(1) > td:nth-child(2)').text().trim(), '12.06.2014', 'check row 1')
|
||||
equal(el.find('tbody > tr:nth-child(1) > td:nth-child(3)').text().trim(), 'true', 'check row 1')
|
||||
equal(el.find('tbody > tr:nth-child(2) > td').length, 3, 'check row 2')
|
||||
equal(el.find('tbody > tr:nth-child(2) > td:first').text().trim(), '2 normal', 'check row 2')
|
||||
equal(el.find('tbody > tr:nth-child(2) > td:nth-child(2)').text().trim(), '10.06.2014', 'check row 2')
|
||||
equal(el.find('tbody > tr:nth-child(3) > td').length, 3, 'check row 3')
|
||||
equal(el.find('tbody > tr:nth-child(3) > td:first').text().trim(), '3 hoch', 'check row 3')
|
||||
equal(el.find('tbody > tr:nth-child(3) > td:nth-child(2)').text().trim(), '10.06.2014', 'check row 3')
|
||||
equal(el.find('tbody > tr:nth-child(4) > td').length, 0, 'check row 3')
|
||||
|
||||
result = table.update({sync: true, objects: App.TicketPriority.all(), orderBy: 'not_existing', orderDirection: 'ASC'})
|
||||
equal(result[0], 'noChanges')
|
||||
|
||||
$('#table').append('<hr><h1>table with data 9</h1><div id="table-new9"></div>')
|
||||
var el = $('#table-new9')
|
||||
App.TicketPriority.refresh([
|
||||
{
|
||||
id: 1,
|
||||
name: '1 low',
|
||||
external_id: 3,
|
||||
note: 'some note',
|
||||
active: true,
|
||||
created_at: '2014-06-12T11:17:34.000Z',
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: '2 normal',
|
||||
external_id: 2,
|
||||
note: 'some note 2',
|
||||
active: false,
|
||||
created_at: '2014-06-10T10:17:34.000Z',
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: '3 high',
|
||||
external_id: 1,
|
||||
note: 'some note 3',
|
||||
active: false,
|
||||
created_at: '2014-06-10T10:17:38.000Z',
|
||||
},
|
||||
], {clear: true})
|
||||
|
||||
App.TicketPriority.resetAttributes()
|
||||
App.TicketPriority.updateAttributes([{
|
||||
name: 'external_id',
|
||||
display: 'External',
|
||||
tag: 'input',
|
||||
readonly: 1,
|
||||
}])
|
||||
|
||||
var table = new App.ControllerTable({
|
||||
el: el,
|
||||
overviewAttributes: ['name', 'created_at', 'active'],
|
||||
model: App.TicketPriority,
|
||||
objects: App.TicketPriority.all(),
|
||||
checkbox: false,
|
||||
radio: false,
|
||||
orderBy: 'external',
|
||||
orderDirection: 'DESC',
|
||||
})
|
||||
|
||||
equal(el.find('table > thead > tr').length, 1, 'row count')
|
||||
equal(el.find('table > thead > tr > th:nth-child(1)').text().trim(), 'Name', 'check header')
|
||||
equal(el.find('table > thead > tr > th:nth-child(2)').text().trim(), 'Erstellt', 'check header')
|
||||
equal(el.find('table > thead > tr > th:nth-child(3)').text().trim(), 'Aktiv', 'check header')
|
||||
equal(el.find('tbody > tr:nth-child(1) > td').length, 3, 'check row 1')
|
||||
equal(el.find('tbody > tr:nth-child(1) > td:first').text().trim(), '1 niedrig', 'check row 1')
|
||||
equal(el.find('tbody > tr:nth-child(1) > td:nth-child(2)').text().trim(), '12.06.2014', 'check row 1')
|
||||
equal(el.find('tbody > tr:nth-child(1) > td:nth-child(3)').text().trim(), 'true', 'check row 1')
|
||||
equal(el.find('tbody > tr:nth-child(2) > td').length, 3, 'check row 2')
|
||||
equal(el.find('tbody > tr:nth-child(2) > td:first').text().trim(), '2 normal', 'check row 2')
|
||||
equal(el.find('tbody > tr:nth-child(2) > td:nth-child(2)').text().trim(), '10.06.2014', 'check row 2')
|
||||
equal(el.find('tbody > tr:nth-child(3) > td').length, 3, 'check row 3')
|
||||
equal(el.find('tbody > tr:nth-child(3) > td:first').text().trim(), '3 hoch', 'check row 3')
|
||||
equal(el.find('tbody > tr:nth-child(3) > td:nth-child(2)').text().trim(), '10.06.2014', 'check row 3')
|
||||
equal(el.find('tbody > tr:nth-child(4) > td').length, 0, 'check row 3')
|
||||
|
||||
result = table.update({sync: true, objects: App.TicketPriority.all(), orderBy: 'external', orderDirection: 'ASC'})
|
||||
equal(result[0], 'fullRender.contentChanged')
|
||||
equal(result[1], 0)
|
||||
|
||||
equal(el.find('table > thead > tr').length, 1, 'row count')
|
||||
equal(el.find('table > thead > tr > th:nth-child(1)').text().trim(), 'Name', 'check header')
|
||||
equal(el.find('table > thead > tr > th:nth-child(2)').text().trim(), 'Erstellt', 'check header')
|
||||
equal(el.find('table > thead > tr > th:nth-child(3)').text().trim(), 'Aktiv', 'check header')
|
||||
equal(el.find('tbody > tr:nth-child(1) > td').length, 3, 'check row 3')
|
||||
equal(el.find('tbody > tr:nth-child(1) > td:first').text().trim(), '3 hoch', 'check row 3')
|
||||
equal(el.find('tbody > tr:nth-child(1) > td:nth-child(2)').text().trim(), '10.06.2014', 'check row 3')
|
||||
equal(el.find('tbody > tr:nth-child(2) > td').length, 3, 'check row 2')
|
||||
equal(el.find('tbody > tr:nth-child(2) > td:first').text().trim(), '2 normal', 'check row 2')
|
||||
equal(el.find('tbody > tr:nth-child(2) > td:nth-child(2)').text().trim(), '10.06.2014', 'check row 2')
|
||||
equal(el.find('tbody > tr:nth-child(3) > td').length, 3, 'check row 1')
|
||||
equal(el.find('tbody > tr:nth-child(3) > td:first').text().trim(), '1 niedrig', 'check row 1')
|
||||
equal(el.find('tbody > tr:nth-child(3) > td:nth-child(2)').text().trim(), '12.06.2014', 'check row 1')
|
||||
equal(el.find('tbody > tr:nth-child(3) > td:nth-child(3)').text().trim(), 'true', 'check row 1')
|
||||
|
||||
equal(el.find('tbody > tr:nth-child(4) > td').length, 0, 'check row 3')
|
||||
|
||||
$('#table').append('<hr><h1>table with data 10</h1><div id="table-new10"></div>')
|
||||
var el = $('#table-new10')
|
||||
App.TicketPriority.refresh([
|
||||
{
|
||||
id: 1,
|
||||
name: '1 low',
|
||||
external_id: 3,
|
||||
note: 'some note',
|
||||
active: true,
|
||||
created_at: '2014-06-12T11:17:34.000Z',
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: '2 normal',
|
||||
external_id: 2,
|
||||
note: 'some note 2',
|
||||
active: false,
|
||||
created_at: '2014-06-10T10:17:34.000Z',
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: '3 high',
|
||||
external_id: 1,
|
||||
note: 'some note 3',
|
||||
active: false,
|
||||
created_at: '2014-06-10T10:17:38.000Z',
|
||||
},
|
||||
], {clear: true})
|
||||
App.TicketPriority.resetAttributes()
|
||||
App.TicketPriority.updateAttributes([{
|
||||
name: 'external',
|
||||
display: 'External',
|
||||
tag: 'input',
|
||||
readonly: 1,
|
||||
}])
|
||||
|
||||
var table = new App.ControllerTable({
|
||||
el: el,
|
||||
overviewAttributes: ['name', 'created_at', 'active'],
|
||||
model: App.TicketPriority,
|
||||
objects: App.TicketPriority.all(),
|
||||
checkbox: false,
|
||||
radio: false,
|
||||
orderBy: 'external',
|
||||
orderDirection: 'ASC',
|
||||
})
|
||||
|
||||
equal(el.find('table > thead > tr').length, 1, 'row count')
|
||||
equal(el.find('table > thead > tr > th:nth-child(1)').text().trim(), 'Name', 'check header')
|
||||
equal(el.find('table > thead > tr > th:nth-child(2)').text().trim(), 'Erstellt', 'check header')
|
||||
equal(el.find('table > thead > tr > th:nth-child(3)').text().trim(), 'Aktiv', 'check header')
|
||||
equal(el.find('tbody > tr:nth-child(1) > td').length, 3, 'check row 1')
|
||||
equal(el.find('tbody > tr:nth-child(1) > td:first').text().trim(), '1 niedrig', 'check row 1')
|
||||
equal(el.find('tbody > tr:nth-child(1) > td:nth-child(2)').text().trim(), '12.06.2014', 'check row 1')
|
||||
equal(el.find('tbody > tr:nth-child(1) > td:nth-child(3)').text().trim(), 'true', 'check row 1')
|
||||
equal(el.find('tbody > tr:nth-child(2) > td').length, 3, 'check row 2')
|
||||
equal(el.find('tbody > tr:nth-child(2) > td:first').text().trim(), '2 normal', 'check row 2')
|
||||
equal(el.find('tbody > tr:nth-child(2) > td:nth-child(2)').text().trim(), '10.06.2014', 'check row 2')
|
||||
equal(el.find('tbody > tr:nth-child(3) > td').length, 3, 'check row 3')
|
||||
equal(el.find('tbody > tr:nth-child(3) > td:first').text().trim(), '3 hoch', 'check row 3')
|
||||
equal(el.find('tbody > tr:nth-child(3) > td:nth-child(2)').text().trim(), '10.06.2014', 'check row 3')
|
||||
equal(el.find('tbody > tr:nth-child(4) > td').length, 0, 'check row 3')
|
||||
|
||||
result = table.update({sync: true, objects: App.TicketPriority.all(), orderBy: 'external', orderDirection: 'DESC'})
|
||||
equal(result[0], 'fullRender.contentChanged')
|
||||
equal(result[1], 0)
|
||||
|
||||
equal(el.find('table > thead > tr').length, 1, 'row count')
|
||||
equal(el.find('table > thead > tr > th:nth-child(1)').text().trim(), 'Name', 'check header')
|
||||
equal(el.find('table > thead > tr > th:nth-child(2)').text().trim(), 'Erstellt', 'check header')
|
||||
equal(el.find('table > thead > tr > th:nth-child(3)').text().trim(), 'Aktiv', 'check header')
|
||||
equal(el.find('tbody > tr:nth-child(1) > td').length, 3, 'check row 3')
|
||||
equal(el.find('tbody > tr:nth-child(1) > td:first').text().trim(), '3 hoch', 'check row 3')
|
||||
equal(el.find('tbody > tr:nth-child(1) > td:nth-child(2)').text().trim(), '10.06.2014', 'check row 3')
|
||||
equal(el.find('tbody > tr:nth-child(2) > td').length, 3, 'check row 2')
|
||||
equal(el.find('tbody > tr:nth-child(2) > td:first').text().trim(), '2 normal', 'check row 2')
|
||||
equal(el.find('tbody > tr:nth-child(2) > td:nth-child(2)').text().trim(), '10.06.2014', 'check row 2')
|
||||
equal(el.find('tbody > tr:nth-child(3) > td').length, 3, 'check row 1')
|
||||
equal(el.find('tbody > tr:nth-child(3) > td:first').text().trim(), '1 niedrig', 'check row 1')
|
||||
equal(el.find('tbody > tr:nth-child(3) > td:nth-child(2)').text().trim(), '12.06.2014', 'check row 1')
|
||||
equal(el.find('tbody > tr:nth-child(3) > td:nth-child(3)').text().trim(), 'true', 'check row 1')
|
||||
|
||||
equal(el.find('tbody > tr:nth-child(4) > td').length, 0, 'check row 3')
|
||||
|
||||
})
|
||||
|
||||
@@ -130,6 +130,7 @@ window.onload = function() {
|
||||
"vip": false,
|
||||
"id": 434
|
||||
},
|
||||
"tags": ["tag a", "tag b"],
|
||||
"escalation_at": "2017-02-09T09:16:56.192Z",
|
||||
"last_contact_agent_at": "2017-02-09T09:16:56.192Z",
|
||||
"last_contact_agent_at": "2017-02-09T09:16:56.192Z",
|
||||
@@ -191,7 +192,7 @@ window.onload = function() {
|
||||
},
|
||||
}
|
||||
};
|
||||
result = App.Ticket.selector(ticket, setting['condition'] );
|
||||
result = App.Ticket.selector(ticket, setting['condition']);
|
||||
equal(result, true, result);
|
||||
|
||||
setting = {
|
||||
@@ -202,7 +203,7 @@ window.onload = function() {
|
||||
},
|
||||
}
|
||||
};
|
||||
result = App.Ticket.selector(ticket, setting['condition'] );
|
||||
result = App.Ticket.selector(ticket, setting['condition']);
|
||||
equal(result, false, result);
|
||||
};
|
||||
|
||||
@@ -215,7 +216,7 @@ window.onload = function() {
|
||||
},
|
||||
}
|
||||
};
|
||||
result = App.Ticket.selector(ticket, setting['condition'] );
|
||||
result = App.Ticket.selector(ticket, setting['condition']);
|
||||
equal(result, true, result);
|
||||
|
||||
setting = {
|
||||
@@ -226,7 +227,7 @@ window.onload = function() {
|
||||
},
|
||||
}
|
||||
};
|
||||
result = App.Ticket.selector(ticket, setting['condition'] );
|
||||
result = App.Ticket.selector(ticket, setting['condition']);
|
||||
equal(result, false, result);
|
||||
};
|
||||
|
||||
@@ -243,7 +244,7 @@ window.onload = function() {
|
||||
},
|
||||
}
|
||||
};
|
||||
result = App.Ticket.selector(ticket, setting['condition'] );
|
||||
result = App.Ticket.selector(ticket, setting['condition']);
|
||||
equal(result, true, result);
|
||||
|
||||
setting = {
|
||||
@@ -256,7 +257,7 @@ window.onload = function() {
|
||||
},
|
||||
}
|
||||
};
|
||||
result = App.Ticket.selector(ticket, setting['condition'] );
|
||||
result = App.Ticket.selector(ticket, setting['condition']);
|
||||
equal(result, false, result);
|
||||
|
||||
setting = {
|
||||
@@ -270,7 +271,7 @@ window.onload = function() {
|
||||
}
|
||||
};
|
||||
|
||||
result = App.Ticket.selector(ticket, setting['condition'] );
|
||||
result = App.Ticket.selector(ticket, setting['condition']);
|
||||
equal(result, true, result);
|
||||
|
||||
setting = {
|
||||
@@ -283,7 +284,7 @@ window.onload = function() {
|
||||
}
|
||||
}
|
||||
};
|
||||
result = App.Ticket.selector(ticket, setting['condition'] );
|
||||
result = App.Ticket.selector(ticket, setting['condition']);
|
||||
equal(result, false, result);
|
||||
|
||||
setting = {
|
||||
@@ -296,7 +297,7 @@ window.onload = function() {
|
||||
}
|
||||
}
|
||||
};
|
||||
result = App.Ticket.selector(ticket, setting['condition'] );
|
||||
result = App.Ticket.selector(ticket, setting['condition']);
|
||||
equal(result, false, result);
|
||||
|
||||
setting = {
|
||||
@@ -307,7 +308,7 @@ window.onload = function() {
|
||||
}
|
||||
}
|
||||
};
|
||||
result = App.Ticket.selector(ticket, setting['condition'] );
|
||||
result = App.Ticket.selector(ticket, setting['condition']);
|
||||
equal(result, false, result);
|
||||
|
||||
setting = {
|
||||
@@ -318,7 +319,7 @@ window.onload = function() {
|
||||
}
|
||||
}
|
||||
};
|
||||
result = App.Ticket.selector(ticket, setting['condition'] );
|
||||
result = App.Ticket.selector(ticket, setting['condition']);
|
||||
equal(result, true, result);
|
||||
};
|
||||
|
||||
@@ -335,7 +336,7 @@ window.onload = function() {
|
||||
},
|
||||
}
|
||||
};
|
||||
result = App.Ticket.selector(ticket, setting['condition'] );
|
||||
result = App.Ticket.selector(ticket, setting['condition']);
|
||||
equal(result, true, result);
|
||||
|
||||
setting = {
|
||||
@@ -348,7 +349,7 @@ window.onload = function() {
|
||||
},
|
||||
}
|
||||
};
|
||||
result = App.Ticket.selector(ticket, setting['condition'] );
|
||||
result = App.Ticket.selector(ticket, setting['condition']);
|
||||
equal(result, false, result);
|
||||
|
||||
setting = {
|
||||
@@ -362,7 +363,7 @@ window.onload = function() {
|
||||
}
|
||||
};
|
||||
|
||||
result = App.Ticket.selector(ticket, setting['condition'] );
|
||||
result = App.Ticket.selector(ticket, setting['condition']);
|
||||
equal(result, true, result);
|
||||
|
||||
setting = {
|
||||
@@ -375,7 +376,7 @@ window.onload = function() {
|
||||
}
|
||||
}
|
||||
};
|
||||
result = App.Ticket.selector(ticket, setting['condition'] );
|
||||
result = App.Ticket.selector(ticket, setting['condition']);
|
||||
equal(result, false, result);
|
||||
|
||||
setting = {
|
||||
@@ -388,7 +389,7 @@ window.onload = function() {
|
||||
}
|
||||
}
|
||||
};
|
||||
result = App.Ticket.selector(ticket, setting['condition'] );
|
||||
result = App.Ticket.selector(ticket, setting['condition']);
|
||||
equal(result, false, result);
|
||||
|
||||
setting = {
|
||||
@@ -399,7 +400,7 @@ window.onload = function() {
|
||||
}
|
||||
}
|
||||
};
|
||||
result = App.Ticket.selector(ticket, setting['condition'] );
|
||||
result = App.Ticket.selector(ticket, setting['condition']);
|
||||
equal(result, false, result);
|
||||
|
||||
setting = {
|
||||
@@ -410,10 +411,148 @@ window.onload = function() {
|
||||
}
|
||||
}
|
||||
};
|
||||
result = App.Ticket.selector(ticket, setting['condition'] );
|
||||
result = App.Ticket.selector(ticket, setting['condition']);
|
||||
equal(result, true, result);
|
||||
};
|
||||
|
||||
var testPreConditionTags = function (key, ticket) {
|
||||
App.Session.set(sessionData);
|
||||
|
||||
setting = {
|
||||
"condition": {
|
||||
"ticket.tags": {
|
||||
"operator": "contains one",
|
||||
"value": "tag a",
|
||||
},
|
||||
}
|
||||
};
|
||||
result = App.Ticket.selector(ticket, setting['condition']);
|
||||
equal(result, true, result);
|
||||
|
||||
setting = {
|
||||
"condition": {
|
||||
"ticket.tags": {
|
||||
"operator": "contains one",
|
||||
"value": "tag aa",
|
||||
},
|
||||
}
|
||||
};
|
||||
result = App.Ticket.selector(ticket, setting['condition']);
|
||||
equal(result, false, result);
|
||||
|
||||
setting = {
|
||||
"condition": {
|
||||
"ticket.tags": {
|
||||
"operator": "contains all",
|
||||
"value": "tag a",
|
||||
},
|
||||
}
|
||||
};
|
||||
result = App.Ticket.selector(ticket, setting['condition']);
|
||||
equal(result, true, result);
|
||||
|
||||
setting = {
|
||||
"condition": {
|
||||
"ticket.tags": {
|
||||
"operator": "contains all",
|
||||
"value": ["tag a", "not existing"],
|
||||
},
|
||||
}
|
||||
};
|
||||
result = App.Ticket.selector(ticket, setting['condition']);
|
||||
equal(result, false, result);
|
||||
|
||||
setting = {
|
||||
"condition": {
|
||||
"ticket.tags": {
|
||||
"operator": "contains all not",
|
||||
"value": "tag a",
|
||||
},
|
||||
}
|
||||
};
|
||||
result = App.Ticket.selector(ticket, setting['condition']);
|
||||
equal(result, false, result);
|
||||
|
||||
setting = {
|
||||
"condition": {
|
||||
"ticket.tags": {
|
||||
"operator": "contains all not",
|
||||
"value": ["tag a", "tag b"],
|
||||
},
|
||||
}
|
||||
};
|
||||
result = App.Ticket.selector(ticket, setting['condition']);
|
||||
equal(result, false, result);
|
||||
|
||||
setting = {
|
||||
"condition": {
|
||||
"ticket.tags": {
|
||||
"operator": "contains all not",
|
||||
"value": ["tag a", "tag b", "tag c"],
|
||||
},
|
||||
}
|
||||
};
|
||||
result = App.Ticket.selector(ticket, setting['condition']);
|
||||
equal(result, false, result);
|
||||
|
||||
setting = {
|
||||
"condition": {
|
||||
"ticket.tags": {
|
||||
"operator": "contains all not",
|
||||
"value": ["tag c", "tag d"],
|
||||
},
|
||||
}
|
||||
};
|
||||
result = App.Ticket.selector(ticket, setting['condition']);
|
||||
equal(result, true, result);
|
||||
|
||||
setting = {
|
||||
"condition": {
|
||||
"ticket.tags": {
|
||||
"operator": "contains one not",
|
||||
"value": "tag a",
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
result = App.Ticket.selector(ticket, setting['condition']);
|
||||
equal(result, true, result);
|
||||
|
||||
setting = {
|
||||
"condition": {
|
||||
"ticket.tags": {
|
||||
"operator": "contains one not",
|
||||
"value": ["tag a", "tag b"],
|
||||
},
|
||||
}
|
||||
};
|
||||
result = App.Ticket.selector(ticket, setting['condition']);
|
||||
equal(result, false, result);
|
||||
|
||||
setting = {
|
||||
"condition": {
|
||||
"ticket.tags": {
|
||||
"operator": "contains one not",
|
||||
"value": ["tag a", "tag c"],
|
||||
},
|
||||
}
|
||||
};
|
||||
result = App.Ticket.selector(ticket, setting['condition']);
|
||||
equal(result, true, result);
|
||||
|
||||
setting = {
|
||||
"condition": {
|
||||
"ticket.tags": {
|
||||
"operator": "contains one not",
|
||||
"value": ["tag c"],
|
||||
},
|
||||
}
|
||||
};
|
||||
result = App.Ticket.selector(ticket, setting['condition']);
|
||||
equal(result, true, result);
|
||||
|
||||
};
|
||||
|
||||
var testTime = function (key, value, ticket) {
|
||||
valueDate = new Date(value);
|
||||
compareDate = new Date( valueDate.setHours( valueDate.getHours() - 1 ) ).toISOString();
|
||||
@@ -425,7 +564,7 @@ window.onload = function() {
|
||||
},
|
||||
}
|
||||
};
|
||||
result = App.Ticket.selector(ticket, setting['condition'] );
|
||||
result = App.Ticket.selector(ticket, setting['condition']);
|
||||
equal(result, true, result);
|
||||
|
||||
valueDate = new Date(value);
|
||||
@@ -438,7 +577,7 @@ window.onload = function() {
|
||||
},
|
||||
}
|
||||
};
|
||||
result = App.Ticket.selector(ticket, setting['condition'] );
|
||||
result = App.Ticket.selector(ticket, setting['condition']);
|
||||
equal(result, false, result);
|
||||
|
||||
valueDate = new Date(value);
|
||||
@@ -451,7 +590,7 @@ window.onload = function() {
|
||||
},
|
||||
}
|
||||
};
|
||||
result = App.Ticket.selector(ticket, setting['condition'] );
|
||||
result = App.Ticket.selector(ticket, setting['condition']);
|
||||
equal(result, false, result);
|
||||
|
||||
valueDate = new Date(value);
|
||||
@@ -464,7 +603,7 @@ window.onload = function() {
|
||||
},
|
||||
}
|
||||
};
|
||||
result = App.Ticket.selector(ticket, setting['condition'] );
|
||||
result = App.Ticket.selector(ticket, setting['condition']);
|
||||
equal(result, true, result);
|
||||
|
||||
valueDate = new Date(value);
|
||||
@@ -478,7 +617,7 @@ window.onload = function() {
|
||||
},
|
||||
}
|
||||
};
|
||||
result = App.Ticket.selector(ticket, setting['condition'] );
|
||||
result = App.Ticket.selector(ticket, setting['condition']);
|
||||
equal(result, true, result);
|
||||
};
|
||||
|
||||
@@ -492,7 +631,7 @@ window.onload = function() {
|
||||
},
|
||||
}
|
||||
};
|
||||
result = App.Ticket.selector(ticket, setting['condition'] );
|
||||
result = App.Ticket.selector(ticket, setting['condition']);
|
||||
equal(result, expectedResult, result);
|
||||
};
|
||||
|
||||
@@ -506,7 +645,7 @@ window.onload = function() {
|
||||
},
|
||||
}
|
||||
};
|
||||
result = App.Ticket.selector(ticket, setting['condition'] );
|
||||
result = App.Ticket.selector(ticket, setting['condition']);
|
||||
equal(result, expectedResult, result);
|
||||
};
|
||||
|
||||
@@ -520,7 +659,7 @@ window.onload = function() {
|
||||
},
|
||||
}
|
||||
};
|
||||
result = App.Ticket.selector(ticket, setting['condition'] );
|
||||
result = App.Ticket.selector(ticket, setting['condition']);
|
||||
equal(result, expectedResult, result);
|
||||
};
|
||||
|
||||
@@ -534,7 +673,7 @@ window.onload = function() {
|
||||
},
|
||||
}
|
||||
};
|
||||
result = App.Ticket.selector(ticket, setting['condition'] );
|
||||
result = App.Ticket.selector(ticket, setting['condition']);
|
||||
equal(result, expectedResult, result);
|
||||
};
|
||||
|
||||
@@ -612,7 +751,7 @@ window.onload = function() {
|
||||
testTimeBeforeRelative('ticket.pending_time', 1, 'hour', false, ticket);
|
||||
|
||||
compareDate = new Date();
|
||||
compareDate.setTime( compareDate.getTime() - 60 * 60 * 2 * 1000 );
|
||||
compareDate.setTime( compareDate.getTime() - 60 * 60 * 2 * 1000);
|
||||
ticket.pending_time = compareDate.toISOString();
|
||||
testTimeBeforeRelative('ticket.pending_time', 1, 'hour', true, ticket);
|
||||
|
||||
@@ -621,7 +760,7 @@ window.onload = function() {
|
||||
testTimeBeforeRelative('ticket.pending_time', 1, 'day', false, ticket);
|
||||
|
||||
compareDate = new Date();
|
||||
compareDate.setTime( compareDate.getTime() - 60 * 60 * 48 * 1000 );
|
||||
compareDate.setTime( compareDate.getTime() - 60 * 60 * 48 * 1000);
|
||||
ticket.pending_time = compareDate.toISOString();
|
||||
testTimeBeforeRelative('ticket.pending_time', 1, 'day', true, ticket);
|
||||
|
||||
@@ -630,7 +769,7 @@ window.onload = function() {
|
||||
testTimeBeforeRelative('ticket.pending_time', 1, 'year', false, ticket);
|
||||
|
||||
compareDate = new Date();
|
||||
compareDate.setTime( compareDate.getTime() - 60 * 60 * 365 * 2 * 1000 );
|
||||
compareDate.setTime( compareDate.getTime() - 60 * 60 * 365 * 2 * 1000);
|
||||
ticket.pending_time = compareDate.toISOString();
|
||||
testTimeBeforeRelative('ticket.pending_time', 1, 'year', true, ticket);
|
||||
|
||||
@@ -643,7 +782,7 @@ window.onload = function() {
|
||||
testTimeAfterRelative('ticket.pending_time', 1, 'hour', false, ticket);
|
||||
|
||||
compareDate = new Date();
|
||||
compareDate.setTime( compareDate.getTime() + 60 * 60 * 2 * 1000 );
|
||||
compareDate.setTime( compareDate.getTime() + 60 * 60 * 2 * 1000);
|
||||
ticket.pending_time = compareDate.toISOString();
|
||||
testTimeAfterRelative('ticket.pending_time', 1, 'hour', true, ticket);
|
||||
|
||||
@@ -652,7 +791,7 @@ window.onload = function() {
|
||||
testTimeAfterRelative('ticket.pending_time', 1, 'day', false, ticket);
|
||||
|
||||
compareDate = new Date();
|
||||
compareDate.setTime( compareDate.getTime() + 60 * 60 * 48 * 1000 );
|
||||
compareDate.setTime( compareDate.getTime() + 60 * 60 * 48 * 1000);
|
||||
ticket.pending_time = compareDate.toISOString();
|
||||
testTimeAfterRelative('ticket.pending_time', 1, 'day', true, ticket);
|
||||
|
||||
@@ -661,7 +800,7 @@ window.onload = function() {
|
||||
testTimeAfterRelative('ticket.pending_time', 1, 'year', false, ticket);
|
||||
|
||||
compareDate = new Date();
|
||||
compareDate.setTime( compareDate.getTime() + 60 * 60 * 365 * 2 * 1000 );
|
||||
compareDate.setTime( compareDate.getTime() + 60 * 60 * 365 * 2 * 1000);
|
||||
ticket.pending_time = compareDate.toISOString();
|
||||
testTimeAfterRelative('ticket.pending_time', 1, 'year', true, ticket);
|
||||
|
||||
@@ -672,12 +811,12 @@ window.onload = function() {
|
||||
|
||||
// hour
|
||||
compareDate = new Date();
|
||||
compareDate.setTime( compareDate.getTime() - 60 * 60 * 0.5 * 1000 );
|
||||
compareDate.setTime( compareDate.getTime() - 60 * 60 * 0.5 * 1000);
|
||||
ticket.pending_time = compareDate.toISOString();
|
||||
testTimeWithinLastRelative('ticket.pending_time', 1, 'hour', true, ticket);
|
||||
|
||||
compareDate = new Date();
|
||||
compareDate.setTime( compareDate.getTime() - 60 * 60 * 2 * 1000 );
|
||||
compareDate.setTime( compareDate.getTime() - 60 * 60 * 2 * 1000);
|
||||
ticket.pending_time = compareDate.toISOString();
|
||||
testTimeWithinLastRelative('ticket.pending_time', 1, 'hour', false, ticket);
|
||||
|
||||
@@ -687,12 +826,12 @@ window.onload = function() {
|
||||
|
||||
// hour
|
||||
compareDate = new Date();
|
||||
compareDate.setTime( compareDate.getTime() + 60 * 60 * 0.5 * 1000 );
|
||||
compareDate.setTime( compareDate.getTime() + 60 * 60 * 0.5 * 1000);
|
||||
ticket.pending_time = compareDate.toISOString();
|
||||
testTimeWithinNextRelative('ticket.pending_time', 1, 'hour', true, ticket);
|
||||
|
||||
compareDate = new Date();
|
||||
compareDate.setTime( compareDate.getTime() + 60 * 60 * 2 * 1000 );
|
||||
compareDate.setTime( compareDate.getTime() + 60 * 60 * 2 * 1000);
|
||||
ticket.pending_time = compareDate.toISOString();
|
||||
testTimeWithinNextRelative('ticket.pending_time', 1, 'hour', false, ticket);
|
||||
});
|
||||
@@ -778,6 +917,13 @@ window.onload = function() {
|
||||
testPreConditionUser('ticket.updated_by_id', '6', ticket, sessionData);
|
||||
});
|
||||
|
||||
test("ticket tags", function() {
|
||||
ticket = new App.Ticket();
|
||||
ticket.load(ticketData);
|
||||
|
||||
testPreConditionTags('ticket.tags', ticket);
|
||||
});
|
||||
|
||||
test("article from", function() {
|
||||
ticket = new App.Ticket();
|
||||
ticket.load(ticketData);
|
||||
|
||||
@@ -20,6 +20,7 @@ if [ "$LEVEL" == '1' ]; then
|
||||
rm test/browser/admin_role_test.rb
|
||||
# test/browser/agent_navigation_and_title_test.rb
|
||||
rm test/browser/agent_ticket_attachment_test.rb
|
||||
rm test/browser/agent_ticket_create_reset_customer_selection_test.rb
|
||||
rm test/browser/agent_ticket_email_reply_keep_body_test.rb
|
||||
rm test/browser/agent_ticket_email_signature_test.rb
|
||||
rm test/browser/agent_ticket_link_test.rb
|
||||
@@ -78,6 +79,7 @@ elif [ "$LEVEL" == '2' ]; then
|
||||
rm test/browser/agent_navigation_and_title_test.rb
|
||||
rm test/browser/agent_organization_profile_test.rb
|
||||
rm test/browser/agent_ticket_attachment_test.rb
|
||||
rm test/browser/agent_ticket_create_reset_customer_selection_test.rb
|
||||
rm test/browser/agent_ticket_email_reply_keep_body_test.rb
|
||||
rm test/browser/agent_ticket_email_signature_test.rb
|
||||
rm test/browser/agent_ticket_link_test.rb
|
||||
@@ -136,6 +138,7 @@ elif [ "$LEVEL" == '3' ]; then
|
||||
rm test/browser/agent_navigation_and_title_test.rb
|
||||
rm test/browser/agent_organization_profile_test.rb
|
||||
# test/browser/agent_ticket_attachment_test.rb
|
||||
# test/browser/agent_ticket_create_reset_customer_selection_test.rb
|
||||
# test/browser/agent_ticket_email_reply_keep_body_test.rb
|
||||
# test/browser/agent_ticket_email_signature_test.rb
|
||||
# test/browser/agent_ticket_link_test.rb
|
||||
@@ -194,6 +197,7 @@ elif [ "$LEVEL" == '4' ]; then
|
||||
rm test/browser/agent_navigation_and_title_test.rb
|
||||
rm test/browser/agent_organization_profile_test.rb
|
||||
rm test/browser/agent_ticket_attachment_test.rb
|
||||
rm test/browser/agent_ticket_create_reset_customer_selection_test.rb
|
||||
rm test/browser/agent_ticket_email_reply_keep_body_test.rb
|
||||
rm test/browser/agent_ticket_email_signature_test.rb
|
||||
rm test/browser/agent_ticket_link_test.rb
|
||||
@@ -251,6 +255,7 @@ elif [ "$LEVEL" == '5' ]; then
|
||||
rm test/browser/agent_navigation_and_title_test.rb
|
||||
# test/browser/agent_organization_profile_test.rb
|
||||
rm test/browser/agent_ticket_attachment_test.rb
|
||||
rm test/browser/agent_ticket_create_reset_customer_selection_test.rb
|
||||
rm test/browser/agent_ticket_email_reply_keep_body_test.rb
|
||||
rm test/browser/agent_ticket_email_signature_test.rb
|
||||
rm test/browser/agent_ticket_link_test.rb
|
||||
@@ -311,6 +316,7 @@ elif [ "$LEVEL" == '6' ]; then
|
||||
rm test/browser/agent_navigation_and_title_test.rb
|
||||
rm test/browser/agent_organization_profile_test.rb
|
||||
rm test/browser/agent_ticket_attachment_test.rb
|
||||
rm test/browser/agent_ticket_create_reset_customer_selection_test.rb
|
||||
rm test/browser/agent_ticket_email_reply_keep_body_test.rb
|
||||
rm test/browser/agent_ticket_email_signature_test.rb
|
||||
rm test/browser/agent_ticket_link_test.rb
|
||||
|
||||
@@ -0,0 +1,244 @@
|
||||
|
||||
require 'browser_test_helper'
|
||||
|
||||
class AgentTicketCreateResetCustomerSelectionTest < TestCase
|
||||
def test_clear_customer
|
||||
@browser = browser_instance
|
||||
login(
|
||||
username: 'master@example.com',
|
||||
password: 'test',
|
||||
url: browser_url,
|
||||
)
|
||||
tasks_close_all()
|
||||
|
||||
click(css: 'a[href="#new"]')
|
||||
click(css: 'a[href="#ticket/create"]')
|
||||
sleep 2
|
||||
|
||||
exists(css: '.content.active .newTicket')
|
||||
exists(css: '.content.active .tabsSidebar .sidebar[data-tab="template"]')
|
||||
exists(css: '.content.active .tabsSidebar .tabsSidebar-tab.active[data-tab="template"]')
|
||||
|
||||
exists_not(css: '.content.active .tabsSidebar .sidebar[data-tab="customer"]')
|
||||
exists_not(css: '.content.active .tabsSidebar .tabsSidebar-tab[data-tab="customer"]')
|
||||
|
||||
click(css: '.content.active .newTicket [name="customer_id_completion"]')
|
||||
|
||||
# check if pulldown is open, it's not working stable via selenium
|
||||
@browser.execute_script( "$('.content.active .newTicket .js-recipientDropdown').addClass('open')" )
|
||||
|
||||
set(
|
||||
css: '.content.active .newTicket input[name="customer_id_completion"]',
|
||||
value: 'nicole',
|
||||
)
|
||||
|
||||
sleep 2
|
||||
sendkey(value: :enter)
|
||||
sleep 1
|
||||
|
||||
exists(css: '.content.active .newTicket')
|
||||
exists(css: '.content.active .tabsSidebar .sidebar[data-tab="template"]')
|
||||
exists(css: '.content.active .tabsSidebar .tabsSidebar-tab.active[data-tab="template"]')
|
||||
|
||||
exists(css: '.content.active .tabsSidebar .sidebar[data-tab="customer"]')
|
||||
exists(css: '.content.active .tabsSidebar .tabsSidebar-tab[data-tab="customer"]')
|
||||
|
||||
set(
|
||||
css: '.content.active .newTicket input[name="customer_id_completion"]',
|
||||
value: '',
|
||||
)
|
||||
sendkey(value: :backspace)
|
||||
|
||||
sleep 1
|
||||
|
||||
exists(css: '.content.active .newTicket')
|
||||
exists(css: '.content.active .tabsSidebar .sidebar[data-tab="template"]')
|
||||
exists(css: '.content.active .tabsSidebar .tabsSidebar-tab.active[data-tab="template"]')
|
||||
|
||||
exists_not(css: '.content.active .tabsSidebar .sidebar[data-tab="customer"]')
|
||||
exists_not(css: '.content.active .tabsSidebar .tabsSidebar-tab[data-tab="customer"]')
|
||||
|
||||
set(
|
||||
css: '.content.active .newTicket input[name="title"]',
|
||||
value: 'some title',
|
||||
)
|
||||
|
||||
set(
|
||||
css: '.content.active .newTicket div[data-name="body"]',
|
||||
value: 'some body',
|
||||
)
|
||||
|
||||
select(
|
||||
css: '.content.active .newTicket select[name="group_id"]',
|
||||
value: 'Users',
|
||||
)
|
||||
|
||||
click(css: '.content.active .newTicket .js-submit')
|
||||
|
||||
watch_for(
|
||||
css: '.content.active .newTicket .user_autocompletion.form-group.has-error',
|
||||
)
|
||||
|
||||
# cleanup
|
||||
tasks_close_all()
|
||||
end
|
||||
|
||||
def test_clear_customer_use_email
|
||||
@browser = browser_instance
|
||||
login(
|
||||
username: 'master@example.com',
|
||||
password: 'test',
|
||||
url: browser_url,
|
||||
)
|
||||
tasks_close_all()
|
||||
|
||||
click(css: 'a[href="#new"]')
|
||||
click(css: 'a[href="#ticket/create"]')
|
||||
sleep 2
|
||||
|
||||
exists(css: '.content.active .newTicket')
|
||||
exists(css: '.content.active .tabsSidebar .sidebar[data-tab="template"]')
|
||||
exists(css: '.content.active .tabsSidebar .tabsSidebar-tab.active[data-tab="template"]')
|
||||
|
||||
exists_not(css: '.content.active .tabsSidebar .sidebar[data-tab="customer"]')
|
||||
exists_not(css: '.content.active .tabsSidebar .tabsSidebar-tab[data-tab="customer"]')
|
||||
|
||||
click(css: '.content.active .newTicket [name="customer_id_completion"]')
|
||||
|
||||
# check if pulldown is open, it's not working stable via selenium
|
||||
@browser.execute_script( "$('.content.active .newTicket .js-recipientDropdown').addClass('open')" )
|
||||
|
||||
set(
|
||||
css: '.content.active .newTicket input[name="customer_id_completion"]',
|
||||
value: 'nicole',
|
||||
)
|
||||
|
||||
sleep 2
|
||||
sendkey(value: :enter)
|
||||
sleep 1
|
||||
|
||||
exists(css: '.content.active .newTicket')
|
||||
exists(css: '.content.active .tabsSidebar .sidebar[data-tab="template"]')
|
||||
exists(css: '.content.active .tabsSidebar .tabsSidebar-tab.active[data-tab="template"]')
|
||||
|
||||
exists(css: '.content.active .tabsSidebar .sidebar[data-tab="customer"]')
|
||||
exists(css: '.content.active .tabsSidebar .tabsSidebar-tab[data-tab="customer"]')
|
||||
|
||||
set(
|
||||
css: '.content.active .newTicket input[name="customer_id_completion"]',
|
||||
value: '',
|
||||
)
|
||||
sendkey(value: :backspace)
|
||||
|
||||
sleep 1
|
||||
|
||||
exists(css: '.content.active .newTicket')
|
||||
exists(css: '.content.active .tabsSidebar .sidebar[data-tab="template"]')
|
||||
exists(css: '.content.active .tabsSidebar .tabsSidebar-tab.active[data-tab="template"]')
|
||||
|
||||
exists_not(css: '.content.active .tabsSidebar .sidebar[data-tab="customer"]')
|
||||
exists_not(css: '.content.active .tabsSidebar .tabsSidebar-tab[data-tab="customer"]')
|
||||
|
||||
set(
|
||||
css: '.content.active .newTicket input[name="customer_id_completion"]',
|
||||
value: 'somecustomer_not_existing_right_now@example.com',
|
||||
)
|
||||
|
||||
set(
|
||||
css: '.content.active .newTicket input[name="title"]',
|
||||
value: 'some title',
|
||||
)
|
||||
|
||||
set(
|
||||
css: '.content.active .newTicket div[data-name="body"]',
|
||||
value: 'some body',
|
||||
)
|
||||
|
||||
select(
|
||||
css: '.content.active .newTicket select[name="group_id"]',
|
||||
value: 'Users',
|
||||
)
|
||||
|
||||
click(css: '.content.active .newTicket .js-submit')
|
||||
|
||||
watch_for(
|
||||
css: '.content.active .ticketZoom-header .ticket-number',
|
||||
value: '\d',
|
||||
)
|
||||
|
||||
click(css: '.content.active .tabsSidebar-tabs .tabsSidebar-tab[data-tab="customer"]')
|
||||
|
||||
match(
|
||||
css: '.content.active .tabsSidebar .sidebar[data-tab="customer"]',
|
||||
value: 'somecustomer_not_existing_right_now@example.com',
|
||||
)
|
||||
|
||||
click(css: '.content.active .tabsSidebar .sidebar[data-tab="customer"] .js-actions')
|
||||
click(css: '.content.active .tabsSidebar .sidebar[data-tab="customer"] .js-actions li[data-type="customer-change"]')
|
||||
|
||||
watch_for(
|
||||
css: '.content.active .modal',
|
||||
)
|
||||
|
||||
exists_not(
|
||||
css: '.content.active .modal .user_autocompletion.form-group.has-error',
|
||||
)
|
||||
|
||||
click(css: '.content.active .modal .js-submit')
|
||||
|
||||
watch_for(
|
||||
css: '.content.active .modal .user_autocompletion.form-group.has-error',
|
||||
)
|
||||
|
||||
set(
|
||||
css: '.content.active .modal input[name="customer_id_completion"]',
|
||||
value: 'master',
|
||||
)
|
||||
|
||||
click(css: '.content.active .modal .js-submit')
|
||||
|
||||
watch_for(
|
||||
css: '.content.active .modal .user_autocompletion.form-group.has-error',
|
||||
)
|
||||
|
||||
set(
|
||||
css: '.content.active .modal input[name="customer_id_completion"]',
|
||||
value: 'master',
|
||||
)
|
||||
|
||||
sendkey(value: :enter)
|
||||
sleep 1
|
||||
|
||||
set(
|
||||
css: '.content.active .modal input[name="customer_id_completion"]',
|
||||
value: '',
|
||||
)
|
||||
sendkey(value: :backspace)
|
||||
sleep 1
|
||||
|
||||
click(css: '.content.active .modal .js-submit')
|
||||
|
||||
watch_for(
|
||||
css: '.content.active .modal .user_autocompletion.form-group.has-error',
|
||||
)
|
||||
|
||||
set(
|
||||
css: '.content.active .modal input[name="customer_id_completion"]',
|
||||
value: 'master',
|
||||
)
|
||||
|
||||
sendkey(value: :enter)
|
||||
sleep 1
|
||||
|
||||
click(css: '.content.active .modal .js-submit')
|
||||
#click(css: '.content.active .tabsSidebar-tabs .tabsSidebar-tab[data-tab="customer"]')
|
||||
|
||||
watch_for(
|
||||
css: '.content.active .tabsSidebar .sidebar[data-tab="customer"]',
|
||||
value: 'master@example.com',
|
||||
)
|
||||
|
||||
# cleanup
|
||||
tasks_close_all()
|
||||
end
|
||||
end
|
||||
@@ -19,17 +19,17 @@ class AgentUserManageTest < TestCase
|
||||
sleep 1
|
||||
|
||||
# create customer
|
||||
click( css: 'a[href="#new"]' )
|
||||
click( css: 'a[href="#ticket/create"]' )
|
||||
click( css: '.active .newTicket [name="customer_id_completion"]' )
|
||||
click(css: 'a[href="#new"]')
|
||||
click(css: 'a[href="#ticket/create"]')
|
||||
click(css: '.active .newTicket [name="customer_id_completion"]')
|
||||
|
||||
# check if pulldown is open, it's not working stable via selenium
|
||||
@browser.execute_script( "$('.active .newTicket .js-recipientDropdown').addClass('open')" )
|
||||
|
||||
sleep 1
|
||||
sendkey( value: :arrow_down )
|
||||
sendkey(value: :arrow_down)
|
||||
sleep 0.5
|
||||
click( css: '.active .newTicket .recipientList-entry.js-objectNew' )
|
||||
click(css: '.active .newTicket .recipientList-entry.js-objectNew')
|
||||
sleep 1
|
||||
|
||||
set(
|
||||
@@ -45,7 +45,7 @@ class AgentUserManageTest < TestCase
|
||||
value: customer_user_email,
|
||||
)
|
||||
|
||||
click( css: '.modal button.js-submit' )
|
||||
click(css: '.modal button.js-submit')
|
||||
sleep 4
|
||||
|
||||
# check is used to check selected
|
||||
@@ -75,8 +75,8 @@ class AgentUserManageTest < TestCase
|
||||
# call new ticket screen again
|
||||
tasks_close_all()
|
||||
|
||||
click( css: 'a[href="#new"]' )
|
||||
click( css: 'a[href="#ticket/create"]' )
|
||||
click(css: 'a[href="#new"]')
|
||||
click(css: 'a[href="#ticket/create"]')
|
||||
sleep 2
|
||||
|
||||
match(
|
||||
@@ -93,7 +93,7 @@ class AgentUserManageTest < TestCase
|
||||
)
|
||||
sleep 3
|
||||
|
||||
click( css: '.active .newTicket .recipientList-entry.js-object.is-active' )
|
||||
click(css: '.active .newTicket .recipientList-entry.js-object.is-active')
|
||||
sleep 1
|
||||
|
||||
# check is used to check selected
|
||||
|
||||
@@ -1268,7 +1268,7 @@ set type of task (closeTab, closeNextInOverview, stayOnTab)
|
||||
sleep 0.5
|
||||
return true
|
||||
|
||||
# match pn attribute
|
||||
# match an attribute
|
||||
else
|
||||
text = if params[:attribute]
|
||||
element.attribute(params[:attribute])
|
||||
|
||||
@@ -245,8 +245,8 @@ class FormControllerTest < ActionDispatch::IntegrationTest
|
||||
end
|
||||
|
||||
test '06 - customer_ticket_create false disables form' do
|
||||
Setting.set('form_ticket_create', true)
|
||||
Setting.set('customer_ticket_create', false)
|
||||
Setting.set('form_ticket_create', false)
|
||||
Setting.set('customer_ticket_create', true)
|
||||
|
||||
fingerprint = SecureRandom.hex(40)
|
||||
|
||||
|
||||
179
test/controllers/overviews_controller_test.rb
Normal file
179
test/controllers/overviews_controller_test.rb
Normal file
@@ -0,0 +1,179 @@
|
||||
|
||||
require 'test_helper'
|
||||
|
||||
class OverviewsControllerTest < ActionDispatch::IntegrationTest
|
||||
setup do
|
||||
|
||||
# set accept header
|
||||
@headers = { 'ACCEPT' => 'application/json', 'CONTENT_TYPE' => 'application/json' }
|
||||
|
||||
# create agent
|
||||
roles = Role.where(name: %w(Admin Agent))
|
||||
groups = Group.all
|
||||
|
||||
UserInfo.current_user_id = 1
|
||||
@admin = User.create_or_update(
|
||||
login: 'tickets-admin',
|
||||
firstname: 'Tickets',
|
||||
lastname: 'Admin',
|
||||
email: 'tickets-admin@example.com',
|
||||
password: 'adminpw',
|
||||
active: true,
|
||||
roles: roles,
|
||||
groups: groups,
|
||||
)
|
||||
|
||||
# create agent
|
||||
roles = Role.where(name: 'Agent')
|
||||
@agent = User.create_or_update(
|
||||
login: 'tickets-agent@example.com',
|
||||
firstname: 'Tickets',
|
||||
lastname: 'Agent',
|
||||
email: 'tickets-agent@example.com',
|
||||
password: 'agentpw',
|
||||
active: true,
|
||||
roles: roles,
|
||||
groups: Group.all,
|
||||
)
|
||||
|
||||
end
|
||||
|
||||
test 'no permissions' do
|
||||
credentials = ActionController::HttpAuthentication::Basic.encode_credentials('tickets-agent', 'agentpw')
|
||||
|
||||
params = {
|
||||
name: 'Overview2',
|
||||
link: 'my_overview',
|
||||
condition: {
|
||||
'ticket.state_id' => {
|
||||
operator: 'is',
|
||||
value: [1, 2, 3],
|
||||
},
|
||||
},
|
||||
order: {
|
||||
by: 'created_at',
|
||||
direction: 'DESC',
|
||||
},
|
||||
view: {
|
||||
d: %w(title customer state created_at),
|
||||
s: %w(number title customer state created_at),
|
||||
m: %w(number title customer state created_at),
|
||||
view_mode_default: 's',
|
||||
},
|
||||
}
|
||||
|
||||
post '/api/v1/overviews', params: params.to_json, headers: @headers.merge('Authorization' => credentials)
|
||||
assert_response(401)
|
||||
result = JSON.parse(@response.body)
|
||||
assert_equal(Hash, result.class)
|
||||
assert_equal('authentication failed', result['error'])
|
||||
end
|
||||
|
||||
test 'create overviews' do
|
||||
credentials = ActionController::HttpAuthentication::Basic.encode_credentials('tickets-admin', 'adminpw')
|
||||
|
||||
params = {
|
||||
name: 'Overview2',
|
||||
link: 'my_overview',
|
||||
condition: {
|
||||
'ticket.state_id' => {
|
||||
operator: 'is',
|
||||
value: [1, 2, 3],
|
||||
},
|
||||
},
|
||||
order: {
|
||||
by: 'created_at',
|
||||
direction: 'DESC',
|
||||
},
|
||||
view: {
|
||||
d: %w(title customer state created_at),
|
||||
s: %w(number title customer state created_at),
|
||||
m: %w(number title customer state created_at),
|
||||
view_mode_default: 's',
|
||||
},
|
||||
}
|
||||
|
||||
post '/api/v1/overviews', params: params.to_json, headers: @headers.merge('Authorization' => credentials)
|
||||
assert_response(201)
|
||||
result = JSON.parse(@response.body)
|
||||
assert_equal(Hash, result.class)
|
||||
assert_equal('Overview2', result['name'])
|
||||
assert_equal('my_overview', result['link'])
|
||||
|
||||
post '/api/v1/overviews', params: params.to_json, headers: @headers.merge('Authorization' => credentials)
|
||||
assert_response(201)
|
||||
result = JSON.parse(@response.body)
|
||||
assert_equal(Hash, result.class)
|
||||
assert_equal('Overview2', result['name'])
|
||||
assert_equal('my_overview_1', result['link'])
|
||||
end
|
||||
|
||||
test 'set mass prio' do
|
||||
overview1 = Overview.create!(
|
||||
name: 'Overview1',
|
||||
link: 'my_overview',
|
||||
condition: {
|
||||
'ticket.state_id' => {
|
||||
operator: 'is',
|
||||
value: [1, 2, 3],
|
||||
},
|
||||
},
|
||||
order: {
|
||||
by: 'created_at',
|
||||
direction: 'DESC',
|
||||
},
|
||||
view: {
|
||||
d: %w(title customer state created_at),
|
||||
s: %w(number title customer state created_at),
|
||||
m: %w(number title customer state created_at),
|
||||
view_mode_default: 's',
|
||||
},
|
||||
prio: 1,
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
)
|
||||
overview2 = Overview.create!(
|
||||
name: 'Overview2',
|
||||
link: 'my_overview',
|
||||
condition: {
|
||||
'ticket.state_id' => {
|
||||
operator: 'is',
|
||||
value: [1, 2, 3],
|
||||
},
|
||||
},
|
||||
order: {
|
||||
by: 'created_at',
|
||||
direction: 'DESC',
|
||||
},
|
||||
view: {
|
||||
d: %w(title customer state created_at),
|
||||
s: %w(number title customer state created_at),
|
||||
m: %w(number title customer state created_at),
|
||||
view_mode_default: 's',
|
||||
},
|
||||
prio: 2,
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
)
|
||||
|
||||
credentials = ActionController::HttpAuthentication::Basic.encode_credentials('tickets-admin', 'adminpw')
|
||||
params = {
|
||||
prios: [
|
||||
[overview2.id, 1],
|
||||
[overview1.id, 2],
|
||||
]
|
||||
}
|
||||
post '/api/v1/overviews_prio', params: params.to_json, headers: @headers.merge('Authorization' => credentials)
|
||||
assert_response(200)
|
||||
result = JSON.parse(@response.body)
|
||||
assert_equal(Hash, result.class)
|
||||
assert_equal(true, result['success'])
|
||||
|
||||
overview1.reload
|
||||
overview2.reload
|
||||
|
||||
assert_equal(2, overview1.prio)
|
||||
assert_equal(1, overview2.prio)
|
||||
end
|
||||
|
||||
end
|
||||
14
test/fixtures/seeds.rb
vendored
14
test/fixtures/seeds.rb
vendored
@@ -20,5 +20,17 @@ email_address = EmailAddress.create_or_update(
|
||||
)
|
||||
Group.all.each do |group|
|
||||
group.email_address_id = email_address.id
|
||||
group.save
|
||||
group.save!
|
||||
end
|
||||
|
||||
User.create_or_update(
|
||||
login: 'admin@example.com',
|
||||
firstname: 'Default',
|
||||
lastname: 'Admin',
|
||||
email: 'admin@example.com',
|
||||
password: 'adminpw',
|
||||
active: true,
|
||||
roles: Role.where(name: %w(Admin)),
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
)
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
require 'integration_test_helper'
|
||||
|
||||
class ClearbitTest < ActiveSupport::TestCase
|
||||
self.use_transactional_tests = true
|
||||
|
||||
# check
|
||||
test 'base' do
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
require 'integration_test_helper'
|
||||
|
||||
class FacebookTest < ActiveSupport::TestCase
|
||||
self.test_order = :sorted
|
||||
self.use_transactional_tests = false
|
||||
|
||||
# set system mode to done / to activate
|
||||
Setting.set('system_init_done', true)
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
require 'test_helper'
|
||||
|
||||
class ObjectManagerTest < ActiveSupport::TestCase
|
||||
self.use_transactional_tests = false
|
||||
|
||||
test 'a object manager' do
|
||||
|
||||
list_objects = ObjectManager.list_objects
|
||||
@@ -2,6 +2,8 @@
|
||||
require 'test_helper'
|
||||
|
||||
class PackageTest < ActiveSupport::TestCase
|
||||
self.use_transactional_tests = false
|
||||
|
||||
test 'packages' do
|
||||
tests = [
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
require 'integration_test_helper'
|
||||
|
||||
class TwitterTest < ActiveSupport::TestCase
|
||||
self.test_order = :sorted
|
||||
self.use_transactional_tests = false
|
||||
|
||||
# set system mode to done / to activate
|
||||
Setting.set('system_init_done', true)
|
||||
|
||||
@@ -2,13 +2,16 @@
|
||||
require 'test_helper'
|
||||
|
||||
class UserDeviceControllerTest < ActionDispatch::IntegrationTest
|
||||
self.test_order = :sorted
|
||||
self.use_transactional_tests = false
|
||||
|
||||
setup do
|
||||
|
||||
# set accept header
|
||||
@headers = { 'ACCEPT' => 'application/json', 'CONTENT_TYPE' => 'application/json' }
|
||||
|
||||
# create agent
|
||||
roles = Role.where( name: %w(Admin Agent) )
|
||||
roles = Role.where(name: %w(Admin Agent))
|
||||
groups = Group.all
|
||||
|
||||
UserInfo.current_user_id = 1
|
||||
@@ -24,7 +27,7 @@ class UserDeviceControllerTest < ActionDispatch::IntegrationTest
|
||||
)
|
||||
|
||||
# create agent
|
||||
roles = Role.where( name: 'Agent' )
|
||||
roles = Role.where(name: 'Agent')
|
||||
@agent = User.create_or_update(
|
||||
login: 'user-device-agent',
|
||||
firstname: 'UserDevice',
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
require 'integration_test_helper'
|
||||
|
||||
class ZendeskImportTest < ActiveSupport::TestCase
|
||||
self.test_order = :sorted
|
||||
self.use_transactional_tests = false
|
||||
|
||||
if !ENV['IMPORT_ZENDESK_ENDPOINT']
|
||||
raise "ERROR: Need IMPORT_ZENDESK_ENDPOINT - hint IMPORT_ZENDESK_ENDPOINT='https://example.zendesk.com/api/v2'"
|
||||
@@ -45,7 +47,7 @@ class ZendeskImportTest < ActiveSupport::TestCase
|
||||
|
||||
# check count of imported items
|
||||
test 'check counts' do
|
||||
assert_equal(143, User.count, 'users')
|
||||
assert_equal(144, User.count, 'users')
|
||||
assert_equal(3, Group.count, 'groups')
|
||||
assert_equal(3, Role.count, 'roles')
|
||||
assert_equal(2, Organization.count, 'organizations')
|
||||
@@ -69,7 +71,7 @@ class ZendeskImportTest < ActiveSupport::TestCase
|
||||
|
||||
checks = [
|
||||
{
|
||||
id: 4,
|
||||
id: 5,
|
||||
data: {
|
||||
firstname: 'Bob',
|
||||
lastname: 'Smith',
|
||||
@@ -83,7 +85,7 @@ class ZendeskImportTest < ActiveSupport::TestCase
|
||||
groups: [group_support],
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
id: 6,
|
||||
data: {
|
||||
firstname: 'Hansimerkur',
|
||||
lastname: '',
|
||||
@@ -96,7 +98,7 @@ class ZendeskImportTest < ActiveSupport::TestCase
|
||||
groups: [group_additional_group, group_support],
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
id: 7,
|
||||
data: {
|
||||
firstname: 'Bernd',
|
||||
lastname: 'Hofbecker',
|
||||
@@ -108,7 +110,7 @@ class ZendeskImportTest < ActiveSupport::TestCase
|
||||
groups: [],
|
||||
},
|
||||
{
|
||||
id: 7,
|
||||
id: 8,
|
||||
data: {
|
||||
firstname: 'Zendesk',
|
||||
lastname: '',
|
||||
@@ -120,7 +122,7 @@ class ZendeskImportTest < ActiveSupport::TestCase
|
||||
groups: [],
|
||||
},
|
||||
{
|
||||
id: 89,
|
||||
id: 90,
|
||||
data: {
|
||||
firstname: 'Hans',
|
||||
lastname: 'Peter Wurst',
|
||||
@@ -309,7 +311,7 @@ class ZendeskImportTest < ActiveSupport::TestCase
|
||||
group_id: 3,
|
||||
priority_id: 3,
|
||||
owner_id: 1,
|
||||
customer_id: 6,
|
||||
customer_id: 7,
|
||||
organization_id: 2,
|
||||
test_checkbox: true,
|
||||
custom_integer: 999,
|
||||
@@ -332,7 +334,7 @@ If you\'re reading this message in your email, click the ticket number link that
|
||||
group_id: 3,
|
||||
priority_id: 1,
|
||||
owner_id: 1,
|
||||
customer_id: 7,
|
||||
customer_id: 8,
|
||||
organization_id: nil,
|
||||
test_checkbox: false,
|
||||
custom_integer: nil,
|
||||
@@ -353,7 +355,7 @@ If you\'re reading this message in your email, click the ticket number link that
|
||||
group_id: 3,
|
||||
priority_id: 2,
|
||||
owner_id: 1,
|
||||
customer_id: 91,
|
||||
customer_id: 92,
|
||||
organization_id: nil,
|
||||
},
|
||||
},
|
||||
@@ -369,7 +371,7 @@ If you\'re reading this message in your email, click the ticket number link that
|
||||
group_id: 1,
|
||||
priority_id: 2,
|
||||
owner_id: 1,
|
||||
customer_id: 143,
|
||||
customer_id: 144,
|
||||
organization_id: nil,
|
||||
},
|
||||
},
|
||||
|
||||
@@ -4,8 +4,9 @@ require 'rails/test_help'
|
||||
require 'cache'
|
||||
|
||||
class ActiveSupport::TestCase
|
||||
# disable transactions
|
||||
#self.use_transactional_tests = false
|
||||
|
||||
# disable transactions / to work with own database connections for each thread
|
||||
self.use_transactional_tests = false
|
||||
|
||||
ActiveRecord::Base.logger = Rails.logger.clone
|
||||
ActiveRecord::Base.logger.level = Logger::INFO
|
||||
@@ -22,15 +23,12 @@ class ActiveSupport::TestCase
|
||||
# clear cache
|
||||
Cache.clear
|
||||
|
||||
# reload settings
|
||||
Setting.reload
|
||||
|
||||
# remove all session messages
|
||||
Sessions.cleanup
|
||||
|
||||
# remove background jobs
|
||||
Delayed::Job.destroy_all
|
||||
Trigger.destroy_all
|
||||
ActivityStream.destroy_all
|
||||
PostmasterFilter.destroy_all
|
||||
|
||||
# set current user
|
||||
UserInfo.current_user_id = nil
|
||||
end
|
||||
|
||||
@@ -7,10 +7,7 @@ require 'simplecov-rcov'
|
||||
require 'coveralls'
|
||||
Coveralls.wear!
|
||||
|
||||
#ActiveSupport::TestCase.test_order = :sorted
|
||||
|
||||
class ActiveSupport::TestCase
|
||||
self.test_order = :sorted
|
||||
|
||||
ActiveRecord::Base.logger = Rails.logger.clone
|
||||
ActiveRecord::Base.logger.level = Logger::INFO
|
||||
@@ -27,9 +24,6 @@ class ActiveSupport::TestCase
|
||||
SimpleCov.start
|
||||
fixtures :all
|
||||
|
||||
# disable transactions
|
||||
self.use_transactional_tests = false
|
||||
|
||||
# clear cache
|
||||
Cache.clear
|
||||
|
||||
@@ -52,27 +46,12 @@ class ActiveSupport::TestCase
|
||||
# clear cache
|
||||
Cache.clear
|
||||
|
||||
# reload settings
|
||||
Setting.reload
|
||||
|
||||
# remove all session messages
|
||||
Sessions.cleanup
|
||||
|
||||
# remove background jobs
|
||||
Delayed::Job.destroy_all
|
||||
Trigger.destroy_all
|
||||
ActivityStream.destroy_all
|
||||
PostmasterFilter.destroy_all
|
||||
Ticket.destroy_all
|
||||
Taskbar.destroy_all
|
||||
Sla.destroy_all
|
||||
Calendar.destroy_all
|
||||
|
||||
# reset settings
|
||||
Setting.all.pluck(:name).each do |name|
|
||||
next if name == 'models_searchable' # skip setting
|
||||
Setting.reset(name, false)
|
||||
end
|
||||
Setting.set('system_init_done', true)
|
||||
Setting.reload
|
||||
|
||||
# set current user
|
||||
UserInfo.current_user_id = nil
|
||||
|
||||
|
||||
@@ -1,566 +0,0 @@
|
||||
# encoding: utf-8
|
||||
require 'test_helper'
|
||||
|
||||
class AssetsTest < ActiveSupport::TestCase
|
||||
test 'user' do
|
||||
|
||||
roles = Role.where(name: %w(Agent Admin))
|
||||
groups = Group.all
|
||||
org1 = Organization.create_or_update(
|
||||
name: 'some user org',
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
)
|
||||
|
||||
user1 = User.create_or_update(
|
||||
login: 'assets1@example.org',
|
||||
firstname: 'assets1',
|
||||
lastname: 'assets1',
|
||||
email: 'assets1@example.org',
|
||||
password: 'some_pass',
|
||||
active: true,
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
organization_id: org1.id,
|
||||
roles: roles,
|
||||
groups: groups,
|
||||
)
|
||||
|
||||
user2 = User.create_or_update(
|
||||
login: 'assets2@example.org',
|
||||
firstname: 'assets2',
|
||||
lastname: 'assets2',
|
||||
email: 'assets2@example.org',
|
||||
password: 'some_pass',
|
||||
active: true,
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
roles: roles,
|
||||
groups: groups,
|
||||
)
|
||||
|
||||
user3 = User.create_or_update(
|
||||
login: 'assets3@example.org',
|
||||
firstname: 'assets3',
|
||||
lastname: 'assets3',
|
||||
email: 'assets3@example.org',
|
||||
password: 'some_pass',
|
||||
active: true,
|
||||
updated_by_id: user1.id,
|
||||
created_by_id: user2.id,
|
||||
roles: roles,
|
||||
groups: groups,
|
||||
)
|
||||
user3 = User.find(user3.id)
|
||||
assets = user3.assets({})
|
||||
|
||||
org1 = Organization.find(org1.id)
|
||||
attributes = org1.attributes_with_association_ids
|
||||
attributes.delete('user_ids')
|
||||
assert( diff(attributes, assets[:Organization][org1.id]), 'check assets')
|
||||
|
||||
user1 = User.find(user1.id)
|
||||
attributes = user1.attributes_with_association_ids
|
||||
attributes['accounts'] = {}
|
||||
attributes.delete('password')
|
||||
attributes.delete('token_ids')
|
||||
attributes.delete('authorization_ids')
|
||||
assert( diff(attributes, assets[:User][user1.id]), 'check assets' )
|
||||
|
||||
user2 = User.find(user2.id)
|
||||
attributes = user2.attributes_with_association_ids
|
||||
attributes['accounts'] = {}
|
||||
attributes.delete('password')
|
||||
attributes.delete('token_ids')
|
||||
attributes.delete('authorization_ids')
|
||||
assert( diff(attributes, assets[:User][user2.id]), 'check assets' )
|
||||
|
||||
user3 = User.find(user3.id)
|
||||
attributes = user3.attributes_with_association_ids
|
||||
attributes['accounts'] = {}
|
||||
attributes.delete('password')
|
||||
attributes.delete('token_ids')
|
||||
attributes.delete('authorization_ids')
|
||||
assert( diff(attributes, assets[:User][user3.id]), 'check assets' )
|
||||
|
||||
# touch org, check if user1 has changed
|
||||
travel 2.seconds
|
||||
org2 = Organization.find(org1.id)
|
||||
org2.note = "some note...#{rand(9_999_999_999_999)}"
|
||||
org2.save!
|
||||
|
||||
attributes = org2.attributes_with_association_ids
|
||||
attributes.delete('user_ids')
|
||||
assert( !diff(attributes, assets[:Organization][org2.id]), 'check assets' )
|
||||
|
||||
user1_new = User.find(user1.id)
|
||||
attributes = user1_new.attributes_with_association_ids
|
||||
attributes['accounts'] = {}
|
||||
attributes.delete('password')
|
||||
attributes.delete('token_ids')
|
||||
attributes.delete('authorization_ids')
|
||||
assert( !diff(attributes, assets[:User][user1_new.id]), 'check assets' )
|
||||
|
||||
# check new assets lookup
|
||||
assets = user3.assets({})
|
||||
attributes = org2.attributes_with_association_ids
|
||||
attributes.delete('user_ids')
|
||||
assert( diff(attributes, assets[:Organization][org1.id]), 'check assets')
|
||||
|
||||
user1 = User.find(user1.id)
|
||||
attributes = user1.attributes_with_association_ids
|
||||
attributes['accounts'] = {}
|
||||
attributes.delete('password')
|
||||
attributes.delete('token_ids')
|
||||
attributes.delete('authorization_ids')
|
||||
assert( diff(attributes, assets[:User][user1.id]), 'check assets' )
|
||||
|
||||
user2 = User.find(user2.id)
|
||||
attributes = user2.attributes_with_association_ids
|
||||
attributes['accounts'] = {}
|
||||
attributes.delete('password')
|
||||
attributes.delete('token_ids')
|
||||
attributes.delete('authorization_ids')
|
||||
assert( diff(attributes, assets[:User][user2.id]), 'check assets' )
|
||||
|
||||
user3 = User.find(user3.id)
|
||||
attributes = user3.attributes_with_association_ids
|
||||
attributes['accounts'] = {}
|
||||
attributes.delete('password')
|
||||
attributes.delete('token_ids')
|
||||
attributes.delete('authorization_ids')
|
||||
assert( diff(attributes, assets[:User][user3.id]), 'check assets' )
|
||||
travel_back
|
||||
|
||||
user3.destroy!
|
||||
user2.destroy!
|
||||
user1.destroy!
|
||||
org1.destroy!
|
||||
assert_not(Organization.find_by(id: org2.id))
|
||||
end
|
||||
|
||||
test 'organization' do
|
||||
|
||||
roles = Role.where( name: %w(Agent Admin) )
|
||||
admin1 = User.create_or_update(
|
||||
login: 'admin1@example.org',
|
||||
firstname: 'admin1',
|
||||
lastname: 'admin1',
|
||||
email: 'admin1@example.org',
|
||||
password: 'some_pass',
|
||||
active: true,
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
roles: roles,
|
||||
)
|
||||
|
||||
roles = Role.where( name: %w(Customer) )
|
||||
org = Organization.create_or_update(
|
||||
name: 'some customer org',
|
||||
updated_by_id: admin1.id,
|
||||
created_by_id: 1,
|
||||
)
|
||||
|
||||
user1 = User.create_or_update(
|
||||
login: 'assets1@example.org',
|
||||
firstname: 'assets1',
|
||||
lastname: 'assets1',
|
||||
email: 'assets1@example.org',
|
||||
password: 'some_pass',
|
||||
active: true,
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
organization_id: org.id,
|
||||
roles: roles,
|
||||
)
|
||||
|
||||
user2 = User.create_or_update(
|
||||
login: 'assets2@example.org',
|
||||
firstname: 'assets2',
|
||||
lastname: 'assets2',
|
||||
email: 'assets2@example.org',
|
||||
password: 'some_pass',
|
||||
active: true,
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
organization_id: org.id,
|
||||
roles: roles,
|
||||
)
|
||||
|
||||
user3 = User.create_or_update(
|
||||
login: 'assets3@example.org',
|
||||
firstname: 'assets3',
|
||||
lastname: 'assets3',
|
||||
email: 'assets3@example.org',
|
||||
password: 'some_pass',
|
||||
active: true,
|
||||
updated_by_id: user1.id,
|
||||
created_by_id: user2.id,
|
||||
roles: roles,
|
||||
)
|
||||
|
||||
org = Organization.find(org.id)
|
||||
assets = org.assets({})
|
||||
attributes = org.attributes_with_association_ids
|
||||
attributes.delete('user_ids')
|
||||
assert( diff(attributes, assets[:Organization][org.id]), 'check assets' )
|
||||
|
||||
admin1 = User.find(admin1.id)
|
||||
attributes = admin1.attributes_with_association_ids
|
||||
attributes['accounts'] = {}
|
||||
attributes.delete('password')
|
||||
attributes.delete('token_ids')
|
||||
attributes.delete('authorization_ids')
|
||||
assert( diff(attributes, assets[:User][admin1.id]), 'check assets' )
|
||||
|
||||
user1 = User.find(user1.id)
|
||||
attributes = user1.attributes_with_association_ids
|
||||
attributes['accounts'] = {}
|
||||
attributes.delete('password')
|
||||
attributes.delete('token_ids')
|
||||
attributes.delete('authorization_ids')
|
||||
assert( diff(attributes, assets[:User][user1.id]), 'check assets' )
|
||||
|
||||
user2 = User.find(user2.id)
|
||||
attributes = user2.attributes_with_association_ids
|
||||
attributes['accounts'] = {}
|
||||
attributes.delete('password')
|
||||
attributes.delete('token_ids')
|
||||
attributes.delete('authorization_ids')
|
||||
assert( diff(attributes, assets[:User][user2.id]), 'check assets' )
|
||||
|
||||
user3 = User.find(user3.id)
|
||||
attributes = user3.attributes_with_association_ids
|
||||
attributes['accounts'] = {}
|
||||
attributes.delete('password')
|
||||
attributes.delete('token_ids')
|
||||
attributes.delete('authorization_ids')
|
||||
assert_nil( assets[:User][user3.id], 'check assets' )
|
||||
|
||||
# touch user 2, check if org has changed
|
||||
travel 2.seconds
|
||||
user_new_2 = User.find(user2.id)
|
||||
user_new_2.lastname = 'assets2'
|
||||
user_new_2.save!
|
||||
|
||||
org_new = Organization.find(org.id)
|
||||
attributes = org_new.attributes_with_association_ids
|
||||
attributes.delete('user_ids')
|
||||
assert( !diff(attributes, assets[:Organization][org_new.id]), 'check assets' )
|
||||
|
||||
attributes = user_new_2.attributes_with_association_ids
|
||||
attributes['accounts'] = {}
|
||||
attributes.delete('password')
|
||||
attributes.delete('token_ids')
|
||||
attributes.delete('authorization_ids')
|
||||
assert( diff(attributes, assets[:User][user_new_2.id]), 'check assets' )
|
||||
|
||||
# check new assets lookup
|
||||
assets = org_new.assets({})
|
||||
attributes = org_new.attributes_with_association_ids
|
||||
attributes.delete('user_ids')
|
||||
assert( diff(attributes, assets[:Organization][org_new.id]), 'check assets' )
|
||||
|
||||
attributes = user_new_2.attributes_with_association_ids
|
||||
attributes['accounts'] = {}
|
||||
attributes.delete('password')
|
||||
attributes.delete('token_ids')
|
||||
attributes.delete('authorization_ids')
|
||||
assert( diff(attributes, assets[:User][user_new_2.id]), 'check assets' )
|
||||
travel_back
|
||||
|
||||
user3.destroy!
|
||||
user2.destroy!
|
||||
user1.destroy!
|
||||
org.destroy!
|
||||
assert_not(Organization.find_by(id: org_new.id))
|
||||
end
|
||||
|
||||
def diff(o1, o2)
|
||||
return true if o1 == o2
|
||||
%w(updated_at created_at).each do |item|
|
||||
if o1[item]
|
||||
o1[item] = o1[item].to_s
|
||||
end
|
||||
if o2[item]
|
||||
o2[item] = o2[item].to_s
|
||||
end
|
||||
end
|
||||
return true if (o1.to_a - o2.to_a).empty?
|
||||
#puts "ERROR: difference \n1: #{o1.inspect}\n2: #{o2.inspect}\ndiff: #{(o1.to_a - o2.to_a).inspect}"
|
||||
false
|
||||
end
|
||||
|
||||
test 'overview' do
|
||||
|
||||
UserInfo.current_user_id = 1
|
||||
roles = Role.where(name: %w(Customer))
|
||||
|
||||
user1 = User.create_or_update(
|
||||
login: 'assets_overview1@example.org',
|
||||
firstname: 'assets_overview1',
|
||||
lastname: 'assets_overview1',
|
||||
email: 'assets_overview1@example.org',
|
||||
password: 'some_pass',
|
||||
active: true,
|
||||
roles: roles,
|
||||
)
|
||||
user2 = User.create_or_update(
|
||||
login: 'assets_overview2@example.org',
|
||||
firstname: 'assets_overview2',
|
||||
lastname: 'assets_overview2',
|
||||
email: 'assets_overview2@example.org',
|
||||
password: 'some_pass',
|
||||
active: true,
|
||||
roles: roles,
|
||||
)
|
||||
user3 = User.create_or_update(
|
||||
login: 'assets_overview3@example.org',
|
||||
firstname: 'assets_overview3',
|
||||
lastname: 'assets_overview3',
|
||||
email: 'assets_overview3@example.org',
|
||||
password: 'some_pass',
|
||||
active: true,
|
||||
roles: roles,
|
||||
)
|
||||
user4 = User.create_or_update(
|
||||
login: 'assets_overview4@example.org',
|
||||
firstname: 'assets_overview4',
|
||||
lastname: 'assets_overview4',
|
||||
email: 'assets_overview4@example.org',
|
||||
password: 'some_pass',
|
||||
active: true,
|
||||
roles: roles,
|
||||
)
|
||||
user5 = User.create_or_update(
|
||||
login: 'assets_overview5@example.org',
|
||||
firstname: 'assets_overview5',
|
||||
lastname: 'assets_overview5',
|
||||
email: 'assets_overview5@example.org',
|
||||
password: 'some_pass',
|
||||
active: true,
|
||||
roles: roles,
|
||||
)
|
||||
|
||||
ticket_state1 = Ticket::State.find_by(name: 'new')
|
||||
ticket_state2 = Ticket::State.find_by(name: 'open')
|
||||
overview_role = Role.find_by(name: 'Agent')
|
||||
overview = Overview.create_or_update(
|
||||
name: 'my asset test',
|
||||
link: 'my_asset_test',
|
||||
prio: 1000,
|
||||
role_ids: [overview_role.id],
|
||||
user_ids: [user4.id, user5.id],
|
||||
condition: {
|
||||
'ticket.state_id' => {
|
||||
operator: 'is',
|
||||
value: [ ticket_state1.id, ticket_state2.id ],
|
||||
},
|
||||
'ticket.owner_id' => {
|
||||
operator: 'is',
|
||||
pre_condition: 'specific',
|
||||
value: user1.id,
|
||||
value_completion: 'John Smith <john.smith@example.com>'
|
||||
},
|
||||
},
|
||||
order: {
|
||||
by: 'created_at',
|
||||
direction: 'ASC',
|
||||
},
|
||||
view: {
|
||||
d: %w(title customer group created_at),
|
||||
s: %w(title customer group created_at),
|
||||
m: %w(number title customer group created_at),
|
||||
view_mode_default: 's',
|
||||
},
|
||||
)
|
||||
assets = overview.assets({})
|
||||
assert(assets[:User][user1.id], 'check assets')
|
||||
assert_not(assets[:User][user2.id], 'check assets')
|
||||
assert_not(assets[:User][user3.id], 'check assets')
|
||||
assert(assets[:User][user4.id], 'check assets')
|
||||
assert(assets[:User][user5.id], 'check assets')
|
||||
assert(assets[:TicketState][ticket_state1.id], 'check assets')
|
||||
assert(assets[:TicketState][ticket_state2.id], 'check assets')
|
||||
|
||||
overview = Overview.create_or_update(
|
||||
name: 'my asset test',
|
||||
link: 'my_asset_test',
|
||||
prio: 1000,
|
||||
role_ids: [overview_role.id],
|
||||
user_ids: [user4.id],
|
||||
condition: {
|
||||
'ticket.state_id' => {
|
||||
operator: 'is',
|
||||
value: ticket_state1.id,
|
||||
},
|
||||
'ticket.owner_id' => {
|
||||
operator: 'is',
|
||||
pre_condition: 'specific',
|
||||
value: [user1.id, user2.id],
|
||||
},
|
||||
},
|
||||
order: {
|
||||
by: 'created_at',
|
||||
direction: 'ASC',
|
||||
},
|
||||
view: {
|
||||
d: %w(title customer group created_at),
|
||||
s: %w(title customer group created_at),
|
||||
m: %w(number title customer group created_at),
|
||||
view_mode_default: 's',
|
||||
},
|
||||
)
|
||||
assets = overview.assets({})
|
||||
assert(assets[:User][user1.id], 'check assets')
|
||||
assert(assets[:User][user2.id], 'check assets')
|
||||
assert_not(assets[:User][user3.id], 'check assets')
|
||||
assert(assets[:User][user4.id], 'check assets')
|
||||
assert_not(assets[:User][user5.id], 'check assets')
|
||||
assert(assets[:TicketState][ticket_state1.id], 'check assets')
|
||||
assert_not(assets[:TicketState][ticket_state2.id], 'check assets')
|
||||
overview.destroy!
|
||||
end
|
||||
|
||||
test 'sla' do
|
||||
|
||||
UserInfo.current_user_id = 1
|
||||
roles = Role.where(name: %w(Customer))
|
||||
|
||||
user1 = User.create_or_update(
|
||||
login: 'assets_sla1@example.org',
|
||||
firstname: 'assets_sla1',
|
||||
lastname: 'assets_sla1',
|
||||
email: 'assets_sla1@example.org',
|
||||
password: 'some_pass',
|
||||
active: true,
|
||||
roles: roles,
|
||||
)
|
||||
user2 = User.create_or_update(
|
||||
login: 'assets_sla2@example.org',
|
||||
firstname: 'assets_sla2',
|
||||
lastname: 'assets_sla2',
|
||||
email: 'assets_sla2@example.org',
|
||||
password: 'some_pass',
|
||||
active: true,
|
||||
roles: roles,
|
||||
)
|
||||
|
||||
calendar1 = Calendar.create_or_update(
|
||||
name: 'US 1',
|
||||
timezone: 'America/Los_Angeles',
|
||||
business_hours: {
|
||||
mon: { '09:00' => '17:00' },
|
||||
tue: { '09:00' => '17:00' },
|
||||
wed: { '09:00' => '17:00' },
|
||||
thu: { '09:00' => '17:00' },
|
||||
fri: { '09:00' => '17:00' }
|
||||
},
|
||||
default: true,
|
||||
ical_url: nil,
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
)
|
||||
ticket_state1 = Ticket::State.find_by(name: 'new')
|
||||
ticket_state2 = Ticket::State.find_by(name: 'open')
|
||||
sla = Sla.create_or_update(
|
||||
name: 'my asset test',
|
||||
calendar_id: calendar1.id,
|
||||
condition: {
|
||||
'ticket.state_id' => {
|
||||
operator: 'is',
|
||||
value: [ ticket_state1.id, ticket_state2.id ],
|
||||
},
|
||||
'ticket.owner_id' => {
|
||||
operator: 'is',
|
||||
pre_condition: 'specific',
|
||||
value: user1.id,
|
||||
value_completion: 'John Smith <john.smith@example.com>'
|
||||
},
|
||||
},
|
||||
)
|
||||
assets = sla.assets({})
|
||||
assert(assets[:User][user1.id], 'check assets')
|
||||
assert_not(assets[:User][user2.id], 'check assets')
|
||||
assert(assets[:TicketState][ticket_state1.id], 'check assets')
|
||||
assert(assets[:TicketState][ticket_state2.id], 'check assets')
|
||||
assert(assets[:Calendar][calendar1.id], 'check assets')
|
||||
|
||||
end
|
||||
|
||||
test 'job' do
|
||||
|
||||
UserInfo.current_user_id = 1
|
||||
roles = Role.where(name: %w(Customer))
|
||||
|
||||
user1 = User.create_or_update(
|
||||
login: 'assets_job1@example.org',
|
||||
firstname: 'assets_job1',
|
||||
lastname: 'assets_job1',
|
||||
email: 'assets_job1@example.org',
|
||||
password: 'some_pass',
|
||||
active: true,
|
||||
roles: roles,
|
||||
)
|
||||
user2 = User.create_or_update(
|
||||
login: 'assets_job2@example.org',
|
||||
firstname: 'assets_job2',
|
||||
lastname: 'assets_job2',
|
||||
email: 'assets_job2@example.org',
|
||||
password: 'some_pass',
|
||||
active: true,
|
||||
roles: roles,
|
||||
)
|
||||
user3 = User.create_or_update(
|
||||
login: 'assets_job3@example.org',
|
||||
firstname: 'assets_job3',
|
||||
lastname: 'assets_job3',
|
||||
email: 'assets_job3@example.org',
|
||||
password: 'some_pass',
|
||||
active: true,
|
||||
roles: roles,
|
||||
)
|
||||
|
||||
ticket_state1 = Ticket::State.find_by(name: 'new')
|
||||
ticket_state2 = Ticket::State.find_by(name: 'open')
|
||||
ticket_priority2 = Ticket::Priority.find_by(name: '2 normal')
|
||||
job = Job.create_or_update(
|
||||
name: 'my job',
|
||||
timeplan: {
|
||||
mon: true,
|
||||
},
|
||||
condition: {
|
||||
'ticket.state_id' => {
|
||||
operator: 'is',
|
||||
value: [ ticket_state1.id, ticket_state2.id ],
|
||||
},
|
||||
'ticket.owner_id' => {
|
||||
operator: 'is',
|
||||
pre_condition: 'specific',
|
||||
value: user1.id,
|
||||
value_completion: 'John Smith <john.smith@example.com>'
|
||||
},
|
||||
},
|
||||
perform: {
|
||||
'ticket.priority_id' => {
|
||||
value: ticket_priority2.id,
|
||||
},
|
||||
'ticket.owner_id' => {
|
||||
pre_condition: 'specific',
|
||||
value: user2.id,
|
||||
value_completion: 'metest123@znuny.com <metest123@znuny.com>'
|
||||
},
|
||||
},
|
||||
disable_notification: true,
|
||||
)
|
||||
assets = job.assets({})
|
||||
assert(assets[:User][user1.id], 'check assets')
|
||||
assert(assets[:User][user2.id], 'check assets')
|
||||
assert_not(assets[:User][user3.id], 'check assets')
|
||||
assert(assets[:TicketState][ticket_state1.id], 'check assets')
|
||||
assert(assets[:TicketState][ticket_state2.id], 'check assets')
|
||||
assert(assets[:TicketPriority][ticket_priority2.id], 'check assets')
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
@@ -0,0 +1,79 @@
|
||||
|
||||
require 'test_helper'
|
||||
|
||||
class EmailProcessCustomerSelectionBasedOnSenderRecipient < ActiveSupport::TestCase
|
||||
|
||||
setup do
|
||||
groups = Group.all
|
||||
roles = Role.where(name: 'Agent')
|
||||
@agent1 = User.create_or_update(
|
||||
login: 'user-customer-selection-agent1@example.com',
|
||||
firstname: 'UserOutOfOffice',
|
||||
lastname: 'Agent1',
|
||||
email: 'user-customer-selection-agent1@example.com',
|
||||
password: 'agentpw',
|
||||
active: true,
|
||||
roles: roles,
|
||||
groups: groups,
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
)
|
||||
roles = Role.where(name: 'Customer')
|
||||
@customer1 = User.create_or_update(
|
||||
login: 'user-customer-selection-customer1@example.com',
|
||||
firstname: 'UserOutOfOffice',
|
||||
lastname: 'customer1',
|
||||
email: 'user-customer-selection-customer1@example.com',
|
||||
password: 'customerpw',
|
||||
active: true,
|
||||
roles: roles,
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
)
|
||||
end
|
||||
|
||||
test 'customer need to be customer' do
|
||||
|
||||
email_raw_string = "From: #{@agent1.email}
|
||||
To: #{@customer1.email}
|
||||
Subject: test
|
||||
|
||||
Some Text"
|
||||
|
||||
ticket_p, article_p, user_p, mail = Channel::EmailParser.new.process({}, email_raw_string)
|
||||
ticket = Ticket.find(ticket_p.id)
|
||||
article = Ticket::Article.find(article_p.id)
|
||||
assert_equal('test', ticket.title)
|
||||
assert_equal('new', ticket.state.name)
|
||||
assert_equal('Agent', ticket.create_article_sender.name)
|
||||
assert_equal('Agent', article.sender.name)
|
||||
assert_equal(@customer1.email, ticket.customer.email)
|
||||
assert_equal(@customer1.firstname, ticket.customer.firstname)
|
||||
assert_equal(@customer1.lastname, ticket.customer.lastname)
|
||||
|
||||
end
|
||||
|
||||
test 'agent need to be customer' do
|
||||
|
||||
Setting.set('postmaster_sender_is_agent_search_for_customer', false)
|
||||
|
||||
email_raw_string = "From: #{@agent1.email}
|
||||
To: #{@customer1.email}
|
||||
Subject: test
|
||||
|
||||
Some Text"
|
||||
|
||||
ticket_p, article_p, user_p, mail = Channel::EmailParser.new.process({}, email_raw_string)
|
||||
ticket = Ticket.find(ticket_p.id)
|
||||
article = Ticket::Article.find(article_p.id)
|
||||
assert_equal('test', ticket.title)
|
||||
assert_equal('new', ticket.state.name)
|
||||
assert_equal('Agent', ticket.create_article_sender.name)
|
||||
assert_equal('Agent', article.sender.name)
|
||||
assert_equal(@agent1.email, ticket.customer.email)
|
||||
assert_equal(@agent1.firstname, ticket.customer.firstname)
|
||||
assert_equal(@agent1.lastname, ticket.customer.lastname)
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
@@ -5,7 +5,7 @@ class EmailProcessIdentifySenderMax < ActiveSupport::TestCase
|
||||
|
||||
test 'text max created recipients per email' do
|
||||
current_users = User.count
|
||||
email_raw_string = "From: customer@example.com
|
||||
email_raw_string = "From: #{generate_recipient(1)}
|
||||
To: #{generate_recipient(22)}
|
||||
Cc: #{generate_recipient(22)}
|
||||
Subject: test max sender identify
|
||||
@@ -15,8 +15,7 @@ Some Text"
|
||||
ticket_p, article_p, user_p, mail = Channel::EmailParser.new.process({}, email_raw_string)
|
||||
ticket = Ticket.find(ticket_p.id)
|
||||
assert_equal('test max sender identify', ticket.title)
|
||||
|
||||
assert_equal(current_users + 40, User.count)
|
||||
assert_equal(current_users + 41, User.count)
|
||||
end
|
||||
|
||||
def generate_recipient(count)
|
||||
|
||||
@@ -69,6 +69,45 @@ Some Textäöü",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
data: "From: me@exampl'e.com
|
||||
To: customer@exampl'e.com
|
||||
Subject: äöü some subject
|
||||
|
||||
Some Textäöü",
|
||||
channel: {
|
||||
trusted: false,
|
||||
},
|
||||
success: true,
|
||||
result: {
|
||||
0 => {
|
||||
priority: '2 normal',
|
||||
title: 'äöü some subject',
|
||||
},
|
||||
1 => {
|
||||
body: 'Some Textäöü',
|
||||
sender: 'Customer',
|
||||
type: 'email',
|
||||
internal: false,
|
||||
},
|
||||
},
|
||||
verify: {
|
||||
users: [
|
||||
{
|
||||
firstname: '',
|
||||
lastname: '',
|
||||
fullname: 'me@exampl\'e.com',
|
||||
email: 'me@exampl\'e.com',
|
||||
},
|
||||
{
|
||||
firstname: '',
|
||||
lastname: '',
|
||||
fullname: 'customer@exampl\'e.com',
|
||||
email: 'customer@exampl\'e.com',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
data: "From: me@example.com
|
||||
To: customer@example.com
|
||||
|
||||
80
test/unit/job_assets_test.rb
Normal file
80
test/unit/job_assets_test.rb
Normal file
@@ -0,0 +1,80 @@
|
||||
|
||||
require 'test_helper'
|
||||
|
||||
class JobAssetsTest < ActiveSupport::TestCase
|
||||
test 'assets' do
|
||||
|
||||
UserInfo.current_user_id = 1
|
||||
roles = Role.where(name: %w(Customer))
|
||||
|
||||
user1 = User.create_or_update(
|
||||
login: 'assets_job1@example.org',
|
||||
firstname: 'assets_job1',
|
||||
lastname: 'assets_job1',
|
||||
email: 'assets_job1@example.org',
|
||||
password: 'some_pass',
|
||||
active: true,
|
||||
roles: roles,
|
||||
)
|
||||
user2 = User.create_or_update(
|
||||
login: 'assets_job2@example.org',
|
||||
firstname: 'assets_job2',
|
||||
lastname: 'assets_job2',
|
||||
email: 'assets_job2@example.org',
|
||||
password: 'some_pass',
|
||||
active: true,
|
||||
roles: roles,
|
||||
)
|
||||
user3 = User.create_or_update(
|
||||
login: 'assets_job3@example.org',
|
||||
firstname: 'assets_job3',
|
||||
lastname: 'assets_job3',
|
||||
email: 'assets_job3@example.org',
|
||||
password: 'some_pass',
|
||||
active: true,
|
||||
roles: roles,
|
||||
)
|
||||
|
||||
ticket_state1 = Ticket::State.find_by(name: 'new')
|
||||
ticket_state2 = Ticket::State.find_by(name: 'open')
|
||||
ticket_priority2 = Ticket::Priority.find_by(name: '2 normal')
|
||||
job = Job.create_or_update(
|
||||
name: 'my job',
|
||||
timeplan: {
|
||||
mon: true,
|
||||
},
|
||||
condition: {
|
||||
'ticket.state_id' => {
|
||||
operator: 'is',
|
||||
value: [ ticket_state1.id, ticket_state2.id ],
|
||||
},
|
||||
'ticket.owner_id' => {
|
||||
operator: 'is',
|
||||
pre_condition: 'specific',
|
||||
value: user1.id,
|
||||
value_completion: 'John Smith <john.smith@example.com>'
|
||||
},
|
||||
},
|
||||
perform: {
|
||||
'ticket.priority_id' => {
|
||||
value: ticket_priority2.id,
|
||||
},
|
||||
'ticket.owner_id' => {
|
||||
pre_condition: 'specific',
|
||||
value: user2.id,
|
||||
value_completion: 'metest123@znuny.com <metest123@znuny.com>'
|
||||
},
|
||||
},
|
||||
disable_notification: true,
|
||||
)
|
||||
assets = job.assets({})
|
||||
assert(assets[:User][user1.id])
|
||||
assert(assets[:User][user2.id])
|
||||
assert_not(assets[:User][user3.id])
|
||||
assert(assets[:TicketState][ticket_state1.id])
|
||||
assert(assets[:TicketState][ticket_state2.id])
|
||||
assert(assets[:TicketPriority][ticket_priority2.id])
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
157
test/unit/organization_assets_test.rb
Normal file
157
test/unit/organization_assets_test.rb
Normal file
@@ -0,0 +1,157 @@
|
||||
|
||||
require 'test_helper'
|
||||
|
||||
class OrganizationAssetsTest < ActiveSupport::TestCase
|
||||
test 'assets' do
|
||||
|
||||
roles = Role.where( name: %w(Agent Admin) )
|
||||
admin1 = User.create_or_update(
|
||||
login: 'admin1@example.org',
|
||||
firstname: 'admin1',
|
||||
lastname: 'admin1',
|
||||
email: 'admin1@example.org',
|
||||
password: 'some_pass',
|
||||
active: true,
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
roles: roles,
|
||||
)
|
||||
|
||||
roles = Role.where( name: %w(Customer) )
|
||||
org = Organization.create_or_update(
|
||||
name: 'some customer org',
|
||||
updated_by_id: admin1.id,
|
||||
created_by_id: 1,
|
||||
)
|
||||
|
||||
user1 = User.create_or_update(
|
||||
login: 'assets1@example.org',
|
||||
firstname: 'assets1',
|
||||
lastname: 'assets1',
|
||||
email: 'assets1@example.org',
|
||||
password: 'some_pass',
|
||||
active: true,
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
organization_id: org.id,
|
||||
roles: roles,
|
||||
)
|
||||
|
||||
user2 = User.create_or_update(
|
||||
login: 'assets2@example.org',
|
||||
firstname: 'assets2',
|
||||
lastname: 'assets2',
|
||||
email: 'assets2@example.org',
|
||||
password: 'some_pass',
|
||||
active: true,
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
organization_id: org.id,
|
||||
roles: roles,
|
||||
)
|
||||
|
||||
user3 = User.create_or_update(
|
||||
login: 'assets3@example.org',
|
||||
firstname: 'assets3',
|
||||
lastname: 'assets3',
|
||||
email: 'assets3@example.org',
|
||||
password: 'some_pass',
|
||||
active: true,
|
||||
updated_by_id: user1.id,
|
||||
created_by_id: user2.id,
|
||||
roles: roles,
|
||||
)
|
||||
|
||||
org = Organization.find(org.id)
|
||||
assets = org.assets({})
|
||||
attributes = org.attributes_with_association_ids
|
||||
attributes.delete('user_ids')
|
||||
assert( diff(attributes, assets[:Organization][org.id]), 'check assets' )
|
||||
|
||||
admin1 = User.find(admin1.id)
|
||||
attributes = admin1.attributes_with_association_ids
|
||||
attributes['accounts'] = {}
|
||||
attributes.delete('password')
|
||||
attributes.delete('token_ids')
|
||||
attributes.delete('authorization_ids')
|
||||
assert( diff(attributes, assets[:User][admin1.id]), 'check assets' )
|
||||
|
||||
user1 = User.find(user1.id)
|
||||
attributes = user1.attributes_with_association_ids
|
||||
attributes['accounts'] = {}
|
||||
attributes.delete('password')
|
||||
attributes.delete('token_ids')
|
||||
attributes.delete('authorization_ids')
|
||||
assert( diff(attributes, assets[:User][user1.id]), 'check assets' )
|
||||
|
||||
user2 = User.find(user2.id)
|
||||
attributes = user2.attributes_with_association_ids
|
||||
attributes['accounts'] = {}
|
||||
attributes.delete('password')
|
||||
attributes.delete('token_ids')
|
||||
attributes.delete('authorization_ids')
|
||||
assert( diff(attributes, assets[:User][user2.id]), 'check assets' )
|
||||
|
||||
user3 = User.find(user3.id)
|
||||
attributes = user3.attributes_with_association_ids
|
||||
attributes['accounts'] = {}
|
||||
attributes.delete('password')
|
||||
attributes.delete('token_ids')
|
||||
attributes.delete('authorization_ids')
|
||||
assert_nil( assets[:User][user3.id], 'check assets' )
|
||||
|
||||
# touch user 2, check if org has changed
|
||||
travel 2.seconds
|
||||
user_new_2 = User.find(user2.id)
|
||||
user_new_2.lastname = 'assets2'
|
||||
user_new_2.save!
|
||||
|
||||
org_new = Organization.find(org.id)
|
||||
attributes = org_new.attributes_with_association_ids
|
||||
attributes.delete('user_ids')
|
||||
assert( !diff(attributes, assets[:Organization][org_new.id]), 'check assets' )
|
||||
|
||||
attributes = user_new_2.attributes_with_association_ids
|
||||
attributes['accounts'] = {}
|
||||
attributes.delete('password')
|
||||
attributes.delete('token_ids')
|
||||
attributes.delete('authorization_ids')
|
||||
assert( diff(attributes, assets[:User][user_new_2.id]), 'check assets' )
|
||||
|
||||
# check new assets lookup
|
||||
assets = org_new.assets({})
|
||||
attributes = org_new.attributes_with_association_ids
|
||||
attributes.delete('user_ids')
|
||||
assert( diff(attributes, assets[:Organization][org_new.id]), 'check assets' )
|
||||
|
||||
attributes = user_new_2.attributes_with_association_ids
|
||||
attributes['accounts'] = {}
|
||||
attributes.delete('password')
|
||||
attributes.delete('token_ids')
|
||||
attributes.delete('authorization_ids')
|
||||
assert( diff(attributes, assets[:User][user_new_2.id]), 'check assets' )
|
||||
travel_back
|
||||
|
||||
user3.destroy!
|
||||
user2.destroy!
|
||||
user1.destroy!
|
||||
org.destroy!
|
||||
assert_not(Organization.find_by(id: org_new.id))
|
||||
end
|
||||
|
||||
def diff(o1, o2)
|
||||
return true if o1 == o2
|
||||
%w(updated_at created_at).each do |item|
|
||||
if o1[item]
|
||||
o1[item] = o1[item].to_s
|
||||
end
|
||||
if o2[item]
|
||||
o2[item] = o2[item].to_s
|
||||
end
|
||||
end
|
||||
return true if (o1.to_a - o2.to_a).blank?
|
||||
#puts "ERROR: difference \n1: #{o1.inspect}\n2: #{o2.inspect}\ndiff: #{(o1.to_a - o2.to_a).inspect}"
|
||||
false
|
||||
end
|
||||
|
||||
end
|
||||
136
test/unit/overview_assets_test.rb
Normal file
136
test/unit/overview_assets_test.rb
Normal file
@@ -0,0 +1,136 @@
|
||||
|
||||
require 'test_helper'
|
||||
|
||||
class OverviewAssetsTest < ActiveSupport::TestCase
|
||||
test 'assets' do
|
||||
|
||||
UserInfo.current_user_id = 1
|
||||
roles = Role.where(name: %w(Customer))
|
||||
|
||||
user1 = User.create_or_update(
|
||||
login: 'assets_overview1@example.org',
|
||||
firstname: 'assets_overview1',
|
||||
lastname: 'assets_overview1',
|
||||
email: 'assets_overview1@example.org',
|
||||
password: 'some_pass',
|
||||
active: true,
|
||||
roles: roles,
|
||||
)
|
||||
user2 = User.create_or_update(
|
||||
login: 'assets_overview2@example.org',
|
||||
firstname: 'assets_overview2',
|
||||
lastname: 'assets_overview2',
|
||||
email: 'assets_overview2@example.org',
|
||||
password: 'some_pass',
|
||||
active: true,
|
||||
roles: roles,
|
||||
)
|
||||
user3 = User.create_or_update(
|
||||
login: 'assets_overview3@example.org',
|
||||
firstname: 'assets_overview3',
|
||||
lastname: 'assets_overview3',
|
||||
email: 'assets_overview3@example.org',
|
||||
password: 'some_pass',
|
||||
active: true,
|
||||
roles: roles,
|
||||
)
|
||||
user4 = User.create_or_update(
|
||||
login: 'assets_overview4@example.org',
|
||||
firstname: 'assets_overview4',
|
||||
lastname: 'assets_overview4',
|
||||
email: 'assets_overview4@example.org',
|
||||
password: 'some_pass',
|
||||
active: true,
|
||||
roles: roles,
|
||||
)
|
||||
user5 = User.create_or_update(
|
||||
login: 'assets_overview5@example.org',
|
||||
firstname: 'assets_overview5',
|
||||
lastname: 'assets_overview5',
|
||||
email: 'assets_overview5@example.org',
|
||||
password: 'some_pass',
|
||||
active: true,
|
||||
roles: roles,
|
||||
)
|
||||
|
||||
ticket_state1 = Ticket::State.find_by(name: 'new')
|
||||
ticket_state2 = Ticket::State.find_by(name: 'open')
|
||||
overview_role = Role.find_by(name: 'Agent')
|
||||
overview = Overview.create_or_update(
|
||||
name: 'my asset test',
|
||||
link: 'my_asset_test',
|
||||
prio: 1000,
|
||||
role_ids: [overview_role.id],
|
||||
user_ids: [user4.id, user5.id],
|
||||
condition: {
|
||||
'ticket.state_id' => {
|
||||
operator: 'is',
|
||||
value: [ ticket_state1.id, ticket_state2.id ],
|
||||
},
|
||||
'ticket.owner_id' => {
|
||||
operator: 'is',
|
||||
pre_condition: 'specific',
|
||||
value: user1.id,
|
||||
value_completion: 'John Smith <john.smith@example.com>'
|
||||
},
|
||||
},
|
||||
order: {
|
||||
by: 'created_at',
|
||||
direction: 'ASC',
|
||||
},
|
||||
view: {
|
||||
d: %w(title customer group created_at),
|
||||
s: %w(title customer group created_at),
|
||||
m: %w(number title customer group created_at),
|
||||
view_mode_default: 's',
|
||||
},
|
||||
)
|
||||
assets = overview.assets({})
|
||||
assert(assets[:User][user1.id])
|
||||
assert_not(assets[:User][user2.id])
|
||||
assert_not(assets[:User][user3.id])
|
||||
assert(assets[:User][user4.id])
|
||||
assert(assets[:User][user5.id])
|
||||
assert(assets[:TicketState][ticket_state1.id])
|
||||
assert(assets[:TicketState][ticket_state2.id])
|
||||
|
||||
overview = Overview.create_or_update(
|
||||
name: 'my asset test',
|
||||
link: 'my_asset_test',
|
||||
prio: 1000,
|
||||
role_ids: [overview_role.id],
|
||||
user_ids: [user4.id],
|
||||
condition: {
|
||||
'ticket.state_id' => {
|
||||
operator: 'is',
|
||||
value: ticket_state1.id,
|
||||
},
|
||||
'ticket.owner_id' => {
|
||||
operator: 'is',
|
||||
pre_condition: 'specific',
|
||||
value: [user1.id, user2.id],
|
||||
},
|
||||
},
|
||||
order: {
|
||||
by: 'created_at',
|
||||
direction: 'ASC',
|
||||
},
|
||||
view: {
|
||||
d: %w(title customer group created_at),
|
||||
s: %w(title customer group created_at),
|
||||
m: %w(number title customer group created_at),
|
||||
view_mode_default: 's',
|
||||
},
|
||||
)
|
||||
assets = overview.assets({})
|
||||
assert(assets[:User][user1.id])
|
||||
assert(assets[:User][user2.id])
|
||||
assert_not(assets[:User][user3.id])
|
||||
assert(assets[:User][user4.id])
|
||||
assert_not(assets[:User][user5.id])
|
||||
assert(assets[:TicketState][ticket_state1.id])
|
||||
assert_not(assets[:TicketState][ticket_state2.id])
|
||||
overview.destroy!
|
||||
end
|
||||
|
||||
end
|
||||
@@ -28,7 +28,7 @@ class OverviewTest < ActiveSupport::TestCase
|
||||
overview.destroy!
|
||||
|
||||
overview = Overview.create!(
|
||||
name: 'My assigned Tickets',
|
||||
name: 'My assigned Tickets 2',
|
||||
condition: {
|
||||
'ticket.state_id' => {
|
||||
operator: 'is',
|
||||
@@ -46,7 +46,7 @@ class OverviewTest < ActiveSupport::TestCase
|
||||
view_mode_default: 's',
|
||||
},
|
||||
)
|
||||
assert_equal(overview.link, 'my_assigned_tickets')
|
||||
assert_equal(overview.link, 'my_assigned_tickets_2')
|
||||
overview.destroy!
|
||||
|
||||
overview = Overview.create!(
|
||||
@@ -210,6 +210,158 @@ class OverviewTest < ActiveSupport::TestCase
|
||||
assert_equal(overview.link, 'my_overview2')
|
||||
|
||||
overview.destroy!
|
||||
end
|
||||
|
||||
test 'same url' do
|
||||
UserInfo.current_user_id = 1
|
||||
|
||||
overview1 = Overview.create!(
|
||||
name: 'My own assigned Tickets',
|
||||
condition: {
|
||||
'ticket.state_id' => {
|
||||
operator: 'is',
|
||||
value: [1, 2, 3],
|
||||
},
|
||||
},
|
||||
order: {
|
||||
by: 'created_at',
|
||||
direction: 'DESC',
|
||||
},
|
||||
view: {
|
||||
d: %w(title customer state created_at),
|
||||
s: %w(number title customer state created_at),
|
||||
m: %w(number title customer state created_at),
|
||||
view_mode_default: 's',
|
||||
},
|
||||
)
|
||||
assert_equal(overview1.link, 'my_own_assigned_tickets')
|
||||
|
||||
overview2 = Overview.create!(
|
||||
name: 'My own assigned Tickets',
|
||||
condition: {
|
||||
'ticket.state_id' => {
|
||||
operator: 'is',
|
||||
value: [1, 2, 3],
|
||||
},
|
||||
},
|
||||
order: {
|
||||
by: 'created_at',
|
||||
direction: 'DESC',
|
||||
},
|
||||
view: {
|
||||
d: %w(title customer state created_at),
|
||||
s: %w(number title customer state created_at),
|
||||
m: %w(number title customer state created_at),
|
||||
view_mode_default: 's',
|
||||
},
|
||||
)
|
||||
assert_equal(overview2.link, 'my_own_assigned_tickets_1')
|
||||
|
||||
overview3 = Overview.create!(
|
||||
name: 'My own assigned Tickets',
|
||||
condition: {
|
||||
'ticket.state_id' => {
|
||||
operator: 'is',
|
||||
value: [1, 2, 3],
|
||||
},
|
||||
},
|
||||
order: {
|
||||
by: 'created_at',
|
||||
direction: 'DESC',
|
||||
},
|
||||
view: {
|
||||
d: %w(title customer state created_at),
|
||||
s: %w(number title customer state created_at),
|
||||
m: %w(number title customer state created_at),
|
||||
view_mode_default: 's',
|
||||
},
|
||||
)
|
||||
assert_equal(overview3.link, 'my_own_assigned_tickets_2')
|
||||
|
||||
overview1.destroy!
|
||||
overview2.destroy!
|
||||
overview3.destroy!
|
||||
end
|
||||
|
||||
test 'priority rearrangement' do
|
||||
UserInfo.current_user_id = 1
|
||||
|
||||
overview1 = Overview.create!(
|
||||
name: 'Overview1',
|
||||
link: 'my_overview',
|
||||
condition: {
|
||||
'ticket.state_id' => {
|
||||
operator: 'is',
|
||||
value: [1, 2, 3],
|
||||
},
|
||||
},
|
||||
order: {
|
||||
by: 'created_at',
|
||||
direction: 'DESC',
|
||||
},
|
||||
view: {
|
||||
d: %w(title customer state created_at),
|
||||
s: %w(number title customer state created_at),
|
||||
m: %w(number title customer state created_at),
|
||||
view_mode_default: 's',
|
||||
},
|
||||
prio: 1,
|
||||
)
|
||||
|
||||
overview2 = Overview.create!(
|
||||
name: 'Overview2',
|
||||
link: 'my_overview',
|
||||
condition: {
|
||||
'ticket.state_id' => {
|
||||
operator: 'is',
|
||||
value: [1, 2, 3],
|
||||
},
|
||||
},
|
||||
order: {
|
||||
by: 'created_at',
|
||||
direction: 'DESC',
|
||||
},
|
||||
view: {
|
||||
d: %w(title customer state created_at),
|
||||
s: %w(number title customer state created_at),
|
||||
m: %w(number title customer state created_at),
|
||||
view_mode_default: 's',
|
||||
},
|
||||
prio: 2,
|
||||
)
|
||||
|
||||
overview3 = Overview.create!(
|
||||
name: 'Overview3',
|
||||
link: 'my_overview',
|
||||
condition: {
|
||||
'ticket.state_id' => {
|
||||
operator: 'is',
|
||||
value: [1, 2, 3],
|
||||
},
|
||||
},
|
||||
order: {
|
||||
by: 'created_at',
|
||||
direction: 'DESC',
|
||||
},
|
||||
view: {
|
||||
d: %w(title customer state created_at),
|
||||
s: %w(number title customer state created_at),
|
||||
m: %w(number title customer state created_at),
|
||||
view_mode_default: 's',
|
||||
},
|
||||
prio: 3,
|
||||
)
|
||||
|
||||
overview2.prio = 3
|
||||
overview2.save!
|
||||
|
||||
overviews = Overview.all.order(prio: :asc).pluck(:id)
|
||||
assert_equal(overview1.id, overviews[0])
|
||||
assert_equal(overview3.id, overviews[1])
|
||||
assert_equal(overview2.id, overviews[2])
|
||||
|
||||
overview1.destroy!
|
||||
overview2.destroy!
|
||||
overview3.destroy!
|
||||
end
|
||||
end
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
require 'test_helper'
|
||||
|
||||
class SessionEnhancedTest < ActiveSupport::TestCase
|
||||
test 'a check clients and send messages' do
|
||||
test 'check clients and send messages' do
|
||||
|
||||
# create users
|
||||
roles = Role.where(name: ['Agent'])
|
||||
@@ -172,7 +172,8 @@ class SessionEnhancedTest < ActiveSupport::TestCase
|
||||
travel_back
|
||||
end
|
||||
|
||||
test 'b check client and backends' do
|
||||
test 'check client and backends' do
|
||||
|
||||
# create users
|
||||
roles = Role.where(name: ['Agent'])
|
||||
groups = Group.all
|
||||
|
||||
71
test/unit/sla_assets_test.rb
Normal file
71
test/unit/sla_assets_test.rb
Normal file
@@ -0,0 +1,71 @@
|
||||
|
||||
require 'test_helper'
|
||||
|
||||
class SlaAssetsTest < ActiveSupport::TestCase
|
||||
test 'assets' do
|
||||
|
||||
UserInfo.current_user_id = 1
|
||||
roles = Role.where(name: %w(Customer))
|
||||
|
||||
user1 = User.create_or_update(
|
||||
login: 'assets_sla1@example.org',
|
||||
firstname: 'assets_sla1',
|
||||
lastname: 'assets_sla1',
|
||||
email: 'assets_sla1@example.org',
|
||||
password: 'some_pass',
|
||||
active: true,
|
||||
roles: roles,
|
||||
)
|
||||
user2 = User.create_or_update(
|
||||
login: 'assets_sla2@example.org',
|
||||
firstname: 'assets_sla2',
|
||||
lastname: 'assets_sla2',
|
||||
email: 'assets_sla2@example.org',
|
||||
password: 'some_pass',
|
||||
active: true,
|
||||
roles: roles,
|
||||
)
|
||||
|
||||
calendar1 = Calendar.create_or_update(
|
||||
name: 'US 1',
|
||||
timezone: 'America/Los_Angeles',
|
||||
business_hours: {
|
||||
mon: { '09:00' => '17:00' },
|
||||
tue: { '09:00' => '17:00' },
|
||||
wed: { '09:00' => '17:00' },
|
||||
thu: { '09:00' => '17:00' },
|
||||
fri: { '09:00' => '17:00' }
|
||||
},
|
||||
default: true,
|
||||
ical_url: nil,
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
)
|
||||
ticket_state1 = Ticket::State.find_by(name: 'new')
|
||||
ticket_state2 = Ticket::State.find_by(name: 'open')
|
||||
sla = Sla.create_or_update(
|
||||
name: 'my asset test',
|
||||
calendar_id: calendar1.id,
|
||||
condition: {
|
||||
'ticket.state_id' => {
|
||||
operator: 'is',
|
||||
value: [ ticket_state1.id, ticket_state2.id ],
|
||||
},
|
||||
'ticket.owner_id' => {
|
||||
operator: 'is',
|
||||
pre_condition: 'specific',
|
||||
value: user1.id,
|
||||
value_completion: 'John Smith <john.smith@example.com>'
|
||||
},
|
||||
},
|
||||
)
|
||||
assets = sla.assets({})
|
||||
assert(assets[:User][user1.id], 'check assets')
|
||||
assert_not(assets[:User][user2.id], 'check assets')
|
||||
assert(assets[:TicketState][ticket_state1.id], 'check assets')
|
||||
assert(assets[:TicketState][ticket_state2.id], 'check assets')
|
||||
assert(assets[:Calendar][calendar1.id], 'check assets')
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
@@ -29,7 +29,7 @@ class StoreTest < ActiveSupport::TestCase
|
||||
assert(exists)
|
||||
end
|
||||
|
||||
test 'store attachment' do
|
||||
test 'store attachment and move it between backends' do
|
||||
files = [
|
||||
{
|
||||
data: 'hello world',
|
||||
@@ -54,7 +54,7 @@ class StoreTest < ActiveSupport::TestCase
|
||||
]
|
||||
|
||||
files.each do |file|
|
||||
sha = Digest::SHA256.hexdigest( file[:data] )
|
||||
sha = Digest::SHA256.hexdigest(file[:data])
|
||||
|
||||
# add attachments
|
||||
store = Store.add(
|
||||
@@ -75,23 +75,23 @@ class StoreTest < ActiveSupport::TestCase
|
||||
assert attachments
|
||||
|
||||
# sha check
|
||||
sha_new = Digest::SHA256.hexdigest( attachments[0].content )
|
||||
assert_equal( sha, sha_new, "check file #{file[:filename]}")
|
||||
sha_new = Digest::SHA256.hexdigest(attachments[0].content)
|
||||
assert_equal(sha, sha_new, "check file #{file[:filename]}")
|
||||
|
||||
# filename check
|
||||
assert_equal( file[:filename], attachments[0].filename )
|
||||
assert_equal(file[:filename], attachments[0].filename)
|
||||
|
||||
# provider check
|
||||
assert_equal( 'DB', attachments[0].provider )
|
||||
assert_equal('DB', attachments[0].provider)
|
||||
end
|
||||
|
||||
success = Store::File.verify
|
||||
assert success, 'verify ok'
|
||||
|
||||
Store::File.move( 'DB', 'File' )
|
||||
Store::File.move('DB', 'File')
|
||||
|
||||
files.each do |file|
|
||||
sha = Digest::SHA256.hexdigest( file[:data] )
|
||||
sha = Digest::SHA256.hexdigest(file[:data])
|
||||
|
||||
# get list of attachments
|
||||
attachments = Store.list(
|
||||
@@ -101,54 +101,55 @@ class StoreTest < ActiveSupport::TestCase
|
||||
assert attachments
|
||||
|
||||
# sha check
|
||||
sha_new = Digest::SHA256.hexdigest( attachments[0].content )
|
||||
assert_equal( sha, sha_new, "check file #{file[:filename]}")
|
||||
sha_new = Digest::SHA256.hexdigest(attachments[0].content)
|
||||
assert_equal(sha, sha_new, "check file #{file[:filename]}")
|
||||
|
||||
# filename check
|
||||
assert_equal( file[:filename], attachments[0].filename )
|
||||
assert_equal(file[:filename], attachments[0].filename)
|
||||
|
||||
# provider check
|
||||
assert_equal( 'File', attachments[0].provider )
|
||||
assert_equal('File', attachments[0].provider)
|
||||
end
|
||||
|
||||
success = Store::File.verify
|
||||
assert success, 'verify ok'
|
||||
|
||||
Store::File.move( 'File', 'DB' )
|
||||
Store::File.move('File', 'DB')
|
||||
|
||||
files.each do |file|
|
||||
sha = Digest::SHA256.hexdigest( file[:data] )
|
||||
sha = Digest::SHA256.hexdigest(file[:data])
|
||||
|
||||
# get list of attachments
|
||||
attachments = Store.list(
|
||||
object: 'Test',
|
||||
o_id: file[:o_id],
|
||||
)
|
||||
assert attachments
|
||||
assert(attachments)
|
||||
assert_equal(attachments.count, 1)
|
||||
|
||||
# sha check
|
||||
sha_new = Digest::SHA256.hexdigest( attachments[0].content )
|
||||
assert_equal( sha, sha_new, "check file #{file[:filename]}")
|
||||
sha_new = Digest::SHA256.hexdigest(attachments[0].content)
|
||||
assert_equal(sha, sha_new, "check file #{file[:filename]}")
|
||||
|
||||
# filename check
|
||||
assert_equal( file[:filename], attachments[0].filename )
|
||||
assert_equal(file[:filename], attachments[0].filename)
|
||||
|
||||
# provider check
|
||||
assert_equal( 'DB', attachments[0].provider )
|
||||
assert_equal('DB', attachments[0].provider)
|
||||
|
||||
# delete attachments
|
||||
success = Store.remove(
|
||||
object: 'Test',
|
||||
o_id: file[:o_id],
|
||||
)
|
||||
assert success
|
||||
assert(success)
|
||||
|
||||
# check attachments again
|
||||
attachments = Store.list(
|
||||
object: 'Test',
|
||||
o_id: file[:o_id],
|
||||
)
|
||||
assert !attachments[0]
|
||||
assert_not(attachments[0])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
75
test/unit/ticket_article_store_empty.rb
Normal file
75
test/unit/ticket_article_store_empty.rb
Normal file
@@ -0,0 +1,75 @@
|
||||
# encoding: utf-8
|
||||
require 'test_helper'
|
||||
|
||||
class TicketArticleStoreEmpty < ActiveSupport::TestCase
|
||||
|
||||
test 'check if attachments are deleted after ticket is deleted' do
|
||||
|
||||
current_count = Store.count
|
||||
current_file_count = Store::File.count
|
||||
current_backend_count = Store::Provider::DB.count
|
||||
|
||||
email_raw_string = IO.binread('test/fixtures/mail1.box')
|
||||
ticket, article, user, mail = Channel::EmailParser.new.process({}, email_raw_string)
|
||||
|
||||
next_count = Store.count
|
||||
next_file_count = Store::File.count
|
||||
next_backend_count = Store::Provider::DB.count
|
||||
|
||||
assert_equal(current_count, next_count - 2)
|
||||
assert_equal(current_file_count, next_file_count - 2)
|
||||
assert_equal(current_backend_count, next_backend_count - 2)
|
||||
|
||||
ticket.destroy!
|
||||
|
||||
after_count = Store.count
|
||||
after_file_count = Store::File.count
|
||||
after_backend_count = Store::Provider::DB.count
|
||||
|
||||
assert_equal(current_count, after_count)
|
||||
assert_equal(current_file_count, after_file_count)
|
||||
assert_equal(current_backend_count, after_backend_count)
|
||||
|
||||
end
|
||||
|
||||
test 'check if attachments are deleted after ticket same ticket 2 times is deleted' do
|
||||
|
||||
current_count = Store.count
|
||||
current_file_count = Store::File.count
|
||||
current_backend_count = Store::Provider::DB.count
|
||||
|
||||
email_raw_string = IO.binread('test/fixtures/mail1.box')
|
||||
ticket1, article1, user1, mail1 = Channel::EmailParser.new.process({}, email_raw_string)
|
||||
ticket2, article2, user2, mail2 = Channel::EmailParser.new.process({}, email_raw_string)
|
||||
|
||||
next_count = Store.count
|
||||
next_file_count = Store::File.count
|
||||
next_backend_count = Store::Provider::DB.count
|
||||
|
||||
assert_equal(current_count, next_count - 4)
|
||||
assert_equal(current_file_count, next_file_count - 2)
|
||||
assert_equal(current_backend_count, next_backend_count - 2)
|
||||
|
||||
ticket1.destroy!
|
||||
|
||||
next_count = Store.count
|
||||
next_file_count = Store::File.count
|
||||
next_backend_count = Store::Provider::DB.count
|
||||
|
||||
assert_equal(current_count, next_count - 2)
|
||||
assert_equal(current_file_count, next_file_count - 2)
|
||||
assert_equal(current_backend_count, next_backend_count - 2)
|
||||
|
||||
ticket2.destroy!
|
||||
|
||||
after_count = Store.count
|
||||
after_file_count = Store::File.count
|
||||
after_backend_count = Store::Provider::DB.count
|
||||
|
||||
assert_equal(current_count, after_count)
|
||||
assert_equal(current_file_count, after_file_count)
|
||||
assert_equal(current_backend_count, after_backend_count)
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
@@ -6,6 +6,7 @@ class TicketLastOwnerUpdateTest < ActiveSupport::TestCase
|
||||
setup do
|
||||
group = Group.create_or_update(
|
||||
name: 'LastOwnerUpdate',
|
||||
email_address: EmailAddress.first,
|
||||
assignment_timeout: 60,
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
@@ -25,6 +26,95 @@ class TicketLastOwnerUpdateTest < ActiveSupport::TestCase
|
||||
)
|
||||
end
|
||||
|
||||
test 'last_owner_update_at check by state' do
|
||||
|
||||
ticket = Ticket.create!(
|
||||
title: 'assignment_timeout test by state 1',
|
||||
group: Group.lookup(name: 'LastOwnerUpdate'),
|
||||
owner: @agent1,
|
||||
customer_id: 2,
|
||||
state: Ticket::State.lookup(name: 'new'),
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
)
|
||||
assert_equal(ticket.last_owner_update_at.to_s, ticket.updated_at.to_s)
|
||||
|
||||
ticket.state = Ticket::State.lookup(name: 'closed')
|
||||
ticket.save!
|
||||
assert_nil(ticket.last_owner_update_at)
|
||||
|
||||
ticket = Ticket.create!(
|
||||
title: 'assignment_timeout test by state 1',
|
||||
group: Group.lookup(name: 'LastOwnerUpdate'),
|
||||
owner: @agent1,
|
||||
customer_id: 2,
|
||||
state: Ticket::State.lookup(name: 'pending reminder'),
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
)
|
||||
assert_nil(ticket.last_owner_update_at)
|
||||
|
||||
ticket.state = Ticket::State.lookup(name: 'open')
|
||||
ticket.save!
|
||||
assert_equal(ticket.last_owner_update_at.to_s, ticket.updated_at.to_s)
|
||||
|
||||
end
|
||||
|
||||
test 'last_owner_update_at check with agent reply' do
|
||||
|
||||
ticket = Ticket.create!(
|
||||
title: 'assignment_timeout test by state 1',
|
||||
group: Group.lookup(name: 'LastOwnerUpdate'),
|
||||
owner: @agent1,
|
||||
customer_id: 2,
|
||||
state: Ticket::State.lookup(name: 'open'),
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
)
|
||||
assert_equal(ticket.last_owner_update_at.to_s, ticket.updated_at.to_s)
|
||||
|
||||
travel 1.hour
|
||||
|
||||
article1 = Ticket::Article.create(
|
||||
ticket_id: ticket.id,
|
||||
from: 'some_sender@example.com',
|
||||
to: 'some_recipient@example.com',
|
||||
subject: 'some subject',
|
||||
message_id: 'some@id',
|
||||
body: 'some message reply by customer email',
|
||||
internal: false,
|
||||
sender: Ticket::Article::Sender.find_by(name: 'Customer'),
|
||||
type: Ticket::Article::Type.find_by(name: 'email'),
|
||||
updated_by_id: 2,
|
||||
created_by_id: 2,
|
||||
)
|
||||
|
||||
ticket_last_owner_update_at = ticket.last_owner_update_at
|
||||
ticket.reload
|
||||
assert_equal(ticket_last_owner_update_at.to_s, ticket.last_owner_update_at.to_s)
|
||||
|
||||
travel 1.hour
|
||||
|
||||
article2 = Ticket::Article.create(
|
||||
ticket_id: ticket.id,
|
||||
from: 'some_sender@example.com',
|
||||
to: 'some_recipient@example.com',
|
||||
subject: 'some subject',
|
||||
message_id: 'some@id',
|
||||
body: 'some message reply by agent email',
|
||||
internal: false,
|
||||
sender: Ticket::Article::Sender.find_by(name: 'Agent'),
|
||||
type: Ticket::Article::Type.find_by(name: 'email'),
|
||||
updated_by_id: @agent1.id,
|
||||
created_by_id: @agent1.id,
|
||||
)
|
||||
|
||||
ticket_last_owner_update_at = Time.zone.now
|
||||
ticket.reload
|
||||
assert_equal(ticket_last_owner_update_at.to_s, ticket.last_owner_update_at.to_s)
|
||||
|
||||
end
|
||||
|
||||
test 'last_owner_update_at check' do
|
||||
|
||||
ticket = Ticket.create!(
|
||||
@@ -77,7 +167,7 @@ class TicketLastOwnerUpdateTest < ActiveSupport::TestCase
|
||||
group: Group.lookup(name: 'LastOwnerUpdate'),
|
||||
owner: @agent1,
|
||||
customer_id: 2,
|
||||
state: Ticket::State.lookup(name: 'closed'),
|
||||
state: Ticket::State.lookup(name: 'open'),
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
)
|
||||
@@ -119,7 +209,7 @@ class TicketLastOwnerUpdateTest < ActiveSupport::TestCase
|
||||
|
||||
ticket = Ticket.create!(
|
||||
title: 'assignment_timeout test 2',
|
||||
group: Group.lookup(name: 'Users'),
|
||||
group: Group.lookup(name: 'LastOwnerUpdate'),
|
||||
owner: @agent1,
|
||||
customer_id: 2,
|
||||
state: Ticket::State.lookup(name: 'new'),
|
||||
@@ -141,7 +231,7 @@ class TicketLastOwnerUpdateTest < ActiveSupport::TestCase
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
)
|
||||
assert_equal(ticket.last_owner_update_at.to_s, ticket.updated_at.to_s)
|
||||
assert_nil(ticket.last_owner_update_at)
|
||||
|
||||
ticket.owner_id = 1
|
||||
ticket.save!
|
||||
@@ -177,7 +267,7 @@ class TicketLastOwnerUpdateTest < ActiveSupport::TestCase
|
||||
group: Group.lookup(name: 'LastOwnerUpdate'),
|
||||
owner: @agent1,
|
||||
customer_id: 2,
|
||||
state: Ticket::State.lookup(name: 'closed'),
|
||||
state: Ticket::State.lookup(name: 'open'),
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
)
|
||||
@@ -195,7 +285,7 @@ class TicketLastOwnerUpdateTest < ActiveSupport::TestCase
|
||||
|
||||
ticket5 = Ticket.create!(
|
||||
title: 'assignment_timeout test 5',
|
||||
group: Group.lookup(name: 'Users'),
|
||||
group: Group.lookup(name: 'LastOwnerUpdate'),
|
||||
owner: @agent1,
|
||||
customer_id: 2,
|
||||
state: Ticket::State.lookup(name: 'new'),
|
||||
@@ -229,7 +319,7 @@ class TicketLastOwnerUpdateTest < ActiveSupport::TestCase
|
||||
|
||||
travel 15.minutes
|
||||
Ticket.process_auto_unassign
|
||||
ticket2_updated_at = Time.current
|
||||
ticket_updated_at = Time.current
|
||||
|
||||
ticket1after = Ticket.find(ticket1.id)
|
||||
assert_nil(ticket1.last_owner_update_at)
|
||||
@@ -238,20 +328,20 @@ class TicketLastOwnerUpdateTest < ActiveSupport::TestCase
|
||||
ticket2after = Ticket.find(ticket2.id)
|
||||
assert_nil(ticket2after.last_owner_update_at)
|
||||
assert_equal(ticket2after.owner_id, 1)
|
||||
assert_equal(ticket2_updated_at.to_s, ticket2after.updated_at.to_s)
|
||||
assert_equal(ticket_updated_at.to_s, ticket2after.updated_at.to_s)
|
||||
|
||||
ticket3after = Ticket.find(ticket3.id)
|
||||
assert_equal(ticket3after.owner_id, @agent1.id)
|
||||
assert_equal(ticket3.last_owner_update_at.to_s, ticket3after.last_owner_update_at.to_s)
|
||||
assert_equal(ticket3.updated_at.to_s, ticket3after.updated_at.to_s)
|
||||
assert_nil(ticket3after.last_owner_update_at)
|
||||
assert_equal(ticket3after.owner_id, 1)
|
||||
assert_equal(ticket_updated_at.to_s, ticket3after.updated_at.to_s)
|
||||
|
||||
ticket4after = Ticket.find(ticket4.id)
|
||||
assert_nil(ticket4.last_owner_update_at)
|
||||
assert_equal(ticket4.updated_at.to_s, ticket4after.updated_at.to_s)
|
||||
|
||||
ticket5after = Ticket.find(ticket5.id)
|
||||
assert_equal(ticket5after.owner_id, @agent1.id)
|
||||
assert_equal(ticket5.updated_at.to_s, ticket5after.updated_at.to_s)
|
||||
assert_equal(ticket5after.owner_id, 1)
|
||||
assert_equal(ticket_updated_at.to_s, ticket5after.updated_at.to_s)
|
||||
|
||||
end
|
||||
|
||||
|
||||
77
test/unit/trigger_assets_test.rb
Normal file
77
test/unit/trigger_assets_test.rb
Normal file
@@ -0,0 +1,77 @@
|
||||
|
||||
require 'test_helper'
|
||||
|
||||
class TriggerAssetsTest < ActiveSupport::TestCase
|
||||
test 'assets' do
|
||||
|
||||
UserInfo.current_user_id = 1
|
||||
roles = Role.where(name: %w(Customer))
|
||||
|
||||
user1 = User.create_or_update(
|
||||
login: 'assets_trigger1@example.org',
|
||||
firstname: 'assets_trigger1',
|
||||
lastname: 'assets_trigger1',
|
||||
email: 'assets_trigger1@example.org',
|
||||
password: 'some_pass',
|
||||
active: true,
|
||||
roles: roles,
|
||||
)
|
||||
user2 = User.create_or_update(
|
||||
login: 'assets_trigger2@example.org',
|
||||
firstname: 'assets_trigger2',
|
||||
lastname: 'assets_trigger2',
|
||||
email: 'assets_trigger2@example.org',
|
||||
password: 'some_pass',
|
||||
active: true,
|
||||
roles: roles,
|
||||
)
|
||||
user3 = User.create_or_update(
|
||||
login: 'assets_trigger3@example.org',
|
||||
firstname: 'assets_trigger3',
|
||||
lastname: 'assets_trigger3',
|
||||
email: 'assets_trigger3@example.org',
|
||||
password: 'some_pass',
|
||||
active: true,
|
||||
roles: roles,
|
||||
)
|
||||
group1 = Group.create_or_update(
|
||||
name: 'group1_trigger',
|
||||
active: true,
|
||||
)
|
||||
|
||||
ticket_state1 = Ticket::State.find_by(name: 'new')
|
||||
ticket_state2 = Ticket::State.find_by(name: 'open')
|
||||
ticket_priority2 = Ticket::Priority.find_by(name: '2 normal')
|
||||
trigger = Trigger.create_or_update(
|
||||
name: 'my trigger',
|
||||
condition: {
|
||||
'ticket.state_id' => {
|
||||
operator: 'is',
|
||||
value: [ ticket_state1.id ],
|
||||
},
|
||||
'ticket.owner_id' => {
|
||||
operator: 'is',
|
||||
pre_condition: 'specific',
|
||||
value: user1.id,
|
||||
value_completion: 'John Smith <john.smith@example.com>'
|
||||
},
|
||||
},
|
||||
perform: {
|
||||
'ticket.group_id' => {
|
||||
value: group1.id.to_s,
|
||||
},
|
||||
},
|
||||
disable_notification: true,
|
||||
)
|
||||
assets = trigger.assets({})
|
||||
assert(assets[:User][user1.id])
|
||||
assert_not(assets[:User][user2.id])
|
||||
assert_not(assets[:User][user3.id])
|
||||
assert(assets[:TicketState][ticket_state1.id])
|
||||
assert_not(assets[:TicketState][ticket_state2.id])
|
||||
assert_not(assets[:TicketPriority])
|
||||
assert(assets[:Group][group1.id])
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
157
test/unit/user_assets_test.rb
Normal file
157
test/unit/user_assets_test.rb
Normal file
@@ -0,0 +1,157 @@
|
||||
|
||||
require 'test_helper'
|
||||
|
||||
class UserAssetsTest < ActiveSupport::TestCase
|
||||
test 'assets' do
|
||||
|
||||
roles = Role.where(name: %w(Agent Admin))
|
||||
groups = Group.all
|
||||
org1 = Organization.create_or_update(
|
||||
name: 'some user org',
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
)
|
||||
|
||||
user1 = User.create_or_update(
|
||||
login: 'assets1@example.org',
|
||||
firstname: 'assets1',
|
||||
lastname: 'assets1',
|
||||
email: 'assets1@example.org',
|
||||
password: 'some_pass',
|
||||
active: true,
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
organization_id: org1.id,
|
||||
roles: roles,
|
||||
groups: groups,
|
||||
)
|
||||
|
||||
user2 = User.create_or_update(
|
||||
login: 'assets2@example.org',
|
||||
firstname: 'assets2',
|
||||
lastname: 'assets2',
|
||||
email: 'assets2@example.org',
|
||||
password: 'some_pass',
|
||||
active: true,
|
||||
updated_by_id: 1,
|
||||
created_by_id: 1,
|
||||
roles: roles,
|
||||
groups: groups,
|
||||
)
|
||||
|
||||
user3 = User.create_or_update(
|
||||
login: 'assets3@example.org',
|
||||
firstname: 'assets3',
|
||||
lastname: 'assets3',
|
||||
email: 'assets3@example.org',
|
||||
password: 'some_pass',
|
||||
active: true,
|
||||
updated_by_id: user1.id,
|
||||
created_by_id: user2.id,
|
||||
roles: roles,
|
||||
groups: groups,
|
||||
)
|
||||
user3 = User.find(user3.id)
|
||||
assets = user3.assets({})
|
||||
|
||||
org1 = Organization.find(org1.id)
|
||||
attributes = org1.attributes_with_association_ids
|
||||
attributes.delete('user_ids')
|
||||
assert(diff(attributes, assets[:Organization][org1.id]), 'check assets')
|
||||
|
||||
user1 = User.find(user1.id)
|
||||
attributes = user1.attributes_with_association_ids
|
||||
attributes['accounts'] = {}
|
||||
attributes.delete('password')
|
||||
attributes.delete('token_ids')
|
||||
attributes.delete('authorization_ids')
|
||||
assert(diff(attributes, assets[:User][user1.id]), 'check assets')
|
||||
|
||||
user2 = User.find(user2.id)
|
||||
attributes = user2.attributes_with_association_ids
|
||||
attributes['accounts'] = {}
|
||||
attributes.delete('password')
|
||||
attributes.delete('token_ids')
|
||||
attributes.delete('authorization_ids')
|
||||
assert(diff(attributes, assets[:User][user2.id]), 'check assets')
|
||||
|
||||
user3 = User.find(user3.id)
|
||||
attributes = user3.attributes_with_association_ids
|
||||
attributes['accounts'] = {}
|
||||
attributes.delete('password')
|
||||
attributes.delete('token_ids')
|
||||
attributes.delete('authorization_ids')
|
||||
assert(diff(attributes, assets[:User][user3.id]), 'check assets')
|
||||
|
||||
# touch org, check if user1 has changed
|
||||
travel 2.seconds
|
||||
org2 = Organization.find(org1.id)
|
||||
org2.note = "some note...#{rand(9_999_999_999_999)}"
|
||||
org2.save!
|
||||
|
||||
attributes = org2.attributes_with_association_ids
|
||||
attributes.delete('user_ids')
|
||||
assert_not(diff(attributes, assets[:Organization][org2.id]), 'check assets')
|
||||
|
||||
user1_new = User.find(user1.id)
|
||||
attributes = user1_new.attributes_with_association_ids
|
||||
attributes['accounts'] = {}
|
||||
attributes.delete('password')
|
||||
attributes.delete('token_ids')
|
||||
attributes.delete('authorization_ids')
|
||||
assert_not(diff(attributes, assets[:User][user1_new.id]), 'check assets')
|
||||
|
||||
# check new assets lookup
|
||||
assets = user3.assets({})
|
||||
attributes = org2.attributes_with_association_ids
|
||||
attributes.delete('user_ids')
|
||||
assert(diff(attributes, assets[:Organization][org1.id]), 'check assets')
|
||||
|
||||
user1 = User.find(user1.id)
|
||||
attributes = user1.attributes_with_association_ids
|
||||
attributes['accounts'] = {}
|
||||
attributes.delete('password')
|
||||
attributes.delete('token_ids')
|
||||
attributes.delete('authorization_ids')
|
||||
assert(diff(attributes, assets[:User][user1.id]), 'check assets')
|
||||
|
||||
user2 = User.find(user2.id)
|
||||
attributes = user2.attributes_with_association_ids
|
||||
attributes['accounts'] = {}
|
||||
attributes.delete('password')
|
||||
attributes.delete('token_ids')
|
||||
attributes.delete('authorization_ids')
|
||||
assert(diff(attributes, assets[:User][user2.id]), 'check assets')
|
||||
|
||||
user3 = User.find(user3.id)
|
||||
attributes = user3.attributes_with_association_ids
|
||||
attributes['accounts'] = {}
|
||||
attributes.delete('password')
|
||||
attributes.delete('token_ids')
|
||||
attributes.delete('authorization_ids')
|
||||
assert(diff(attributes, assets[:User][user3.id]), 'check assets')
|
||||
travel_back
|
||||
|
||||
user3.destroy!
|
||||
user2.destroy!
|
||||
user1.destroy!
|
||||
org1.destroy!
|
||||
assert_not(Organization.find_by(id: org2.id))
|
||||
end
|
||||
|
||||
def diff(o1, o2)
|
||||
return true if o1 == o2
|
||||
%w(updated_at created_at).each do |item|
|
||||
if o1[item]
|
||||
o1[item] = o1[item].to_s
|
||||
end
|
||||
if o2[item]
|
||||
o2[item] = o2[item].to_s
|
||||
end
|
||||
end
|
||||
return true if (o1.to_a - o2.to_a).blank?
|
||||
#puts "ERROR: difference \n1: #{o1.inspect}\n2: #{o2.inspect}\ndiff: #{(o1.to_a - o2.to_a).inspect}"
|
||||
false
|
||||
end
|
||||
|
||||
end
|
||||
40
test/unit/user_mail_delivery_failed_test.rb
Normal file
40
test/unit/user_mail_delivery_failed_test.rb
Normal file
@@ -0,0 +1,40 @@
|
||||
require 'test_helper'
|
||||
|
||||
class UserMailDeliveryFailedTest < ActiveSupport::TestCase
|
||||
setup do
|
||||
|
||||
UserInfo.current_user_id = 1
|
||||
|
||||
roles = Role.where(name: 'Customer')
|
||||
@customer1 = User.create_or_update(
|
||||
login: 'user-mail-delivery-failed-customer1@example.com',
|
||||
firstname: 'UserOutOfOffice',
|
||||
lastname: 'Customer1',
|
||||
email: 'user-mail-delivery-failed-customer1@example.com',
|
||||
password: 'agentpw',
|
||||
active: true,
|
||||
roles: roles,
|
||||
)
|
||||
|
||||
end
|
||||
|
||||
test 'check reset of mail_delivery_failed' do
|
||||
|
||||
@customer1.preferences[:mail_delivery_failed] = true
|
||||
@customer1.preferences[:mail_delivery_failed_data] = Time.zone.now
|
||||
@customer1.save!
|
||||
@customer1.reload
|
||||
|
||||
assert_equal(@customer1.preferences[:mail_delivery_failed], true)
|
||||
assert(@customer1.preferences[:mail_delivery_failed_data])
|
||||
|
||||
@customer1.email = 'new-user-mail-delivery-failed-customer1@example.com'
|
||||
@customer1.save!
|
||||
@customer1.reload
|
||||
|
||||
assert_not(@customer1.preferences[:mail_delivery_failed], true)
|
||||
assert(@customer1.preferences[:mail_delivery_failed_data])
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
@@ -932,15 +932,9 @@ class UserTest < ActiveSupport::TestCase
|
||||
end
|
||||
|
||||
test 'min admin permission check' do
|
||||
# workaround:
|
||||
# - We need to get rid of all admin users but can't delete them
|
||||
# because we have foreign keys pointing at them since the tests are not isolated yet :(
|
||||
# - We can't just remove the roles since then our check would take place
|
||||
# So we need to merge them with the User Nr 1 and destroy them afterwards
|
||||
User.with_permissions('admin').each do |user|
|
||||
Models.merge('User', 1, user.id)
|
||||
user.destroy!
|
||||
end
|
||||
|
||||
# delete inital admin
|
||||
User.find_by(login: 'admin@example.com').destroy
|
||||
|
||||
# store current admin count
|
||||
admin_count_inital = User.with_permissions('admin').count
|
||||
|
||||
@@ -79,7 +79,7 @@ class UserValidateAgentLimit < ActiveSupport::TestCase
|
||||
permissions: Permission.where(name: 'ticket.agent'),
|
||||
active: false,
|
||||
)
|
||||
user3.roles = [role_agent_limit]
|
||||
user3.roles = [role_agent_limit]
|
||||
user3.active = true
|
||||
user3.save!
|
||||
|
||||
@@ -90,6 +90,17 @@ class UserValidateAgentLimit < ActiveSupport::TestCase
|
||||
|
||||
assert_equal(User.with_permissions('ticket.agent').count, agent_max)
|
||||
|
||||
# set roles of agent again
|
||||
role_admin = Role.lookup(name: 'Admin')
|
||||
user2.roles = [role_agent, role_admin]
|
||||
user2.save!
|
||||
|
||||
user2.role_ids = [role_admin.id, role_agent_limit.id]
|
||||
user2.save!
|
||||
|
||||
user2.role_ids = [role_admin.id.to_s, role_agent_limit.id.to_s]
|
||||
user2.save!
|
||||
|
||||
user1.destroy!
|
||||
user2.destroy!
|
||||
user3.destroy!
|
||||
|
||||
Reference in New Issue
Block a user