tracco 0.0.14 → 0.0.15

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 (45) hide show
  1. data/CHANGELOG +16 -0
  2. data/Gemfile.lock +1 -1
  3. data/README.md +4 -4
  4. data/lib/patches/trello/card.rb +3 -2
  5. data/lib/patches/trello/member.rb +4 -2
  6. data/lib/tasks/tasks.rake +2 -2
  7. data/lib/tracco/google_docs_exporter.rb +50 -47
  8. data/lib/tracco/models/effort.rb +40 -0
  9. data/lib/tracco/models/estimate.rb +29 -0
  10. data/lib/tracco/models/member.rb +64 -0
  11. data/lib/tracco/models/tracked_card.rb +148 -0
  12. data/lib/tracco/tracking/base.rb +68 -65
  13. data/lib/tracco/tracking/card_done_tracking.rb +9 -6
  14. data/lib/tracco/tracking/effort_tracking.rb +32 -29
  15. data/lib/tracco/tracking/estimate_tracking.rb +16 -13
  16. data/lib/tracco/tracking/factory.rb +18 -16
  17. data/lib/tracco/tracking/invalid_tracking.rb +15 -13
  18. data/lib/tracco/trello_tracker.rb +34 -30
  19. data/lib/tracco/version.rb +2 -2
  20. data/lib/tracco.rb +4 -4
  21. data/spec/factories/effort_factory.rb +2 -2
  22. data/spec/factories/estimate_factory.rb +1 -1
  23. data/spec/factories/tracked_card_factory.rb +1 -1
  24. data/spec/integration/trello_tracker_spec.rb +49 -47
  25. data/spec/models/effort_spec.rb +61 -0
  26. data/spec/models/estimate_spec.rb +40 -0
  27. data/spec/models/member_spec.rb +83 -0
  28. data/spec/models/tracked_card_spec.rb +467 -0
  29. data/spec/support/spec_helper_methods.rb +7 -1
  30. data/spec/tracking/card_done_tracking_spec.rb +11 -9
  31. data/spec/tracking/effort_tracking_spec.rb +77 -75
  32. data/spec/tracking/estimate_tracking_spec.rb +30 -28
  33. data/spec/tracking/factory_spec.rb +39 -0
  34. data/spec/trello_tracker_spec.rb +20 -18
  35. data/tracco.gemspec +1 -1
  36. metadata +12 -12
  37. data/lib/tracco/effort.rb +0 -37
  38. data/lib/tracco/estimate.rb +0 -26
  39. data/lib/tracco/member.rb +0 -61
  40. data/lib/tracco/tracked_card.rb +0 -145
  41. data/spec/effort_spec.rb +0 -59
  42. data/spec/estimate_spec.rb +0 -38
  43. data/spec/member_spec.rb +0 -81
  44. data/spec/tracked_card_spec.rb +0 -465
  45. data/spec/tracking_factory_spec.rb +0 -42
@@ -1,42 +1,45 @@
1
- module Tracking
2
- class EffortTracking
3
- include Base
1
+ module Tracco
2
+ module Tracking
3
+ class EffortTracking
4
+ include Base
4
5
 
5
- def add_to(card)
6
- card.efforts << effort unless card.contains_effort?(effort)
7
- end
6
+ def add_to(card)
7
+ card.efforts << effort unless card.contains_effort?(effort)
8
+ end
8
9
 
9
- def effort
10
- @effort ||= Effort.new(amount: total_effort_from(raw_effort), date: date, members: effort_members, tracking_notification_id: tracking_notification.id)
11
- end
10
+ def effort
11
+ @effort ||= Effort.new(amount: total_effort_from(raw_effort), date: date, members: effort_members, tracking_notification_id: tracking_notification.id)
12
+ end
12
13
 
13
- private
14
+ private
14
15
 
15
- def total_effort_from(raw_effort)
16
- effort_amount = convert_to_hours(raw_effort)
17
- total_effort = effort_amount * effort_members.size
18
- end
16
+ def total_effort_from(raw_effort)
17
+ effort_amount = convert_to_hours(raw_effort)
18
+ total_effort = effort_amount * effort_members.size
19
+ end
19
20
 
