trello_effort_tracker 0.0.3 → 0.0.4

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 (37) hide show
  1. data/.gitignore +2 -1
  2. data/.travis.yml +0 -1
  3. data/CHANGELOG +17 -0
  4. data/Gemfile +7 -4
  5. data/Gemfile.lock +27 -13
  6. data/README.md +106 -36
  7. data/Rakefile +1 -1
  8. data/config/config.template.yml +0 -1
  9. data/config/config.yml.trackinguser_for_test +7 -0
  10. data/lib/patches/trello/card.rb +19 -0
  11. data/lib/patches/trello/member.rb +5 -5
  12. data/lib/trello_effort_tracker/tracked_card.rb +17 -10
  13. data/lib/trello_effort_tracker/tracking/base.rb +82 -0
  14. data/lib/trello_effort_tracker/tracking/card_done_tracking.rb +10 -0
  15. data/lib/trello_effort_tracker/tracking/effort_tracking.rb +45 -0
  16. data/lib/trello_effort_tracker/tracking/estimate_tracking.rb +23 -0
  17. data/lib/trello_effort_tracker/tracking/invalid_tracking.rb +19 -0
  18. data/lib/trello_effort_tracker/tracking_factory.rb +22 -0
  19. data/lib/trello_effort_tracker/trello_authorize.rb +4 -20
  20. data/lib/trello_effort_tracker/trello_tracker.rb +5 -10
  21. data/lib/trello_effort_tracker/version.rb +1 -1
  22. data/lib/trello_effort_tracker.rb +7 -1
  23. data/spec/integration/trello_tracker_spec.rb +69 -0
  24. data/spec/patches/trello/card_spec.rb +25 -0
  25. data/spec/spec_helper.rb +46 -1
  26. data/spec/support/database_cleaner.rb +12 -0
  27. data/spec/tracked_card_spec.rb +56 -5
  28. data/spec/tracking/card_done_tracking_spec.rb +18 -0
  29. data/spec/tracking/effort_tracking_spec.rb +114 -0
  30. data/spec/tracking/estimate_tracking_spec.rb +44 -0
  31. data/spec/tracking_factory_spec.rb +42 -0
  32. data/spec/trello_authorize_spec.rb +10 -16
  33. data/spec/trello_configuration_spec.rb +2 -2
  34. data/trello_effort_tracker.gemspec +12 -0
  35. metadata +131 -5
  36. data/lib/trello_effort_tracker/tracking.rb +0 -130
  37. data/spec/tracking_spec.rb +0 -236
@@ -16,41 +16,37 @@ describe TrelloAuthorize do
16
16
  describe "#authorize_on_trello" do
17
17
 
18
18
  it "creates oath credentials using auth params given as params when present as arguments, ignoring env vars or config YML vars" do
19
- ENV["developer_public_key"] = ENV["access_token_key"] = ENV["developer_secret"] = "anything"
19
+ ENV["developer_public_key"] = ENV["access_token_key"] = "anything"
20
20
  YAML.should_receive(:load_file).never
21
21
 
22
- authorize_on_trello("developer_public_key" => "custom_dpk", "access_token_key" => "custom_atk", "developer_secret" => "custom_ds")
22
+ authorize_on_trello("developer_public_key" => "custom_dpk", "access_token_key" => "custom_atk")
23
23
 
24
- Trello::Authorization::OAuthPolicy.consumer_credential.key.should == "custom_dpk"
25
- Trello::Authorization::OAuthPolicy.consumer_credential.secret.should == "custom_ds"
26
- Trello::Authorization::OAuthPolicy.token.key.should == "custom_atk"
24
+ Trello.client.auth_policy.developer_public_key.should == "custom_dpk"
25
+ Trello.client.auth_policy.member_token.should == "custom_atk"
27
26
  end
28
27
 
29
28
  it "creates oath credentials using auth params taken from env variables when auth params are not given as arguments" do
