lazylead 0.1.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +19 -7
  3. data/.circleci/release_image.sh +10 -7
  4. data/.docker/Dockerfile +10 -9
  5. data/.docker/docker-compose.yml +3 -3
  6. data/.docker/readme.md +24 -21
  7. data/.docker/vcs.dockerfile +10 -0
  8. data/.docs/duedate_expired.md +92 -0
  9. data/.docs/propagate_down.md +89 -0
  10. data/.rubocop.yml +1 -1
  11. data/.rultor.yml +13 -14
  12. data/.simplecov +0 -6
  13. data/CNAME +1 -0
  14. data/Rakefile +38 -1
  15. data/bin/lazylead +7 -2
  16. data/lazylead.gemspec +5 -17
  17. data/lib/lazylead/cc.rb +180 -0
  18. data/lib/lazylead/cli/app.rb +4 -3
  19. data/lib/lazylead/exchange.rb +14 -1
  20. data/lib/lazylead/home.rb +38 -0
  21. data/lib/lazylead/model.rb +29 -7
  22. data/lib/lazylead/postman.rb +14 -14
  23. data/lib/lazylead/schedule.rb +4 -2
  24. data/lib/lazylead/system/fake.rb +1 -1
  25. data/lib/lazylead/system/jira.rb +46 -5
  26. data/lib/lazylead/task/fix_version.rb +1 -1
  27. data/lib/lazylead/task/propagate_down.rb +118 -0
  28. data/lib/lazylead/task/savepoint.rb +58 -0
  29. data/lib/lazylead/version.rb +1 -1
  30. data/lib/messages/due_date_expired.erb +8 -7
  31. data/lib/messages/illegal_fixversion_change.erb +9 -8
  32. data/lib/messages/missing_comment.erb +10 -9
  33. data/lib/messages/savepoint.erb +43 -0
  34. data/readme.md +98 -82
  35. data/test/lazylead/cc_test.rb +153 -0
  36. data/test/lazylead/cli/app_test.rb +1 -2
  37. data/test/lazylead/exchange_test.rb +20 -0
  38. data/test/lazylead/model_test.rb +11 -0
  39. data/test/lazylead/postman_test.rb +57 -0
  40. data/test/lazylead/system/jira_test.rb +8 -0
  41. data/test/lazylead/task/assignee_alert_test.rb +47 -0
  42. data/test/lazylead/task/duedate_test.rb +20 -8
  43. data/test/lazylead/task/fix_version_test.rb +2 -4
  44. data/test/lazylead/task/missing_comment_test.rb +2 -4
  45. data/test/lazylead/task/propagate_down_test.rb +86 -0
  46. data/test/lazylead/task/savepoint_test.rb +51 -0
  47. data/test/test.rb +11 -0
  48. data/upgrades/sqlite/001-install-main-lazylead-tables.sql +3 -4
  49. data/upgrades/sqlite/999.testdata.sql +7 -2
  50. metadata +38 -175
  51. data/deploy.sh +0 -16
  52. data/todo.yml +0 -16