20
- def raw_effort
21
- extract_match_from_raw_tracking(/\+#{DURATION_REGEXP}/)
22
- end
21
+ def raw_effort
22
+ extract_match_from_raw_tracking(/\+#{DURATION_REGEXP}/)
23
+ end
23
24
 
24
- def effort_members
25
- @effort_members ||= members_involved_in_the_effort.map do |username|
26
- Member.build_from(Trello::Member.find(username))
25
+ def effort_members
26
+ @effort_members ||= members_involved_in_the_effort.map do |username|
27
+ Member.build_from(Trello::Member.find(username))
28
+ end
27
29
  end
28
- end
29
30
 
30
- def members_involved_in_the_effort
31
- members_involved_in_the_effort = raw_tracking.scan(/@(\w+)/).flatten
32
- members_involved_in_the_effort << notifier.username unless should_count_only_listed_members?
31
+ def members_involved_in_the_effort
32
+ members_involved_in_the_effort = raw_tracking.scan(/@(\w+)/).flatten
33
+ members_involved_in_the_effort << notifier.username unless should_count_only_listed_members?
33
34
 
34
- members_involved_in_the_effort
35
- end
35
+ members_involved_in_the_effort
36
+ end
36
37
 
37
- def should_count_only_listed_members?
38
- raw_tracking =~ /\((@\w+\W*\s*)+\)/
39
- end
38
+ def should_count_only_listed_members?
39
+ raw_tracking =~ /\((@\w+\W*\s*)+\)/
40
+ end
40
41
 
42
+ end
41
43
  end
44
+
42
45
  end
@@ -1,20 +1,23 @@
1
- module Tracking
2
- class EstimateTracking
3
- include Base
1
+ module Tracco
2
+ module Tracking
3
+ class EstimateTracking
4
+ include Base
4
5
 
5
- def estimate
6
- @estimate ||= Estimate.new(amount: convert_to_hours(raw_estimate), date: date, tracking_notification_id: tracking_notification.id)
7
- end
6
+ def estimate
7
+ @estimate ||= Estimate.new(amount: convert_to_hours(raw_estimate), date: date, tracking_notification_id: tracking_notification.id)
8
+ end
8
9
 
9
- def add_to(card)
10
- card.estimates << estimate unless card.contains_estimate?(estimate)
11
- end
10
+ def add_to(card)
11
+ card.estimates << estimate unless card.contains_estimate?(estimate)
12
+ end
12
13
 
13
- private
14
+ private
14
15
 
15
- def raw_estimate
16
- extract_match_from_raw_tracking(/\[#{DURATION_REGEXP}\]/)
17
- end
16
+ def raw_estimate
17
+ extract_match_from_raw_tracking(/\[#{DURATION_REGEXP}\]/)
18
+ end
18
19
 
20
+ end
19
21
  end
22
+
20
23
  end
@@ -1,26 +1,28 @@
1
- module Tracking
2
- class Factory
1
+ module Tracco
2
+ module Tracking
3
+ class Factory
3
4
 
4
- DURATION_REGEXP = '(\d+\.?\d*[phdg])'
5
+ DURATION_REGEXP = '(\d+\.?\d*[phdg])'
5
6
 
6
- @match_pairs = {}
7
+ @match_pairs = {}
7
8
 
8
- def self.build_from(tracking_notification)
9
- matching_pair = @match_pairs.find { |regexp, tracking_class| tracking_notification.data['text'] =~ regexp }
9
+ def self.build_from(tracking_notification)
10
+ matching_pair = @match_pairs.find { |regexp, tracking_class| tracking_notification.data['text'] =~ regexp }
10
11
 
11
- tracking_class = matching_pair ? matching_pair.last : Tracking::InvalidTracking
12
- tracking_class.new(tracking_notification)
13
- end
12
+ tracking_class = matching_pair ? matching_pair.last : Tracking::InvalidTracking
13
+ tracking_class.new(tracking_notification)
14
+ end
14
15
 
15
- private
16
+ private
16
17
 
17
- def self.match(match_pair)
18
- @match_pairs.merge!(match_pair)
19
- end
18
+ def self.match(match_pair)
19
+ @match_pairs.merge!(match_pair)
20
+ end
20
21
 
21
- match /\[#{DURATION_REGEXP}\]/ => Tracking::EstimateTracking
22
- match /\+#{DURATION_REGEXP}/ => Tracking::EffortTracking
23
- match /DONE/ => Tracking::CardDoneTracking
22
+ match /\[#{DURATION_REGEXP}\]/ => Tracking::EstimateTracking
23
+ match /\+#{DURATION_REGEXP}/ => Tracking::EffortTracking
24
+ match /DONE/ => Tracking::CardDoneTracking
24
25
 
26
+ end
25
27
  end
26
28
  end
@@ -1,19 +1,21 @@
1
- module Tracking
2
- class InvalidTracking
3
- include Base
1
+ module Tracco
2
+ module Tracking
3
+ class InvalidTracking
4
+ include Base
4
5
 
5
- def add_to(card)
6
- # do nothing
7
- Trello.logger.warn "Ignoring tracking notification: '#{raw_text}'"
8
- end
6
+ def add_to(card)
7
+ # do nothing
8
+ Trello.logger.warn "Ignoring tracking notification: '#{raw_text}'"
9
+ end
9
10
 
10
- def estimate
11
- nil
12
- end
11
+ def estimate
12
+ nil
13
+ end
13
14
 
14
- def effort
15
- nil
16
- end
15
+ def effort
16
+ nil
17
+ end
17
18
 
19
+ end
18
20
  end
19
21
  end
@@ -1,44 +1,48 @@
1
- class TrelloTracker
2
- include TrelloAuthorize
3
- include Trello
1
+ module Tracco
4
2
 
5
- trap("SIGINT") { exit! }
3
+ class TrelloTracker
4
+ include TrelloAuthorize
5
+ include Trello
6
6
 
7
- def initialize(custom_config_params = {})
8
- authorize_on_trello(custom_config_params)
9
- tracker_username(custom_config_params[:tracker_username])
10
- end
7
+ trap("SIGINT") { exit! }
8
+
9
+ def initialize(custom_config_params = {})
10
+ authorize_on_trello(custom_config_params)
11
+ tracker_username(custom_config_params[:tracker_username])
12
+ end
11
13
 
12
- def track(starting_date=Date.today)
13
- notifications = tracker.notifications_since(starting_date)
14
+ def track(starting_date=Date.today)
15
+ tracking_notifications = tracker.tracking_notifications_since(starting_date)
14
16
 
15
- oldest, latest = boundary_dates_in(notifications)
16
- Trello.logger.info "Processing #{notifications.size} tracking notifications (from #{oldest} to #{latest}) starting from #{starting_date}..."
17
+ oldest, latest = boundary_dates_in(tracking_notifications)
18
+ Trello.logger.info "Processing #{tracking_notifications.size} tracking events (from #{oldest} to #{latest}) starting from #{starting_date}..."
17
19
 
18
- notifications.each do |notification|
19
- tracking = Tracking::Factory.build_from(notification)
20
- begin
21
- tracked_card = TrackedCard.update_or_create_with(notification.card)
22
- tracked_card.add!(tracking)
23
- Trello.logger.info tracking
20
+ tracking_notifications.each do |tracking_notification|
21
+ tracking = Tracking::Factory.build_from(tracking_notification)
22
+ begin
23
+ tracked_card = TrackedCard.update_or_create_with(tracking_notification.card)
24
+ tracked_card.add!(tracking)
25
+ Trello.logger.info tracking
24
26
 
25
- rescue StandardError => e
26
- Trello.logger.warn "skipping tracking: #{e.message}".color(:magenta)
27
- Trello.logger.debug "#{e.backtrace}"
27
+ rescue StandardError => e
28
+ Trello.logger.warn "skipping tracking: #{e.message}".color(:magenta)
29
+ Trello.logger.debug "#{e.backtrace}"
30
+ end
28
31
  end
32
+ Trello.logger.info "Done tracking cards!".color(:green)
29
33
  end
30
- Trello.logger.info "Done tracking cards!".color(:green)
31
- end
32
34
 
33
- private
35
+ private
34
36
 
35
- def tracker
36
- @tracker ||= Member.find(tracker_username)
37
- end
37
+ def tracker
38
+ @tracker ||= Trello::Member.find(tracker_username)
39
+ end
40
+
41
+ def boundary_dates_in(tracking_notifications)
42
+ dates = tracking_notifications.map { |each_tracking_notification| Chronic.parse(each_tracking_notification.date) }
43
+ [dates.min, dates.max]
44
+ end
38
45
 
39
- def boundary_dates_in(notifications)
40
- dates = notifications.map { |each_notification| Chronic.parse(each_notification.date) }
41
- [dates.min, dates.max]
42
46
  end
43
47
 
44
48
  end
@@ -1,3 +1,3 @@
1
- class TrelloEffortTracker
2
- VERSION = '0.0.14'
1
+ module Tracco
2
+ VERSION = '0.0.15'
3
3
  end
data/lib/tracco.rb CHANGED
@@ -9,10 +9,10 @@ require 'forwardable'
9
9
  require 'tracco/mongoid_helper'
10
10
  require 'tracco/trello_configuration'
11
11
  require 'tracco/trello_authorize'
12
- require 'tracco/tracked_card'
13
- require 'tracco/member'
14
- require 'tracco/estimate'
15
- require 'tracco/effort'
12
+ require 'tracco/models/tracked_card'
13
+ require 'tracco/models/member'
14
+ require 'tracco/models/estimate'
15
+ require 'tracco/models/effort'
16
16
  require 'tracco/tracking/base'
17
17
  require 'tracco/tracking/estimate_tracking'
18
18
  require 'tracco/tracking/effort_tracking'
@@ -1,9 +1,9 @@
1
1
  FactoryGirl.define do
2
2
 
3
- factory :effort do
3
+ factory :effort, :class => Tracco::Effort do
4
4
  amount 4
5
5
  date Date.today
6
- members [Member.new(username: "any_name")]
6
+ members [Tracco::Member.new(username: "any_name")]
7
7
  sequence(:tracking_notification_id, 1000)
8
8
  muted false
9
9
  end
@@ -1,6 +1,6 @@
1
1
  FactoryGirl.define do
2
2
 
3
- factory :estimate do
3
+ factory :estimate, :class => Tracco::Estimate do
4
4
  amount 42
5
5
  date Date.today
6
6
  sequence(:tracking_notification_id, 1000)
@@ -1,6 +1,6 @@
1
1
  FactoryGirl.define do
2
2
 
3
- factory :tracked_card do
3
+ factory :tracked_card, :class => Tracco::TrackedCard do
4
4
  sequence(:short_id, 1000)
5
5
  sequence(:trello_id, 100000) { |n| "xyz#{n}" }
6
6
  sequence(:name) { |n| "any_card_#{n}" }
@@ -1,66 +1,68 @@
1
1
  require 'spec_helper'
2
2
  require 'ostruct'
3
3
 
4
- describe TrelloTracker do
5
- # This integration test works on a real Trello board created just for this purpose
6
- # (see https://trello.com/board/testingboard/50ff225c7162123e3600074f)
7
- # The board has some cards in todo, one card in progress and one done
4
+ module Tracco
5
+ describe TrelloTracker do
6
+ # This integration test works on a real Trello board created just for this purpose
7
+ # (see https://trello.com/board/testingboard/50ff225c7162123e3600074f)
8
+ # The board has some cards in todo, one card in progress and one done
8
9
 
9
- TODO_CARD_ID = "51062b71df2bfec47b0039fb"
10
- IN_PROGRESS_CARD_ID = "51062b99d81a343121004046"
11
- DONE_CARD_ID = "51062b936d2deed22100157e"
12
- ANOTHER_DONE_CARD_ID = "510c46d7c7bc9ac6020007ab"
10
+ TODO_CARD_ID = "51062b71df2bfec47b0039fb"
11
+ IN_PROGRESS_CARD_ID = "51062b99d81a343121004046"
12
+ DONE_CARD_ID = "51062b936d2deed22100157e"
13
+ ANOTHER_DONE_CARD_ID = "510c46d7c7bc9ac6020007ab"
13
14
 
14
- let(:config) {
15
- # auth params for trackinguser_for_test/testinguser!
16
- OpenStruct.new(tracker: "trackinguser_for_test",
17
- dev_key: "ef7c400e711057d7ba5e00be20139a33",
18
- token: "9047d8fdbfdc960d41910673e300516cc8630dd4967e9b418fc27e410516362e")
19
- }
15
+ let(:config) {
16
+ # auth params for trackinguser_for_test/testinguser!
17
+ OpenStruct.new(tracker: "trackinguser_for_test",
18
+ dev_key: "ef7c400e711057d7ba5e00be20139a33",
19
+ token: "9047d8fdbfdc960d41910673e300516cc8630dd4967e9b418fc27e410516362e")
20
+ }
20
21
 
21
- it "tracks some estimates and efforts", :needs_valid_configuration => true do
22
- without_logging do
23
- tracker = TrelloTracker.new(tracker_username: config.tracker, developer_public_key: config.dev_key, access_token_key: config.token)
24
- tracker.track(DateTime.parse("2013-01-28"))
25
- end
22
+ it "tracks some estimates and efforts", :needs_valid_configuration => true do
23
+ without_logging do
24
+ tracker = TrelloTracker.new(tracker_username: config.tracker, developer_public_key: config.dev_key, access_token_key: config.token)
25
+ tracker.track(DateTime.parse("2013-01-28"))
26
+ end
26
27
 
27
- # a card to do
28
- todo_card = TrackedCard.find_by_trello_id(TODO_CARD_ID)
28
+ # a card to do
29
+ todo_card = TrackedCard.find_by_trello_id(TODO_CARD_ID)
29
30
 
30
- todo_card.estimates.should have(1).estimate
31
- todo_card.estimates.first.amount.should == 4
32
- todo_card.should_not be_done
31
+ todo_card.estimates.should have(1).estimate
32
+ todo_card.estimates.first.amount.should == 4
33
+ todo_card.should_not be_done
33
34
 
34
- # a card in progress
35
- in_progress_card = TrackedCard.find_by_trello_id(IN_PROGRESS_CARD_ID)
35
+ # a card in progress
36
+ in_progress_card = TrackedCard.find_by_trello_id(IN_PROGRESS_CARD_ID)
36
37
 
37
- in_progress_card.estimates.should have(1).estimate
38
- in_progress_card.estimates.should have(1).effort
39
- in_progress_card.estimates.first.amount.should == 5
40
- in_progress_card.efforts.first.amount.should == 1
41
- in_progress_card.should_not be_done
38
+ in_progress_card.estimates.should have(1).estimate
39
+ in_progress_card.estimates.should have(1).effort
40
+ in_progress_card.estimates.first.amount.should == 5
41
+ in_progress_card.efforts.first.amount.should == 1
42
+ in_progress_card.should_not be_done
42
43
 
43
- # a done card
44
- done_card = TrackedCard.find_by_trello_id(DONE_CARD_ID)
45
- done_card.total_effort.should == 2
46
- done_card.should be_done
44
+ # a done card
45
+ done_card = TrackedCard.find_by_trello_id(DONE_CARD_ID)
46
+ done_card.total_effort.should == 2
47
+ done_card.should be_done
47
48
 
48
- # another done card (this time for the DONE column)
49
- another_done_card = TrackedCard.find_by_trello_id(ANOTHER_DONE_CARD_ID)
50
- another_done_card.should be_done
51
- end
49
+ # another done card (this time for the DONE column)
50
+ another_done_card = TrackedCard.find_by_trello_id(ANOTHER_DONE_CARD_ID)
51
+ another_done_card.should be_done
52
+ end
52
53
 
53
54
 
54
- private
55
+ private
55
56
 
56
- def without_logging(&block)
57
- original_error_level = Trello.logger.level
57
+ def without_logging(&block)
58
+ original_error_level = Trello.logger.level
58
59
 
59
- begin
60
- Trello.logger.level = Logger::WARN
61
- block.call unless block.nil?
62
- ensure
63
- Trello.logger.level = original_error_level
60
+ begin
61
+ Trello.logger.level = Logger::WARN
62
+ block.call unless block.nil?
63
+ ensure
64
+ Trello.logger.level = original_error_level
65
+ end
64
66
  end
65
67
  end
66
68
  end
@@ -0,0 +1,61 @@
1
+ require 'spec_helper'
2
+ require 'mongoid-rspec'
3
+
4
+ module Tracco
5
+ describe Effort do
6
+
7
+ it { should have_fields(:amount, :date, :muted, :tracking_notification_id) }
8
+ it { should be_embedded_in(:tracked_card) }
9
+ it { should embed_many(:members) }
10
+
11
+ describe "validation" do
12
+ it { should validate_presence_of(:amount) }
13
+ it { should validate_presence_of(:date) }
14
+ it { should validate_presence_of(:members) }
15
+ end
16
+
17
+ %w{piero tommaso tom ugo}.each do |username|
18
+ let(username.to_sym) { Member.new(username: username) }
19
+ end
20
+
21
+ describe "#amount_per_member" do
22
+ it "counts the amount spent per single member" do
23
+ effort = Effort.new(amount: 6, members: [piero, tommaso], date: Date.parse("2012-11-09"), )
24
+ effort.amount_per_member.should == 3
25
+ end
26
+ end
27
+
28
+ describe "equality" do
29
+ it "is equal to another effort with same amount, date and members" do
30
+ effort = Effort.new(amount: 3, date: Date.parse("2012-11-09"), members: [piero, tommaso])
31
+ same_effort = Effort.new(amount: 3, date: Date.parse("2012-11-09"), members: [piero, tommaso])
32
+ yet_same_effort = Effort.new(amount: 3, date: Date.parse("2012-11-09"), members: [tommaso, piero])
33
+
34
+ effort.should == same_effort
35
+ effort.should == yet_same_effort
36
+ end
37
+
38
+ it "is not equal when amount differs" do
39
+ effort = Effort.new(amount: 3, date: Date.today, members: [tom, ugo])
40
+ another_effort = Effort.new(amount: 1, date: Date.today, members: [tom, ugo])
41
+
42
+ effort.should_not == another_effort
43
+ end
44
+
45
+ it "is not equal when date differs" do
46
+ effort = Effort.new(amount: 3, date: Date.parse("2012-11-09"), members: [tom, ugo])
47
+ another_effort = Effort.new(amount: 3, date: Date.parse("2011-10-08"), members: [tom, ugo])
48
+
49
+ effort.should_not == another_effort
50
+ end
51
+
52
+ it "is not equal when members differ" do
53
+ effort = Effort.new(amount: 3, date: Date.today, members: [tom, ugo])
54
+ another_effort = Effort.new(amount: 3, date: Date.today, members: [piero, ugo])
55
+
56
+ effort.should_not == another_effort
57
+ end
58
+
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,40 @@
1
+ require 'spec_helper'
2
+ require 'mongoid-rspec'
3
+
4
+ module Tracco
5
+ describe Estimate do
6
+
7
+ it { should have_fields(:amount, :date) }
8
+ it { should be_embedded_in(:tracked_card) }
9
+
10
+ describe "validation" do
11
+ it { should validate_presence_of(:amount) }
12
+ it { should validate_presence_of(:date) }
13
+ end
14
+
15
+ describe "equality" do
16
+
17
+ it "is equal to another estimate with same amount and date" do
18
+ estimate = Estimate.new(amount: 3, date: Date.parse("2012-11-09"))
19
+ same_estimate = Estimate.new(amount: 3, date: Date.parse("2012-11-09"))
20
+
21
+ estimate.should == same_estimate
22
+ end
23
+
24
+ it "is not equal when amount differs" do
25
+ estimate = Estimate.new(amount: 3, date: Date.today)
26
+ another_estimate = Estimate.new(amount: 1, date: Date.today)
27
+
28
+ estimate.should_not == another_estimate
29
+ end
30
+
31
+ it "is not equal when date differs" do
32
+ estimate = Estimate.new(amount: 3, date: Date.parse("2012-11-09"))
33
+ another_estimate = Estimate.new(amount: 3, date: Date.parse("2011-10-08"))
34
+
35
+ estimate.should_not == another_estimate
36
+ end
37
+
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,83 @@
1
+ require 'spec_helper'
2
+ require 'mongoid-rspec'
3
+
4
+ module Tracco
5
+ describe Member do
6
+
7
+ it { should have_fields(:trello_id, :username, :full_name, :avatar_id, :bio, :url) }
8
+ it { should be_embedded_in(:effort) }
9
+
10
+ describe "validation" do
11
+ it { should validate_presence_of(:username) }
12
+ end
13
+
14
+ describe "equality" do
15
+ it "is equal to another member with the same username" do
16
+ member = Member.new(username: "piero")
17
+ same_member = Member.new(username: "piero")
18
+ different_member = Member.new(username: "tommaso")
19
+
20
+ member.should == same_member
21
+ member.should_not == different_member
22
+ end
23
+ end
24
+
25
+ describe ".build_from" do
26
+ it "builds a Member from a Trello Member" do
27
+ member = Member.build_from(Trello::Member.new("username" => "piero"))
28
+
29
+ member.username.should == "piero"
30
+ end
31
+
32
+ it "takes the Trello Member id and set it as trello_id" do
33
+ member = Member.build_from(Trello::Member.new("username" => "piero", "id" => "1234567abc"))
34
+
35
+ member.id.should_not == "1234567abc"
36
+ member.trello_id.should == "1234567abc"
37
+ end
38
+ end
39
+
40
+ describe "#effort_spent" do
41
+ %w{piero tommaso}.each do |username|
42
+ let(username.to_sym) { Member.new(username: username) }
43
+ end
44
+
45
+ let(:card) { TrackedCard.create(name: "any", short_id: 1234, trello_id: "123123") }
46
+ let(:another_card) { TrackedCard.create(name: "any_other", short_id: 1235, trello_id: "123125") }
47
+
48
+ it "is zero when the member did not spent effort at all" do
49
+ piero.effort_spent.should == 0
50
+ end
51
+
52
+ it "counts the effort spent on a card" do
53
+ card.efforts << Effort.new(amount: 4, date: Date.today, members: [piero, tommaso])
54
+ card.efforts << Effort.new(amount: 5, date: Date.today, members: [tommaso])
55
+
56
+ piero.effort_spent.should == 4 / 2
57
+ end
58
+
59
+ it "counts the effort spent on several cards" do
60
+ card.efforts << Effort.new(amount: 4, date: Date.today, members: [piero, tommaso])
61
+ another_card.efforts << Effort.new(amount: 5, date: Date.today, members: [piero])
62
+
63
+ piero.effort_spent.should == 2 + 5
64
+ end
65
+
66
+ it "counts the effort spent on a card from a given date" do
67
+ card.efforts << Effort.new(amount: 4, date: Date.yesterday, members: [piero])
68
+ card.efforts << Effort.new(amount: 5, date: Date.today, members: [piero])
69
+
70
+ piero.effort_spent(Date.today).should == 5
71
+ piero.effort_spent_since(Date.today).should == 5
72
+ end
73
+
74
+ end
75
+
76
+ describe "#avatar_url" do
77
+ it "points to the avatar thumbnail image" do
78
+ member = Member.new(avatar_id: "123xyz")
79
+ member.avatar_url.should == "https://trello-avatars.s3.amazonaws.com/123xyz/30.png"
80
+ end
81
+ end
82
+ end
83
+ end