30
29
  ENV["developer_public_key"] = "my_dpk"
31
30
  ENV["access_token_key"] = "my_atk"
32
- ENV["developer_secret"] = "my_ds"
33
31
 
34
32
  YAML.should_receive(:load_file).never
35
33
 
36
34
  authorize_on_trello("any" => "thing")
37
35
 
38
- Trello::Authorization::OAuthPolicy.consumer_credential.key.should == "my_dpk"
39
- Trello::Authorization::OAuthPolicy.consumer_credential.secret.should == "my_ds"
40
- Trello::Authorization::OAuthPolicy.token.key.should == "my_atk"
36
+ Trello.client.auth_policy.developer_public_key.should == "my_dpk"
37
+ Trello.client.auth_policy.member_token.should == "my_atk"
41
38
  end
42
39
 
43
40
  it "creates oath credentials using auth params from config file when auth env variables are not set" do
44
- ENV["developer_public_key"] = ENV["access_token_key"] = ENV["developer_secret"] = nil
41
+ ENV["developer_public_key"] = ENV["access_token_key"] = nil
45
42
 
46
- config_hash = {"trello" => { "developer_public_key" => "any_dpk", "access_token_key" => "any_atk", "developer_secret" => "any_ds"}}
43
+ config_hash = {"trello" => { "developer_public_key" => "any_dpk", "access_token_key" => "any_atk"}}
47
44
  YAML.should_receive(:load_file).with("config/config.yml").and_return(config_hash)
48
45
 
49
46
  authorize_on_trello("any" => "thing")
50
47
 
51
- Trello::Authorization::OAuthPolicy.consumer_credential.key.should == "any_dpk"
52
- Trello::Authorization::OAuthPolicy.consumer_credential.secret.should == "any_ds"
53
- Trello::Authorization::OAuthPolicy.token.key.should == "any_atk"
48
+ Trello.client.auth_policy.developer_public_key.should == "any_dpk"
49
+ Trello.client.auth_policy.member_token.should == "any_atk"
54
50
  end
55
51
 
56
52
  end
@@ -60,12 +56,10 @@ describe TrelloAuthorize do
60
56
  def keep_original_auth_envs
61
57
  @original_developer_public_key = ENV["developer_public_key"]
62
58
  @original_access_token_key = ENV["access_token_key"]
63
- @original_developer_secret = ENV["developer_secret"]
64
59
  end
65
60
 
66
61
  def reset_original_auth_envs
67
62
  ENV["developer_public_key"] = @original_developer_public_key
68
63
  ENV["access_token_key"] = @original_access_token_key
69
- ENV["developer_secret"] = @original_developer_secre
70
64
  end
71
65
  end
@@ -6,12 +6,11 @@ describe TrelloConfiguration do
6
6
 
7
7
  describe "#authorization_params_from_config_file" do
8
8
  it "loads the default trello auth params from config yml" do
9
- config_hash = {"trello" => { "developer_public_key" => "any_dpk", "access_token_key" => "any_atk", "developer_secret" => "any_ds"} }
9
+ config_hash = { "trello" => { "developer_public_key" => "any_dpk", "access_token_key" => "any_atk" } }
10
10
  YAML.should_receive(:load_file).with("config/config.yml").and_return(config_hash)
11
11
 
12
12
  authorization_params_from_config_file["developer_public_key"].should == "any_dpk"
13
13
  authorization_params_from_config_file["access_token_key"].should == "any_atk"
14
- authorization_params_from_config_file["developer_secret"].should == "any_ds"
15
14
  end
16
15
  end
17
16
 
@@ -30,6 +29,7 @@ describe TrelloConfiguration do
30
29
 
31
30
  tracker_username.should == "my_tracker"
32
31
  end
32
+
33
33
  it "searches for the trello tracker username in the config yml file if the env var is not set" do
34
34
  ENV["tracker_username"] = nil
35
35
  config_hash = {"tracker_username" => "my_trello_tracker" }