data/readme.md CHANGED
@@ -3,7 +3,6 @@
3
3
  [![Downloads](https://ruby-gem-downloads-badge.herokuapp.com/lazylead?type=total)](https://rubygems.org/gems/lazylead)
4
4
  [![](https://img.shields.io/docker/pulls/dgroup/lazylead.svg)](https://hub.docker.com/r/dgroup/lazylead "Image pulls")
5
5
  [![](https://images.microbadger.com/badges/image/dgroup/lazylead.svg)](https://microbadger.com/images/dgroup/lazylead "Image layers")
6
- [![](https://images.microbadger.com/badges/version/dgroup/lazylead.svg)](https://microbadger.com/images/dgroup/lazylead "Image version")
7
6
  [![Commit activity](https://img.shields.io/github/commit-activity/y/dgroup/lazylead.svg?style=flat-square)](https://github.com/dgroup/lazylead/graphs/commit-activity)
8
7
  [![Hits-of-Code](https://hitsofcode.com/github/dgroup/lazylead)](https://hitsofcode.com/view/github/dgroup/lazylead)
9
8
  [![License: MIT](https://img.shields.io/github/license/mashape/apistatus.svg)](./license.txt)
@@ -11,62 +10,71 @@
11
10
  [![Build status circleci](https://circleci.com/gh/dgroup/lazylead.svg?style=shield)](https://circleci.com/gh/dgroup/lazylead)
12
11
  [![0pdd](http://www.0pdd.com/svg?name=dgroup/lazylead)](http://www.0pdd.com/p?name=dgroup/lazylead)
13
12
  [![Dependency Status](https://requires.io/github/dgroup/lazylead/requirements.svg?branch=master)](https://requires.io/github/dgroup/lazylead/requirements/?branch=master)
13
+ [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=dgroup_lazylead&metric=alert_status)](https://sonarcloud.io/dashboard?id=dgroup_lazylead)
14
+ [![codebeat badge](https://codebeat.co/badges/f3bc8c19-5986-413f-89c4-c869b1e9b705)](https://codebeat.co/projects/github-com-dgroup-lazylead-master)
15
+ [![Codacy Badge](https://app.codacy.com/project/badge/Grade/e1ec2d63ff9040d99c934e3c05c24abe)](https://www.codacy.com/manual/dgroup/lazylead?utm_source=github.com&utm_medium=referral&utm_content=dgroup/lazylead&utm_campaign=Badge_Grade)
14
16
  [![Maintainability](https://api.codeclimate.com/v1/badges/e873a41b1c76d7b2d6ae/maintainability)](https://codeclimate.com/github/dgroup/lazylead/maintainability)
17
+ [![codecov](https://codecov.io/gh/dgroup/lazylead/branch/master/graph/badge.svg)](https://codecov.io/gh/dgroup/lazylead)
15
18
 
16
19
  [![DevOps By Rultor.com](http://www.rultor.com/b/dgroup/lazylead)](http://www.rultor.com/p/dgroup/lazylead)
17
20
  [![EO badge](http://www.elegantobjects.org/badge.svg)](http://www.elegantobjects.org/#principles)
18
21
 
22
+ ⚠️ We're still in a very early alpha version, the API may change frequently until we release version `1.0`.
23
+
19
24
  ### Overview
20
25
  Ticketing systems (Github, Jira, etc.) are strongly integrated into our processes and everyone understands their necessity. As soon as a developer becomes a lead/technical manager, he or she faces a set of routine tasks that are related to ticketing work. On large projects this becomes a problem, more and more you spend time running around on dashboards and tickets, looking for incorrect deviations in tickets and performing routine tasks instead of solving technical problems.
21
26
 
22
27
  The idea of automatic management is not new, for example [Zerocracy](https://www.zerocracy.com/) is available on the market.
23
28
  I like this idea, but large companies/projects are not ready yet for such a decisive breakthrough and need step-by-step solutions such as [lazylead](https://github.com/dgroup/lazylead).
24
- I think you remember how [static code analysis](https://en.wikipedia.org/wiki/Static_program_analysis) treated at in the past; today we have a huge toolkit (pmd, checkstyle, qulice, rubocop, etc) for each language that allows you to avoid routine/known issues and remove from the code reviewer the unnecessary load.
29
+ I think you remember how [static code analysis](https://en.wikipedia.org/wiki/Static_program_analysis) treated at in the past; today we have a huge toolkit (pmd, checkstyle, qulice, rubocop, peon, etc) for each language that allows you to avoid routine issues and remove from the code reviewer the unnecessary load.
25
30
 
26
- Join our [telegram group](https://t.me/lazyleads) for discussions.
27
-
28
- | Daily annoying task | Jira | Github | Trello |
29
- | :--------------------------------------------------------------------- | :----------------: | :---------: | :---------: |
30
- | [Notify ticket's assignee](lib/lazylead/task/alert.rb) | :white_check_mark: | :hourglass: | :hourglass: |
31
- | [Notify ticket's reporter](lib/lazylead/task/alert.rb) | :white_check_mark: | :hourglass: | :hourglass: |
32
- | [Notify ticket's manager](lib/lazylead/task/alert.rb) | :white_check_mark: | :hourglass: | :hourglass: |
33
- | [Notify about illegal "Fix Version" modification](lib/lazylead/task/fix_version.rb) | :white_check_mark: | :x: | :x: |
34
- | [Expected comment in ticket is missing](lib/lazylead/task/missing_comment.rb) | :white_check_mark: | :hourglass: | :hourglass: |
35
- | Propagate some fields from parent ticket into sub-tasks | :hourglass: | :x: | :x: |
36
- | Print the current capacity of team into newly created tasks | :hourglass: | :hourglass: | :hourglass: |
37
- | Create/retrofit the defect automatically into latest release | :hourglass: | :hourglass: | :x: |
38
- | Notify about expired(ing) due dates | :hourglass: | :hourglass: | :hourglass: |
39
- | Notify about absent original estimations | :hourglass: | :hourglass: | :hourglass: |
40
- | Notify about 'Hot potato' tickets | :hourglass: | :hourglass: | :hourglass: |
41
- | Notify about long live tickets (aging) | :hourglass: | :hourglass: | :hourglass: |
42
- | Notify about tickets with invalid format (missing url/stacktrace, etc) | :hourglass: | :hourglass: | :hourglass: |
43
- | Create a meeting(s) automatically in case some tickets appeared (group by assignee/reporters/component/ticket type/etc) | :hourglass: | :hourglass: | :hourglass: |
44
-
45
- :white_check_mark: - implemented, :hourglass: - planned, :x: - not supported by ticketing system.
46
-
47
- | Integration | Type | Status |
48
- | :---------------------------------------------------- | :-----------: | :----------------: |
49
- | [Microsoft Exchange Server](lib/lazylead/exchange.rb) | Emails | :white_check_mark: |
50
- | [Microsoft Exchange Server](lib/lazylead/exchange.rb) | Calendar | :hourglass: |
51
- | [mail.yandex.ru](lib/lazylead/postman.rb) | Emails | :white_check_mark: |
52
- | [mail.google.ru](lib/lazylead/postman.rb) | Emails | :cactus: |
53
- | slack | Notifications | :hourglass: |
54
-
55
- :white_check_mark: - implemented, :hourglass: - planned, :cactus: - implemented, but not tested.
31
+ Join our telegram group [lazylead.org](https://t.me/lazyleads) for discussions.
32
+
33
+ | Daily annoying task | Jira | Github | Trello |
34
+ | :---------------------------------------------------------------------------------- | :---: | :----: | :----: |
35
+ | [Notify ticket's assignee](lib/lazylead/task/alert.rb) | | | |
36
+ | [Notify ticket's reporter](lib/lazylead/task/alert.rb) | | | |
37
+ | [Notify ticket's manager](lib/lazylead/task/alert.rb) | | | |
38
+ | [Notify about illegal "Fix Version" modification](lib/lazylead/task/fix_version.rb) | | | |
39
+ | [Expected comment in ticket is missing](lib/lazylead/task/missing_comment.rb) | | | |
40
+ | [Propagate some fields from parent ticket into sub-tasks](.docs/propagate_down.md) | | | |
41
+ | Print the current capacity of team into newly created tasks | | | |
42
+ | Create/retrofit the defect automatically into latest release | | | |
43
+ | [Notify about expired(ing) due dates](.docs/duedate_expired.md) | | | |
44
+ | Notify about absent original estimations | | | |
45
+ | Notify about 'Hot potato' tickets | | | |
46
+ | Notify about long live tickets (aging) | | | |
47
+ | Notify about tickets with invalid format (missing url/stacktrace, etc) | | | |
48
+ | Create a meeting(s) automatically in case some tickets appeared (group by assignee/reporters/component/ticket type/etc) | | | |
49
+
50
+ | Integration | Type | Status |
51
+ | :---------------------------------------------------- | :-----------: | :----: |
52
+ | [Microsoft Exchange Server](lib/lazylead/exchange.rb) | Emails | |
53
+ | [Microsoft Exchange Server](lib/lazylead/exchange.rb) | Calendar | |
54
+ | [mail.yandex.com](lib/lazylead/postman.rb) | Emails | |
55
+ | [mail.google.com](lib/lazylead/postman.rb) | Emails | 🌵 |
56
+ | calendar.google.com | Calendar | |
57
+ | slack.com | Notifications | |
58
+
59
+ ✅ - implemented, ⌛ - planned, 🌵 - implemented, but not tested, ❌ - not supported by ticketing system.
56
60
 
57
61
  New ideas, bugs, suggestions or questions are welcome [via GitHub issues](https://github.com/dgroup/lazylead/issues/new)!
58
62
 
59
63
  ### Get started
60
- :warning: We're still in a very early alpha version, the API may change frequently until we release version 1.0.
64
+ ⚠️ We're still in a very early alpha version, the API may change frequently until we release version `1.0`.
61
65
 
62
66
  Let's assume that:
63
67
  - your team is using jira as a ticketing system
64
- - you defined a jira filter with tickets where actions need. The filter id is `555` and it has JQL like `project=XXXX and type=Bug and status not in (Closed, Cancelled, "Ready For Testing", "On Hold) and parent = YYYY and duedate < startOfDay()`
68
+ - you defined a jira filter with tickets where actions need. The filter id is `555` and it has JQL like
69
+ ```text
70
+ project=XXXX and type=Bug and status not in (Closed, Cancelled, "Ready For Testing", "On Hold)
71
+ and parent = YYYY and duedate < startOfDay()
72
+ ```
65
73
  - you have `MS Exchange` server for email notifications
66
74
  - you want to notify your developers during working days at `8am (UTC)` time about tickets where due dates are expired
67
75
 
68
76
  For simplicity, we are using [docker-compose](https://docs.docker.com/compose/):
69
- 1. Define yml file with configuration [tasks.yml](.github/tasks.yml):
77
+ 1. Define yml file with configuration [tasks.yml](.github/tasks.yml)
70
78
  ```yml
71
79
  version: '2.3'
72
80
  services:
@@ -92,38 +100,40 @@ For simplicity, we are using [docker-compose](https://docs.docker.com/compose/):
92
100
  - ./:/lazylead/db
93
101
  # db/ll.db is sqlite file with jira related annoying tasks
94
102
  entrypoint: bin/lazylead --sqlite db/ll.db --trace --verbose
95
- ```
96
- or just download the project using git
97
- ```bash
98
- git clone https://github.com/dgroup/lazylead.git ll && cd ll && pwd && ls -lah
99
- ```
100
- 2. Create a container, using `docker-compose -f .github/tasks.yml up`
101
- The container will stop as there were no tasks provided:
102
- ```bash
103
- ll > docker-compose -f .github/tasks.yml up  100% 🔋  13:35:04
104
- Creating lazylead ... done
105
- Attaching to lazylead
106
- lazylead | [2020-06-06T10:35:13] DEBUG Memory footprint at start is 52MB
107
- lazylead | [2020-06-06T10:35:13] DEBUG Database: '/lazylead/db/ll.db', sql migration dir: '/lazylead/upgrades/sqlite'
108
- lazylead | [2020-06-06T10:35:13] DEBUG Migration applied to /lazylead/db/ll.db from /lazylead/upgrades/sqlite
109
- lazylead | [2020-06-06T10:35:13] DEBUG Database connection established
110
- lazylead | [2020-06-06T10:35:13] WARN SMTP connection enabled in test mode.
111
- lazylead | [2020-06-06T10:35:13] WARN ll-001: No tasks found.
112
- lazylead | [2020-06-06T10:35:13] DEBUG Memory footprint at the end is 66MB
113
- lazylead exited with code 0
114
- ll >
115
- ```
116
- 3. Define your team and tasks in database.
117
- Yes, there are no UI yet, but its planned. Pull requests are welcome!
118
- The tables structure defined [here](upgrades/sqlite/001-install-main-lazylead-tables.sql).
119
- Modify you [sqlite](https://sqlite.com/index.html) file(`ll.db`) using [DB Browser](https://sqlitebrowser.org/) or any similar tool.
120
- Please change the `<youremail.com>` to your email address in order to be in CC when developer get the notification:
121
- ```sql
122
- insert into teams (id, name, properties)
103
+ ```
104
+ or just download the project using git
105
+ ```bash
106
+ git clone https://github.com/dgroup/lazylead.git ll && cd ll
107
+ ```
108
+
109
+ 2. Create a container, using `docker-compose -f .github/tasks.yml up`
110
+ The container will stop as there were no tasks provided:
111
+ ```bash
112
+ ll > docker-compose -f .github/tasks.yml up
113
+ Creating lazylead ... done
114
+ Attaching to lazylead
115
+ lazylead | [2020-06-06T10:35:13] DEBUG Memory footprint at start is 52MB
116
+ lazylead | [2020-06-06T10:35:13] DEBUG Database: '/lazylead/db/ll.db', sql migration dir: '/lazylead/upgrades/sqlite'
117
+ lazylead | [2020-06-06T10:35:13] DEBUG Migration applied to /lazylead/db/ll.db from /lazylead/upgrades/sqlite
118
+ lazylead | [2020-06-06T10:35:13] DEBUG Database connection established
119
+ lazylead | [2020-06-06T10:35:13] WARN SMTP connection enabled in test mode.
120
+ lazylead | [2020-06-06T10:35:13] WARN ll-001: No tasks found.
121
+ lazylead | [2020-06-06T10:35:13] DEBUG Memory footprint at the end is 66MB
122
+ lazylead exited with code 0
123
+ ll >
124
+ ```
125
+
126
+ 3. Define your team and tasks in database.
127
+ Yes, there are no UI yet, but its planned. Pull requests are welcome!
128
+ The tables structure defined [here](upgrades/sqlite/001-install-main-lazylead-tables.sql).
129
+ Modify you [sqlite](https://sqlite.com/index.html) file(`ll.db`) using [DB Browser](https://sqlitebrowser.org/) or any similar tool.
130
+ Please change the `<youremail.com>` to your email address in order to be in CC when developer get the notification:
131
+ ```sql
132
+ insert into teams (id, name, properties)
123
133
  values (1, 'Dream team with lazylead', '{}');
124
- insert into systems(id, properties)
134
+ insert into systems(id, properties)
125
135
  values (1,'{"type":"Lazylead::Jira", "username":"${jira_user}", "password":"${jira_password}", "site":"${jira_url}", "context_path":""}');
126
- insert into tasks (name, cron, enabled, id, system, team_id, action, properties)
136
+ insert into tasks (name, cron, enabled, id, system, team_id, action, properties)
127
137
  values ('Expired due dates',
128
138
  '0 8 * * 1-5',
129
139
  'true',
@@ -131,30 +141,36 @@ For simplicity, we are using [docker-compose](https://docs.docker.com/compose/):
131
141
  'Lazylead::Task::AssigneeAlert',
132
142
  '{"sql":"filter=555", "cc":"<youremail.com>", "subject":"[LL] Expired due dates", "template":"lib/messages/due_date_expired.erb", "postman":"Lazylead::Exchange"}');
133
143
 
134
- ```
135
- Yes, for task scheduling we are using [cron](https://crontab.guru).
136
- 4. Once you changed `./ll.db`, please restart the container using `docker-compose -f .github/tasks.yml restart`
137
- ```bash
138
- ll > docker-compose -f .github/tasks.yml restart  100% 🔋  14:37:19
139
- Restarting lazylead ... done
140
- ```
141
- check the logs and stop container if needed
142
- ```bash
143
- ll > docker logs lazylead
144
+ ```
145
+ Yes, for task scheduling we are using [cron](https://crontab.guru).
146
+
147
+ 4. Once you changed `./ll.db`, please restart the container using `docker-compose -f .github/tasks.yml restart`
148
+ ```bash
149
+ ll > docker-compose -f .github/tasks.yml restart
150
+ Restarting lazylead ... done
151
+ ```
152
+ check the logs and stop container if needed
153
+ ```bash
154
+ ll > docker logs lazylead
144
155
  2020-06-06T11:37:36] DEBUG Memory footprint at start is 52MB
145
156
  [2020-06-06T11:37:37] DEBUG Database: '/lazylead/db/ll.db', sql migration dir: '/lazylead/upgrades/sqlite'
146
157
  [2020-06-06T11:37:37] DEBUG Migration applied to /lazylead/db/ll.db from /lazylead/upgrades/sqlite
147
158
  [2020-06-06T11:37:37] DEBUG Database connection established
148
159
  [2020-06-06T11:37:37] WARN SMTP connection enabled in test mode.
149
160
  [2020-06-06T11:37:37] DEBUG Task scheduled: id='1', name='Expired due dates', cron='0 8 * * 1-5', system='1', action='Lazylead::Task::AssigneeAlert', team_id='1', description='', enabled='true', properties='{"sql":"filter=555", "cc":"my.email@google.com", "subject":"[LL] Expired due dates", "template":"lib/messages/due_date_expired.erb", "postman":"Lazylead::Exchange"}'
150
- ll > docker stop lazylead
151
- lazylead
152
- ```
161
+ ...
162
+ ll > docker stop lazylead
163
+ lazylead
164
+ ```
153
165
 
154
- #### Contribution guide
155
- Pull requests are welcome!
156
- Don't forget to run this, beforehand:
157
- ```
166
+ ### How to contribute?
167
+ [![EO badge](http://www.elegantobjects.org/badge.svg)](http://www.elegantobjects.org/#principles)
168
+
169
+ Pull requests are welcome! Don't forget to add your name to contribution section and run this, beforehand:
170
+ ```ruby
158
171
  bundle exec rake
159
172
  ```
160
173
  Everyone interacting in this project’s codebases, issue trackers, chat rooms is expected to follow the [code of conduct](.github/CODE_OF_CONDUCT.md).
174
+
175
+ Contributors:
176
+ * [dgroup](https://github.com/dgroup) as Yurii Dubinka (yurii.dubinka@gmail.com)
@@ -0,0 +1,153 @@
1
+ # frozen_string_literal: true
2
+
3
+ # The MIT License
4
+ #
5
+ # Copyright (c) 2019-2020 Yurii Dubinka
6
+ #
7
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ # of this software and associated documentation files (the "Software"),
9
+ # to deal in the Software without restriction, including without limitation
10
+ # the rights to use, copy, modify, merge, publish, distribute, sublicense,
11
+ # and/or sell copies of the Software, and to permit persons to whom
12
+ # the Software is furnished to do so, subject to the following conditions:
13
+ #
14
+ # The above copyright notice and this permission notice shall be included
15
+ # in all copies or substantial portions of the Software.
16
+ #
17
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ # FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
20
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22
+ # ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
23
+ # OR OTHER DEALINGS IN THE SOFTWARE.
24
+
25
+ require_relative "../test"
26
+ require_relative "../../lib/lazylead/log"
27
+ require_relative "../../lib/lazylead/cli/app"
28
+ require_relative "../../lib/lazylead/cc"
29
+ require_relative "../../lib/lazylead/system/jira"
30
+
31
+ module Lazylead
32
+ class CcTest < Lazylead::Test
33
+ test "plain cc detected as text" do
34
+ assert Lazylead::CC.new.plain? "a@fake.com,b@fake.com"
35
+ end
36
+ test "plain cc not found in text" do
37
+ refute Lazylead::CC.new.plain? "justatext.com,eeeee.com"
38
+ end
39
+ test "plain cc detected as object" do
40
+ assert Lazylead::CC.new.recognized? Lazylead::PlainCC.new("a@fake.com")
41
+ end
42
+ test "cc is incorrect" do
43
+ refute Lazylead::CC.new.recognized? key: "value"
44
+ end
45
+ test "cc is not found in hash" do
46
+ assert Lazylead::CC.new.undefined? key: "value"
47
+ end
48
+ test "cc type is blank" do
49
+ assert Lazylead::CC.new.undefined? "type" => " "
50
+ end
51
+ end
52
+ class PlainCcTest < Lazylead::Test
53
+ test "cc has valid email" do
54
+ assert_equal "a@fake.com", Lazylead::PlainCC.new("a@fake.com").cc.first
55
+ end
56
+
57
+ test "cc has valid email despite on additional spaces" do
58
+ assert_equal "a@fake.com", Lazylead::PlainCC.new("a@fake.com ").cc.first
59
+ end
60
+
61
+ test "cc has valid email despite on unexpected symbols" do
62
+ assert_equal "a@f.com", Lazylead::PlainCC.new("a@f.com, , -").cc.first
63
+ end
64
+
65
+ test "cc has valid emails" do
66
+ assert_equal %w[a@fake.com b@fake.com c@fake.com],
67
+ Lazylead::PlainCC.new("a@fake.com,b@fake.com,c@fake.com").cc
68
+ end
69
+
70
+ test "cc count is correct" do
71
+ assert_equal 3, Lazylead::PlainCC.new("a@f.com,b@f.com,c@f.com").count
72
+ end
73
+
74
+ test "cc behaves as array" do
75
+ assert_equal %w[A@f.com B@f.com C@f.com],
76
+ Lazylead::PlainCC.new("a@f.com,b@f.com,c@f.com")
77
+ .map(&:capitalize)
78
+ end
79
+ end
80
+
81
+ class PredefinedCcTest < Lazylead::Test
82
+ test "predefined cc has valid emails" do
83
+ assert_entries(
84
+ {
85
+ "jdbc" => %w[j@fake.com],
86
+ "jvm" => %w[j@fake.com v@fake.com]
87
+ },
88
+ PredefinedCC.new(
89
+ "jdbc" => "j@fake.com ",
90
+ "jvm" => "j@fake.com,,v@fake.com"
91
+ ).to_h
92
+ )
93
+ end
94
+
95
+ test "all predefined cc are valid emails" do
96
+ assert_equal %w[j@fake.com v@fake.com m@fake.com],
97
+ PredefinedCC.new(
98
+ "jdbc" => "j@fake.com ",
99
+ "jvm" => "j@fake.com,,v@fake.com,-, ,m@fake.com"
100
+ ).cc
101
+ end
102
+
103
+ test "cc by key is found" do
104
+ assert_equal %w[j@fake.com],
105
+ PredefinedCC.new(
106
+ "jdbc" => "j@fake.com ",
107
+ "jvm" => "j@fake.com,,v@fake.com,-, ,m@fake.com"
108
+ )["jdbc"]
109
+ end
110
+
111
+ # @todo #/DEV The test has performance issue. Jira has no way how to take
112
+ # the emails for leads quickly due to https://bit.ly/2ZRZlWc.
113
+ # Thus, for each component we need to find a lead, and only then detect
114
+ # lead's email, thus, its took few minutes for huge projects.
115
+ test "cc by component is found" do
116
+ skip "Disabled due to performance issue with Jira API"
117
+ assert_equal ENV["cc_email"],
118
+ ComponentCC.new(
119
+ ENV["cc_project"],
120
+ Jira.new(
121
+ {
122
+ username: ENV["JIRA_USER"],
123
+ password: ENV["JIRA_PASS"],
124
+ site: ENV["JIRA_URL"],
125
+ context_path: ""
126
+ }
127
+ )
128
+ ).cc(ENV["cc_component"])
129
+ end
130
+
131
+ test "detect plain cc" do
132
+ CLI::App.new(Log::NOTHING, NoSchedule.new).run(
133
+ home: ".",
134
+ sqlite: "test/resources/#{no_ext(__FILE__)}.#{__method__}.db",
135
+ vcs4sql: "upgrades/sqlite",
136
+ testdata: true
137
+ )
138
+ assert_equal %w[leelakenny@mail.com maciecrane@mail.com],
139
+ ORM::Task.find(3).detect_cc(nil)["cc"].cc
140
+ end
141
+
142
+ test "detect complex cc by predefined component" do
143
+ CLI::App.new(Log::NOTHING, NoSchedule.new).run(
144
+ home: ".",
145
+ sqlite: "test/resources/#{no_ext(__FILE__)}.#{__method__}.db",
146
+ vcs4sql: "upgrades/sqlite",
147
+ testdata: true
148
+ )
149
+ assert_equal %w[tom@fake.com mike@fake.com],
150
+ ORM::Task.find(165).detect_cc(nil)["cc"].cc("jvm", "jdbc")
151
+ end
152
+ end
153
+ end
@@ -39,8 +39,7 @@ module Lazylead
39
39
  assert_tables "test/resources/#{no_ext(__FILE__)}.#{__method__}.db",
40
40
  systems: %w[id properties],
41
41
  teams: %w[id name properties],
42
- tasks: %w[id name cron system action team_id description
43
- enabled properties]
42
+ tasks: %w[id name cron system action team_id enabled properties]
44
43
  assert_fk "test/resources/#{no_ext(__FILE__)}.#{__method__}.db",
45
44
  %w[tasks team_id teams id],
46
45
  %w[tasks system systems id]
@@ -25,6 +25,7 @@
25
25
  require_relative "../test"
26
26
  require_relative "../../lib/lazylead/log"
27
27
  require_relative "../../lib/lazylead/salt"
28
+ require_relative "../../lib/lazylead/home"
28
29
  require_relative "../../lib/lazylead/exchange"
29
30
  require_relative "../../lib/lazylead/system/jira"
30
31
 
@@ -64,5 +65,24 @@ module Lazylead
64
65
  "template" => "lib/messages/due_date_expired.erb"
65
66
  )
66
67
  end
68
+
69
+ test "exchange email with attachment" do
70
+ skip "No MS Exchange credentials provided" unless env? "exchange_url",
71
+ "exchange_user",
72
+ "exchange_password",
73
+ "exchange_to"
74
+ Exchange.new(
75
+ Log::NOTHING,
76
+ Salt.new("exchange_salt"),
77
+ "exchange_url" => ENV["exchange_url"],
78
+ "exchange_user" => ENV["enc_exchange_usr"],
79
+ "exchange_password" => ENV["enc_exchange_psw"]
80
+ ).send(
81
+ to: ENV["exchange_to"],
82
+ "attachments" => "readme.md",
83
+ "subject" => "[LL] Attachments",
84
+ "template" => "lib/messages/savepoint.erb"
85
+ )
86
+ end
67
87
  end
68
88
  end
@@ -61,5 +61,16 @@ module Lazylead
61
61
  )
62
62
  assert_kind_of Lazylead::Postman, ORM::Task.find(5).postman
63
63
  end
64
+
65
+ test "task properties are using ENV variables" do
66
+ ENV["key171"] = "value"
67
+ CLI::App.new(Log::NOTHING, NoSchedule.new).run(
68
+ home: ".",
69
+ sqlite: "test/resources/#{no_ext(__FILE__)}.#{__method__}.db",
70
+ vcs4sql: "upgrades/sqlite",
71
+ testdata: true
72
+ )
73
+ assert_equal "value", ORM::Task.find(171).props["envkey"]
74
+ end
64
75
  end
65
76
  end