@@ -4,16 +4,28 @@ require File.expand_path('../lib/trello_effort_tracker/version', __FILE__)
4
4
  Gem::Specification.new do |gem|
5
5
  gem.name = "trello_effort_tracker"
6
6
  gem.version = TrelloEffortTracker::VERSION
7
+ gem.platform = Gem::Platform::RUBY
8
+
7
9
  gem.description = "A tool to extract estimates and efforts from Trello"
8
10
  gem.summary = "You notify all the estimates and efforts of your Trello cards. This tool will extract and store these estimates and actual efforts to let you extract useful key metrics (e.g. estimate errors)"
9
11
  gem.authors = ['Pietro Di Bello']
10
12
  gem.email = 'pierodibello@gmail.com'
11
13
  gem.homepage = 'http://xplayer.wordpress.com'
12
14
  gem.date = Time.now.strftime "%Y-%m-%d"
15
+
13
16
  gem.require_paths = ["lib"]
14
17
  gem.files = `git ls-files`.split("\n")
15
18
  gem.test_files = `git ls-files -- {spec}/*`.split("\n")
16
19
  gem.extra_rdoc_files = ["README.md"]
20
+
17
21
  gem.rubygems_version = %q{1.8.24}
18
22
  gem.required_rubygems_version = ">= 1.3.6"
23
+
24
+ gem.add_dependency 'ruby-trello'
25
+ gem.add_dependency 'mongoid'
26
+ gem.add_dependency 'bson_ext'
27
+ gem.add_dependency 'google_drive'
28
+ gem.add_dependency 'rainbow'
29
+ gem.add_dependency 'chronic'
30
+ gem.add_dependency 'highline'
19
31
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: trello_effort_tracker
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,8 +9,120 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-01-15 00:00:00.000000000 Z
13
- dependencies: []
12
+ date: 2013-02-03 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: ruby-trello
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: mongoid
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: bson_ext
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: google_drive
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :runtime
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: rainbow
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :runtime
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ - !ruby/object:Gem::Dependency
95
+ name: chronic
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :runtime
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ - !ruby/object:Gem::Dependency
111
+ name: highline
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ! '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ! '>='
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
14
126
  description: A tool to extract estimates and efforts from Trello
15
127
  email: pierodibello@gmail.com
16
128
  executables: []
@@ -22,13 +134,16 @@ files:
22
134
  - .rspec
23
135
  - .rvmrc.template
24
136
  - .travis.yml
137
+ - CHANGELOG
25
138
  - Gemfile
26
139
  - Gemfile.lock
27
140
  - LICENSE.txt
28
141
  - README.md
29
142
  - Rakefile
30
143
  - config/config.template.yml
144
+ - config/config.yml.trackinguser_for_test
31
145
  - config/mongoid.template.yml
146
+ - lib/patches/trello/card.rb
32
147
  - lib/patches/trello/member.rb
33
148
  - lib/startup_trello.rb
34
149
  - lib/trello_effort_tracker.rb
@@ -38,7 +153,12 @@ files:
38
153
  - lib/trello_effort_tracker/member.rb
39
154
  - lib/trello_effort_tracker/mongoid_helper.rb
40
155
  - lib/trello_effort_tracker/tracked_card.rb
41
- - lib/trello_effort_tracker/tracking.rb
156
+ - lib/trello_effort_tracker/tracking/base.rb
157
+ - lib/trello_effort_tracker/tracking/card_done_tracking.rb
158
+ - lib/trello_effort_tracker/tracking/effort_tracking.rb
159
+ - lib/trello_effort_tracker/tracking/estimate_tracking.rb
160
+ - lib/trello_effort_tracker/tracking/invalid_tracking.rb
161
+ - lib/trello_effort_tracker/tracking_factory.rb
42
162
  - lib/trello_effort_tracker/trello_authorize.rb
43
163
  - lib/trello_effort_tracker/trello_configuration.rb
44
164
  - lib/trello_effort_tracker/trello_tracker.rb
@@ -50,10 +170,16 @@ files:
50
170
  - spec/effort_spec.rb
51
171
  - spec/estimate_spec.rb
52
172
  - spec/integration/trello_authorization_spec.rb
173
+ - spec/integration/trello_tracker_spec.rb
53
174
  - spec/member_spec.rb
175
+ - spec/patches/trello/card_spec.rb
54
176
  - spec/spec_helper.rb
177
+ - spec/support/database_cleaner.rb
55
178
  - spec/tracked_card_spec.rb
56
- - spec/tracking_spec.rb
179
+ - spec/tracking/card_done_tracking_spec.rb
180
+ - spec/tracking/effort_tracking_spec.rb
181
+ - spec/tracking/estimate_tracking_spec.rb
182
+ - spec/tracking_factory_spec.rb
57
183
  - spec/trello_authorize_spec.rb
58
184
  - spec/trello_configuration_spec.rb
59
185
  - trello_effort_tracker.gemspec
@@ -1,130 +0,0 @@
1
- class Tracking
2
- extend Forwardable
3
- include TrelloConfiguration
4
-
5
- TIME_CONVERTERS = {
6
- 'h' => lambda { |estimate| estimate },
7
- 'd' => lambda { |estimate| estimate * 8 },
8
- 'g' => lambda { |estimate| estimate * 8 },
9
- 'p' => lambda { |estimate| estimate / 2 }
10
- }
11
-
12
- DURATION_REGEXP = '(\d+\.?\d*[phdg])'
13
- DATE_REGEXP = /(\d{2})\.(\d{2})\.(\d{4})/
14
-
15
- # delegate to the trello notification the member_creator method aliased as 'notifier'
16
- def_delegator :@tracking_notification, :member_creator, :notifier
17
-
18
- def initialize(tracking_notification)
19
- @tracking_notification = tracking_notification
20
- end
21
-
22
- def date
23
- Chronic.parse(date_as_string).to_date
24
- end
25
-
26
- def estimate?
27
- !raw_estimate.nil?
28
- end
29
-
30
- def estimate
31
- estimate = convert_to_hours(raw_estimate)
32
- Estimate.new(amount: estimate, date: date, tracking_notification_id: @tracking_notification.id) if estimate
33
- end
34
-
35
- def effort?
36
- !raw_effort.nil?
37
- end
38
-
39
- def effort
40
- effort_amount = convert_to_hours(raw_effort)
41
- if effort_amount
42
- total_effort = effort_amount * effort_members.size
43
- Effort.new(amount: total_effort, date: date, members: effort_members, tracking_notification_id: @tracking_notification.id)
44
- end
45
- end
46
-
47
- def unknown_format?
48
- !estimate? && !effort?
49
- end
50
-
51
- def to_s
52
- "[#{date}] From #{notifier.username.color(:green)}\t on card '#{trello_card.name.color(:yellow)}': #{raw_text}"
53
- end
54
-
55
- private
56
-
57
- def effort_members
58
- @effort_members ||= users_involved_in_the_effort.map do |username|
59
- Member.build_from(Trello::Member.find(username))
60
- end
61
-
62
- @effort_members
63
- end
64
-
65
- def users_involved_in_the_effort
66
- users_involved_in_the_effort = raw_tracking.scan(/@(\w+)/).flatten
67
- users_involved_in_the_effort << notifier.username unless should_count_only_listed_members?
68
-
69
- users_involved_in_the_effort
70
- end
71
-
72
- def should_count_only_listed_members?
73
- raw_tracking =~ /\((@\w+\W*\s*)+\)/
74
- end
75
-
76
- def raw_tracking
77
- raw_text.gsub("@#{tracker_username}", "")
78
- end
79
-
80
- def raw_text
81
- @tracking_notification.data['text']
82
- end
83
-
84
- def raw_estimate
85
- extract_match_from_raw_tracking(/\[#{DURATION_REGEXP}\]/)
86
- end
87
-
88
- def raw_effort
89
- extract_match_from_raw_tracking(/\+#{DURATION_REGEXP}/)
90
- end
91
-
92
- def convert_to_hours(duration_as_string)
93
- return if duration_as_string.nil?
94
-
95
- time_scale = duration_as_string.slice!(-1)
96
- converter = TIME_CONVERTERS[time_scale]
97
- converter.call(Float(duration_as_string))
98
- end
99
-
100
- def date_as_string
101
- case raw_tracking
102
- when DATE_REGEXP
103
- day, month, year = raw_tracking.scan(DATE_REGEXP).flatten
104
- "#{year}-#{month}-#{day}"
105
- when /yesterday\s+\+#{DURATION_REGEXP}/, /\+#{DURATION_REGEXP}\s+yesterday/
106
- (notification_date - 1).to_s
107
- else
108
- @tracking_notification.date
109
- end
110
- end
111
-
112
- def extract_match_from_raw_tracking(regexp)
113
- extracted = nil
114
- raw_tracking.scan(regexp) do |match|
115
- extracted = match.first
116
- end
117
-
118
- extracted
119
- end
120
-
121
- def trello_card
122
- @trello_card ||= @tracking_notification.card
123
- end
124
-
125
- def notification_date
126
- Chronic.parse(@tracking_notification.date).to_date
127
- end
128
-
129
- end
130
-
@@ -1,236 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Tracking do
4
-
5
- TIME_MEASUREMENTS = {
6
- hours: 'h',
7
- days: 'd',
8
- giorni: 'g',
9
- pomodori: 'p'
10
- }
11
-
12
- let(:unrecognized_notification) { create_notification(data: { 'text' => '@trackinguser hi there!' }) }
13
-
14
- describe "#unknown_format?" do
15
- it "tells when a notification cannot be interpreted as a tracking info" do
16
- Tracking.new(unrecognized_notification).unknown_format?.should be_true
17
-
18
- with_message("@trackinguser +30m") { |tracking| tracking.unknown_format?.should be_true }
19
- end
20
-
21
- end
22
-
23
- describe "#estimate?" do
24
- it "is false when the notification does not contain an estimate" do
25
- Tracking.new(unrecognized_notification).estimate?.should be_false
26
- end
27
-
28
- TIME_MEASUREMENTS.each_key do |time_measurement|
29
- it "is true when the notification contains an estimate in #{time_measurement}" do
30
- tracking_estimate = Tracking.new(create_estimate(time_measurement))
31
-
32
- tracking_estimate.estimate?.should be_true
33
- tracking_estimate.effort?.should be_false
34
- end
35
- end
36
-
37
- end
38
-
39
- describe "#estimate" do
40
-
41
- it "is nil when the notification does not contain an estimate" do
42
- Tracking.new(unrecognized_notification).estimate.should be_nil
43
- end
44
-
45
- it "is the hour-based estimate when the notification contains an estimate in hours" do
46
- raw_data = create_notification(data: { 'text' => "@trackinguser [2h]" }, date: "2012-10-28T21:06:14.801Z")
47
-
48
- Tracking.new(raw_data).estimate.should == Estimate.new(amount: 2.0, date: Date.parse('2012-10-28'))
49
- end
50
-
51
- it "converts the estimate in hours when the notification contains an estimate in days" do
52
- Tracking.new(create_notification(data: { 'text' => "@trackinguser [1.5d]" })).estimate.amount.should == 8+4
53
- Tracking.new(create_notification(data: { 'text' => "@trackinguser [1.5g]" })).estimate.amount.should == 8+4
54
- end
55
-
56
- it "converts the estimate in hours when the notification contains an estimate in pomodori" do
57
- raw_data = create_notification(data: { 'text' => "@trackinguser [10p]" })
58
- Tracking.new(raw_data).estimate.amount.should == 5
59
- end
60
-
61
- it "fetch the estimate from a complex estimate message" do
62
- raw_data = create_notification(data: { 'text' => "@maxmazza Dobbiamo ancora lavorarci.\n@trackinguser ristimo ancora [3h] per il fix" })
63
- Tracking.new(raw_data).estimate.amount.should == 3.0
64
- end
65
-
66
- it "tracks the effort with the date given in the notification text, not the actual notification date" do
67
- raw_data = create_notification( data: { 'text' => "@trackinguser 22.11.2012 [6p]" }, date: "2012-09-19T12:46:13.713Z")
68
-
69
- tracking = Tracking.new(raw_data)
70
-
71
- tracking.estimate.date.should == Date.parse('2012-11-22')
72
- end
73
-
74
- end
75
-
76
- describe "#effort?" do
77
- it "is false when the notification does not contain an estimate" do
78
- Tracking.new(unrecognized_notification).effort?.should be_false
79
- end
80
-
81
- TIME_MEASUREMENTS.each_key do |time_measurement|
82
- it "is true when the notification contains an estimate in #{time_measurement}" do
83
- tracking_effort = Tracking.new(create_effort(time_measurement))
84
-
85
- tracking_effort.effort?.should be_true
86
- tracking_effort.estimate?.should be_false
87
- end
88
- end
89
- end
90
-
91
- describe "#effort" do
92
-
93
- %w{pietrodibello michelepangrazzi alessandrodescovi michelevincenzi}.each do |username|
94
- let(username.to_sym) { Member.new(username: username) }
95
- end
96
-
97
- before(:each) do
98
- Trello::Member.stub(:find).and_return(Member.new(username: "any"))
99
- end
100
-
101
- it "is nil when the notification does not contain an estimate" do
102
- with(unrecognized_notification) { |tracking| tracking.effort.should be_nil }
103
- end
104
-
105
- it "does not parse effort in minutes (e.g. +30m)" do
106
- with_message("@trackinguser +30m") { |tracking| tracking.effort.should be_nil }
107
- end
108
-
109
- it "is the hour-based effort when the notification contains an effort in hours" do
110
- Trello::Member.should_receive(:find).with("michelepangrazzi").and_return(michelepangrazzi)
111
-
112
- raw_data = create_notification(data: { 'text' => "@trackinguser +2h" },
113
- date: "2012-10-28T21:06:14.801Z",
114
- member_creator: stub(username: "michelepangrazzi"))
115
-
116
- Tracking.new(raw_data).effort.should == Effort.new(amount: 2.0, date: Date.parse('2012-10-28'), members: [michelepangrazzi])
117
- end
118
-
119
- it "converts the effort in hours when the notification contains an effort in days" do
120
- with_message("@trackinguser +1.5d") { |t| t.effort.amount.should == 8+4 }
121
- with_message("@trackinguser +1.5g") { |t| t.effort.amount.should == 8+4 }
122
- end
123
-
124
- it "converts the effort in hours when the notification contains an effort in pomodori" do
125
- with_message("@trackinguser +10p") { |t| t.effort.amount.should == 5}
126
- end
127
-
128
- it "fetch the effort from a complex effort message" do
129
- with_message "@trackinguser ho speso +2h e spero che stavolta possiamo rilasciarla" do |tracking|
130
- tracking.effort.amount.should == 2.0
131
- end
132
- end
133
-
134
- it "fetch the effort even when beween square brackets" do
135
- with_message "@trackinguser [+0.5h]" do |tracking|
136
- tracking.effort.amount.should == 0.5
137
- end
138
- end
139
-
140
- it "computes the effort considering all the mentioned team mates in the message" do
141
- with_message "@trackinguser +2h assieme a @michelepangrazzi e @alessandrodescovi" do |tracking|
142
- tracking.effort.amount.should == 2.0 * 3
143
- end
144
- end
145
-
146
- it "tracks all the team mates which spent that effort on the card" do
147
- %w{pietrodibello michelepangrazzi alessandrodescovi}.each do |username|
148
- Trello::Member.should_receive(:find).with(username).and_return(self.send(username))
149
- end
150
-
151
- notification = create_notification(data: { 'text' => "@trackinguser +2h assieme a @michelepangrazzi e @alessandrodescovi" },
152
- member_creator: stub(username: "pietrodibello"))
153
- with notification do |tracking|
154
- tracking.effort.members.should == [michelepangrazzi, alessandrodescovi, pietrodibello]
155
- end
156
- end
157
-
158
- it "tracks the effort only on the team members listed between round brackets" do
159
- %w{michelevincenzi alessandrodescovi}.each do |username|
160
- Trello::Member.should_receive(:find).with(username).and_return(self.send(username))
161
- end
162
-
163
- notification = create_notification(data: { 'text' => "@trackinguser +3p (@alessandrodescovi @michelevincenzi)" },
164
- member_creator: stub(username: "pietrodibello"))
165
-
166
- with notification do |tracking|
167
- tracking.effort.members.should == [alessandrodescovi, michelevincenzi]
168
- tracking.effort.amount.should == 1.5 * 2
169
- end
170
- end
171
-
172
- it "does not have an effort when is an estimate" do
173
- raw_data = create_notification(data: { 'text' => "@trackinguser stimata [6h]" })
174
-
175
- tracking = Tracking.new(raw_data)
176
-
177
- tracking.effort.should be_nil
178
- end
179
-
180
- it "tracks the effort with the date given in the notification text, not the actual notification date" do
181
- raw_data = create_notification(data: { 'text' => "@trackinguser 22.11.2012 +6p" }, date: "2012-09-19T12:46:13.713Z")
182
-
183
- tracking = Tracking.new(raw_data)
184
-
185
- tracking.effort.date.should == Date.parse('2012-11-22')
186
- end
187
-
188
- it "tracks the effort to yesterday when the keyword 'yesterday' is present before the effort amount" do
189
- raw_data = create_notification(data: { 'text' => "@trackinguser yesterday +6p" }, date: "2012-09-19T12:46:13.713Z")
190
-
191
- tracking = Tracking.new(raw_data)
192
-
193
- tracking.effort.date.should == Date.parse('2012-09-18')
194
- end
195
-
196
- it "tracks the effort to yesterday when the keyword 'yesterday' is present before the effort amount" do
197
- raw_data = create_notification(data: { 'text' => "@trackinguser +6p yesterday" }, date: "2012-09-19T12:46:13.713Z")
198
-
199
- tracking = Tracking.new(raw_data)
200
-
201
- tracking.effort.date.should == Date.parse('2012-09-18')
202
- end
203
-
204
- end
205
-
206
- private
207
-
208
- def notification_with_message(message)
209
- create_notification(data: { 'text' => message })
210
- end
211
-
212
- def create_notification(custom_params)
213
- params = { data: { 'text' => "@trackinguser +2h" }, date: "2012-10-28T21:06:14.801Z", member_creator: stub(username: "pietrodibello") }
214
- params.merge!(custom_params)
215
-
216
- stub(data: params[:data], date: params[:date], member_creator: params[:member_creator]).as_null_object
217
- end
218
-
219
- def create_estimate(time_measurement)
220
- create_notification(data: { 'text' => "@trackinguser [1.5#{TIME_MEASUREMENTS[time_measurement]}]" })
221
- end
222
-
223
- def create_effort(time_measurement)
224
- create_notification(data: { 'text' => "@trackinguser +4.5#{TIME_MEASUREMENTS[time_measurement]}]" })
225
- end
226
-
227
- def with(notification)
228
- tracking = Tracking.new(notification)
229
- yield(tracking)
230
- end
231
-
232
- def with_message(notification_message, &block)
233
- with(notification_with_message(notification_message), &block)
234
- end
235
-
236
- end