pivotal-to-trello 0.1.2 → 0.2.0

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.
@@ -3,32 +3,31 @@ require 'pivotal-tracker'
3
3
  module PivotalToTrello
4
4
  # Interface to the Pivotal Tracker API.
5
5
  class PivotalWrapper
6
-
7
6
  # Constructor
8
7
  def initialize(token)
9
8
  ::PivotalTracker::Client.token = token
9
+ ::PivotalTracker::Client.use_ssl = true
10
10
  end
11
11
 
12
12
  # Returns a hash of available projects keyed on project ID.
13
13
  def project_choices
14
- ::PivotalTracker::Project.all.inject({}) do |hash, project|
14
+ ::PivotalTracker::Project.all.each_with_object({}) do |project, hash|
15
15
  hash[project.id] = project.name
16
- hash
16
+
17
17
  end
18
18
  end
19
19
 
20
20
  # Returns all stories for the given project.
21
21
  def stories(project_id)
22
- project(project_id).stories.all
22
+ project(project_id).stories.all.sort_by(&:created_at)
23
23
  end
24
24
 
25
25
  private
26
26
 
27
- # Returns the Pivotal project that we're exporting.
28
- def project(project_id)
29
- @projects ||= {}
30
- @projects[project_id] ||= ::PivotalTracker::Project.find(project_id)
31
- end
32
-
27
+ # Returns the Pivotal project that we're exporting.
28
+ def project(project_id)
29
+ @projects ||= {}
30
+ @projects[project_id] ||= ::PivotalTracker::Project.find(project_id)
31
+ end
33
32
  end
34
- end
33
+ end
@@ -3,7 +3,6 @@ require 'trello'
3
3
  module PivotalToTrello
4
4
  # Interface to the Trello API.
5
5
  class TrelloWrapper
6
-
7
6
  # Constructor
8
7
  def initialize(key, token)
9
8
  Trello.configure do |config|
@@ -18,15 +17,13 @@ module PivotalToTrello
18
17
  card ||= begin
19
18
  puts "Creating a card for #{pivotal_story.story_type} '#{pivotal_story.name}'."
20
19
  card = Trello::Card.create(
21
- :name => pivotal_story.name,
22
- :desc => pivotal_story.description,
23
- :list_id => list_id
20
+ name: pivotal_story.name,
21
+ desc: pivotal_story.description,
22
+ list_id: list_id,
24
23
  )
25
24
 
26
- pivotal_story.notes.all.each do |note|
27
- card.add_comment("[#{note.author}] #{note.text.to_s.strip}") unless note.text.to_s.strip.empty?
28
- end
29
-
25
+ create_notes(card, pivotal_story)
26
+ create_tasks(card, pivotal_story)
30
27
  card
31
28
  end
32
29
 
@@ -38,9 +35,8 @@ module PivotalToTrello
38
35
 
39
36
  # Returns a hash of available boards, keyed on board ID.
40
37
  def board_choices
41
- Trello::Board.all.inject({}) do |hash, board|
38
+ Trello::Board.all.each_with_object({}) do |board, hash|
42
39
  hash[board.id] = board.name
43
- hash
44
40
  end
45
41
  end
46
42
 
@@ -49,9 +45,8 @@ module PivotalToTrello
49
45
  # Cache the list to improve performance.
50
46
  @lists ||= {}
51
47
  @lists[board_id] ||= begin
52
- choices = Trello::Board.find(board_id).lists.inject({}) do |hash, list|
48
+ choices = Trello::Board.find(board_id).lists.each_with_object({}) do |list, hash|
53
49
  hash[list.id] = list.name
54
- hash
55
50
  end
56
51
  choices = Hash[choices.sort_by { |_, v| v }]
57
52
  choices[false] = "[don't import these stories]"
@@ -64,17 +59,21 @@ module PivotalToTrello
64
59
  # Returns a list of all cards in the given list, keyed on name.
65
60
  def cards_for_list(list_id)
66
61
  @cards ||= {}
67
- @cards[list_id] ||= Trello::List.find(list_id).cards.inject({}) do |hash, card|
62
+ @cards[list_id] ||= Trello::List.find(list_id).cards.each_with_object({}) do |card, hash|
68
63
  hash[card_hash(card.name, card.desc)] = card
69
- hash
70
64
  end
71
65
 
72
66
  @cards[list_id]
73
67
  end
74
68
 
75
69
  # Adds the given label to the card.
76
- def add_label(card, label)
77
- card.add_label(label) unless card.labels.collect { |label| label.color }.include?(label)
70
+ def add_label(card, label_name, label_color)
71
+ @labels ||= {}
72
+ @labels[card.board_id] ||= Trello::Board.find(card.board_id).labels
73
+ label = @labels[card.board_id].find { |l| l.name == label_name && l.color == label_color }
74
+ label ||= Trello::Label.create(name: label_name, board_id: card.board_id, color: label_color)
75
+
76
+ card.add_label(label) unless card.labels.detect { |l| l.id == label.id }
78
77
  end
79
78
 
80
79
  # Returns a list of colors that can be used to label cards.
@@ -86,22 +85,42 @@ module PivotalToTrello
86
85
  'purple' => 'Purple',
87
86
  'red' => 'Red',
88
87
  'yellow' => 'Yellow',
89
- false => '[none]'
88
+ false => '[none]',
90
89
  }
91
90
  end
92
91
 
93
92
  private
94
93
 
95
- # Returns a unique identifier for this list/name/description combination.
96
- def card_hash(name, description)
97
- Digest::SHA1.hexdigest("#{name}_#{description}")
94
+ # Copies notes from the pivotal story to the card.
95
+ def create_notes(card, pivotal_story)
96
+ pivotal_story.notes.all.each do |note|
97
+ card.add_comment("[#{note.author}] #{note.text.to_s.strip}") unless note.text.to_s.strip.empty?
98
98
  end
99
+ end
100
+
101
+ # Copies notes from the pivotal story to the card.
102
+ def create_tasks(card, pivotal_story)
103
+ tasks = pivotal_story.tasks.all
104
+ return if tasks.empty?
99
105
 
100
- # Returns a card with the given name and description if it exists in the given list, nil otherwise.
101
- def get_card(list_id, name, description)
102
- key = card_hash(name, description)
103
- cards_for_list(list_id)[key] if !cards_for_list(list_id)[key].nil?
106
+ checklist = Trello::Checklist.create(name: 'Tasks', card_id: card.id)
107
+ card.add_checklist(checklist)
108
+
109
+ tasks.each do |task|
110
+ puts " - Creating task '#{task.description}'"
111
+ checklist.add_item(task.description, task.complete)
104
112
  end
113
+ end
105
114
 
115
+ # Returns a unique identifier for this list/name/description combination.
116
+ def card_hash(name, description)
117
+ Digest::SHA1.hexdigest("#{name}_#{description}")
118
+ end
119
+
120
+ # Returns a card with the given name and description if it exists in the given list, nil otherwise.
121
+ def get_card(list_id, name, description)
122
+ key = card_hash(name, description)
123
+ cards_for_list(list_id)[key] unless cards_for_list(list_id)[key].nil?
124
+ end
106
125
  end
107
- end
126
+ end
@@ -2,16 +2,16 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: pivotal-to-trello 0.1.2 ruby lib
5
+ # stub: pivotal-to-trello 0.2.0 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "pivotal-to-trello"
9
- s.version = "0.1.2"
9
+ s.version = "0.2.0"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
12
  s.require_paths = ["lib"]
13
- s.authors = ["Dave Perrett"]
14
- s.date = "2014-01-13"
13
+ s.authors = ["Dave Perrett", "Erik Frederiksen", "Kenneth Kalmer"]
14
+ s.date = "2017-08-10"
15
15
  s.description = "Pulls stories from Pivotal Tracker and imports them into Trello"
16
16
  s.email = "hello@daveperrett.com"
17
17
  s.executables = ["pivotal-to-trello"]
@@ -21,6 +21,8 @@ Gem::Specification.new do |s|
21
21
  ]
22
22
  s.files = [
23
23
  ".document",
24
+ ".rubocop.yml",
25
+ "Dockerfile",
24
26
  "Gemfile",
25
27
  "LICENSE.txt",
26
28
  "README.markdown",
@@ -40,34 +42,37 @@ Gem::Specification.new do |s|
40
42
  ]
41
43
  s.homepage = "http://github.com/recurser/pivotal-to-trello"
42
44
  s.licenses = ["MIT"]
43
- s.rubygems_version = "2.2.1"
45
+ s.rubygems_version = "2.4.5"
44
46
  s.summary = "Pivotal Tracker to Trello exporter"
45
47
 
46
48
  if s.respond_to? :specification_version then
47
49
  s.specification_version = 4
48
50
 
49
51
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
50
- s.add_runtime_dependency(%q<highline>, [">= 1.6.20"])
51
- s.add_runtime_dependency(%q<ruby-trello>, [">= 1.1.0"])
52
- s.add_runtime_dependency(%q<pivotal-tracker>, [">= 0.5.12"])
52
+ s.add_runtime_dependency(%q<highline>, ["~> 1.7.8"])
53
+ s.add_runtime_dependency(%q<ruby-trello>, ["~> 2.0.0"])
54
+ s.add_runtime_dependency(%q<pivotal-tracker>, ["~> 0.5.13"])
53
55
  s.add_development_dependency(%q<rspec>, [">= 2.14.1"])
54
56
  s.add_development_dependency(%q<rdoc>, [">= 4.1.1"])
55
- s.add_development_dependency(%q<jeweler>, [">= 2.0.0"])
57
+ s.add_development_dependency(%q<jeweler>, [">= 2.3.7"])
58
+ s.add_development_dependency(%q<rubocop>, [">= 0.49.1"])
56
59
  else
57
- s.add_dependency(%q<highline>, [">= 1.6.20"])
58
- s.add_dependency(%q<ruby-trello>, [">= 1.1.0"])
59
- s.add_dependency(%q<pivotal-tracker>, [">= 0.5.12"])
60
+ s.add_dependency(%q<highline>, ["~> 1.7.8"])
61
+ s.add_dependency(%q<ruby-trello>, ["~> 2.0.0"])
62
+ s.add_dependency(%q<pivotal-tracker>, ["~> 0.5.13"])
60
63
  s.add_dependency(%q<rspec>, [">= 2.14.1"])
61
64
  s.add_dependency(%q<rdoc>, [">= 4.1.1"])
62
- s.add_dependency(%q<jeweler>, [">= 2.0.0"])
65
+ s.add_dependency(%q<jeweler>, [">= 2.3.7"])
66
+ s.add_dependency(%q<rubocop>, [">= 0.49.1"])
63
67
  end
64
68
  else
65
- s.add_dependency(%q<highline>, [">= 1.6.20"])
66
- s.add_dependency(%q<ruby-trello>, [">= 1.1.0"])
67
- s.add_dependency(%q<pivotal-tracker>, [">= 0.5.12"])
69
+ s.add_dependency(%q<highline>, ["~> 1.7.8"])
70
+ s.add_dependency(%q<ruby-trello>, ["~> 2.0.0"])
71
+ s.add_dependency(%q<pivotal-tracker>, ["~> 0.5.13"])
68
72
  s.add_dependency(%q<rspec>, [">= 2.14.1"])
69
73
  s.add_dependency(%q<rdoc>, [">= 4.1.1"])
70
- s.add_dependency(%q<jeweler>, [">= 2.0.0"])
74
+ s.add_dependency(%q<jeweler>, [">= 2.3.7"])
75
+ s.add_dependency(%q<rubocop>, [">= 0.49.1"])
71
76
  end
72
77
  end
73
78
 
@@ -6,32 +6,32 @@ describe 'Core' do
6
6
  let(:trello) { mock_trello_wrapper }
7
7
 
8
8
  before(:each) do
9
- IO.any_instance.stub(:puts)
10
- core.stub(:pivotal => pivotal)
11
- core.stub(:trello => trello)
12
-
13
- core.stub(:prompt_selection).with('Which Pivotal project would you like to export?', pivotal.project_choices).and_return('pivotal_project_id')
14
- core.stub(:prompt_selection).with('Which Trello board would you like to import into?', trello.board_choices).and_return('trello_board_id')
15
- core.stub(:prompt_selection).with("Which Trello list would you like to put 'icebox' stories into?", trello.list_choices).and_return('icebox_list_id')
16
- core.stub(:prompt_selection).with("Which Trello list would you like to put 'current' stories into?", trello.list_choices).and_return('current_list_id')
17
- core.stub(:prompt_selection).with("Which Trello list would you like to put 'finished' stories into?", trello.list_choices).and_return('finished_list_id')
18
- core.stub(:prompt_selection).with("Which Trello list would you like to put 'delivered' stories into?", trello.list_choices).and_return('delivered_list_id')
19
- core.stub(:prompt_selection).with("Which Trello list would you like to put 'accepted' stories into?", trello.list_choices).and_return('accepted_list_id')
20
- core.stub(:prompt_selection).with("Which Trello list would you like to put 'rejected' stories into?", trello.list_choices).and_return('rejected_list_id')
21
- core.stub(:prompt_selection).with("Which Trello list would you like to put 'backlog' bugs into?", trello.list_choices).and_return('bug_list_id')
22
- core.stub(:prompt_selection).with("Which Trello list would you like to put 'backlog' chores into?", trello.list_choices).and_return('chore_list_id')
23
- core.stub(:prompt_selection).with("Which Trello list would you like to put 'backlog' features into?", trello.list_choices).and_return('feature_list_id')
24
- core.stub(:prompt_selection).with("Which Trello list would you like to put 'backlog' releases into?", trello.list_choices).and_return('release_list_id')
25
- core.stub(:prompt_selection).with('What color would you like to label bugs with?', trello.label_choices).and_return('bug_label')
26
- core.stub(:prompt_selection).with('What color would you like to label features with?', trello.label_choices).and_return('feature_label')
27
- core.stub(:prompt_selection).with('What color would you like to label chores with?', trello.label_choices).and_return('chore_label')
28
- core.stub(:prompt_selection).with('What color would you like to label releases with?', trello.label_choices).and_return('release_label')
9
+ allow_any_instance_of(IO).to receive(:puts)
10
+ allow(core).to receive_messages(pivotal: pivotal)
11
+ allow(core).to receive_messages(trello: trello)
12
+
13
+ allow(core).to receive(:prompt_selection).with('Which Pivotal project would you like to export?', pivotal.project_choices).and_return('pivotal_project_id')
14
+ allow(core).to receive(:prompt_selection).with('Which Trello board would you like to import into?', trello.board_choices).and_return('trello_board_id')
15
+ allow(core).to receive(:prompt_selection).with("Which Trello list would you like to put 'icebox' stories into?", trello.list_choices).and_return('icebox_list_id')
16
+ allow(core).to receive(:prompt_selection).with("Which Trello list would you like to put 'current' stories into?", trello.list_choices).and_return('current_list_id')
17
+ allow(core).to receive(:prompt_selection).with("Which Trello list would you like to put 'finished' stories into?", trello.list_choices).and_return('finished_list_id')
18
+ allow(core).to receive(:prompt_selection).with("Which Trello list would you like to put 'delivered' stories into?", trello.list_choices).and_return('delivered_list_id')
19
+ allow(core).to receive(:prompt_selection).with("Which Trello list would you like to put 'accepted' stories into?", trello.list_choices).and_return('accepted_list_id')
20
+ allow(core).to receive(:prompt_selection).with("Which Trello list would you like to put 'rejected' stories into?", trello.list_choices).and_return('rejected_list_id')
21
+ allow(core).to receive(:prompt_selection).with("Which Trello list would you like to put 'backlog' bugs into?", trello.list_choices).and_return('bug_list_id')
22
+ allow(core).to receive(:prompt_selection).with("Which Trello list would you like to put 'backlog' chores into?", trello.list_choices).and_return('chore_list_id')
23
+ allow(core).to receive(:prompt_selection).with("Which Trello list would you like to put 'backlog' features into?", trello.list_choices).and_return('feature_list_id')
24
+ allow(core).to receive(:prompt_selection).with("Which Trello list would you like to put 'backlog' releases into?", trello.list_choices).and_return('release_list_id')
25
+ allow(core).to receive(:prompt_selection).with('What color would you like to label bugs with?', trello.label_choices).and_return('bug_label')
26
+ allow(core).to receive(:prompt_selection).with('What color would you like to label features with?', trello.label_choices).and_return('feature_label')
27
+ allow(core).to receive(:prompt_selection).with('What color would you like to label chores with?', trello.label_choices).and_return('chore_label')
28
+ allow(core).to receive(:prompt_selection).with('What color would you like to label releases with?', trello.label_choices).and_return('release_label')
29
29
  end
30
30
 
31
31
  context '#import!' do
32
32
  it 'prompts the user for details' do
33
33
  core.import!
34
- core.options.should == mock_options
34
+ expect(core.options).to eq(mock_options)
35
35
  end
36
36
 
37
37
  describe 'story handling' do
@@ -39,68 +39,68 @@ describe 'Core' do
39
39
  let(:story) { mock_pivotal_story }
40
40
 
41
41
  before(:each) do
42
- pivotal.should_receive(:stories).and_return([story])
43
- trello.stub(:add_label => true, :create_card => card)
42
+ expect(pivotal).to receive(:stories).and_return([story])
43
+ allow(trello).to receive_messages(add_label: true, create_card: card)
44
44
  end
45
45
 
46
46
  it 'handles accepted stories' do
47
- story.stub(:current_state => 'accepted')
48
- trello.should_receive(:create_card).with(core.options.accepted_list_id, story).and_return(card)
47
+ allow(story).to receive_messages(current_state: 'accepted')
48
+ expect(trello).to receive(:create_card).with(core.options.accepted_list_id, story).and_return(card)
49
49
  core.import!
50
50
  end
51
51
 
52
52
  it 'handles rejected stories' do
53
- story.stub(:current_state => 'rejected')
54
- trello.should_receive(:create_card).with(core.options.rejected_list_id, story).and_return(card)
53
+ allow(story).to receive_messages(current_state: 'rejected')
54
+ expect(trello).to receive(:create_card).with(core.options.rejected_list_id, story).and_return(card)
55
55
  core.import!
56
56
  end
57
57
 
58
58
  it 'handles finished stories' do
59
- story.stub(:current_state => 'finished')
60
- trello.should_receive(:create_card).with(core.options.finished_list_id, story).and_return(card)
59
+ allow(story).to receive_messages(current_state: 'finished')
60
+ expect(trello).to receive(:create_card).with(core.options.finished_list_id, story).and_return(card)
61
61
  core.import!
62
62
  end
63
63
 
64
64
  it 'handles delivered stories' do
65
- story.stub(:current_state => 'delivered')
66
- trello.should_receive(:create_card).with(core.options.delivered_list_id, story).and_return(card)
65
+ allow(story).to receive_messages(current_state: 'delivered')
66
+ expect(trello).to receive(:create_card).with(core.options.delivered_list_id, story).and_return(card)
67
67
  core.import!
68
68
  end
69
69
 
70
70
  it 'handles unstarted features' do
71
- story.stub(:current_state => 'unstarted', :story_type => 'feature')
72
- trello.should_receive(:create_card).with(core.options.feature_list_id, story).and_return(card)
71
+ allow(story).to receive_messages(current_state: 'unstarted', story_type: 'feature')
72
+ expect(trello).to receive(:create_card).with(core.options.feature_list_id, story).and_return(card)
73
73
  core.import!
74
74
  end
75
75
 
76
76
  it 'handles unstarted chores' do
77
- story.stub(:current_state => 'unstarted', :story_type => 'chore')
78
- trello.should_receive(:create_card).with(core.options.chore_list_id, story).and_return(card)
77
+ allow(story).to receive_messages(current_state: 'unstarted', story_type: 'chore')
78
+ expect(trello).to receive(:create_card).with(core.options.chore_list_id, story).and_return(card)
79
79
  core.import!
80
80
  end
81
81
 
82
82
  it 'handles unstarted bugs' do
83
- story.stub(:current_state => 'unstarted', :story_type => 'bug')
84
- trello.should_receive(:create_card).with(core.options.bug_list_id, story).and_return(card)
83
+ allow(story).to receive_messages(current_state: 'unstarted', story_type: 'bug')
84
+ expect(trello).to receive(:create_card).with(core.options.bug_list_id, story).and_return(card)
85
85
  core.import!
86
86
  end
87
87
 
88
88
  it 'handles unstarted releases' do
89
- story.stub(:current_state => 'unstarted', :story_type => 'release')
90
- trello.should_receive(:create_card).with(core.options.release_list_id, story).and_return(card)
89
+ allow(story).to receive_messages(current_state: 'unstarted', story_type: 'release')
90
+ expect(trello).to receive(:create_card).with(core.options.release_list_id, story).and_return(card)
91
91
  core.import!
92
92
  end
93
93
 
94
94
  it 'labels stories' do
95
- story.stub(:story_type => 'bug')
96
- trello.should_receive(:add_label).with(card, core.options.bug_label)
95
+ allow(story).to receive_messages(story_type: 'bug')
96
+ expect(trello).to receive(:add_label).with(card, 'bug', core.options.bug_label)
97
97
  core.import!
98
98
  end
99
99
 
100
100
  it 'ignores nil labels' do
101
- core.options.stub(:bug_label => nil)
102
- story.stub(:story_type => 'bug')
103
- trello.should_not_receive(:add_label)
101
+ allow(core.options).to receive_messages(bug_label: nil)
102
+ allow(story).to receive_messages(story_type: 'bug')
103
+ expect(trello).not_to receive(:add_label)
104
104
  core.import!
105
105
  end
106
106
  end
@@ -5,26 +5,28 @@ describe 'PivotalWrapper' do
5
5
 
6
6
  context '#initialize' do
7
7
  it 'sets the pivotal token' do
8
- ::PivotalTracker::Client.should_receive(:token=).with('token')
8
+ expect(::PivotalTracker::Client).to receive(:token=).with('token')
9
9
  PivotalToTrello::PivotalWrapper.new('token')
10
10
  end
11
11
  end
12
12
 
13
13
  context '#project_choices' do
14
14
  it 'returns a hash of pivotal projects' do
15
- project = OpenStruct.new(:id => 'id', :name => 'My Project')
16
- ::PivotalTracker::Project.should_receive(:all).and_return([project])
17
- wrapper.project_choices.should == { 'id' => 'My Project'}
15
+ project = OpenStruct.new(id: 'id', name: 'My Project')
16
+ expect(::PivotalTracker::Project).to receive(:all).and_return([project])
17
+ expect(wrapper.project_choices).to eq('id' => 'My Project')
18
18
  end
19
19
  end
20
20
 
21
21
  context '#stories' do
22
- it 'returns an array of pivotal stories' do
23
- story = mock_pivotal_story
22
+ it 'returns a sorted array of pivotal stories' do
23
+ first_story = mock_pivotal_story(created_at: Time.now - 10_000)
24
+ last_story = mock_pivotal_story(created_at: Time.now + 10_000)
24
25
  project = double(PivotalTracker::Project)
25
- ::PivotalTracker::Project.should_receive(:find).with('project_id').and_return(project)
26
- project.stub_chain(:stories, :all).and_return([story])
27
- wrapper.stories('project_id').should == [story]
26
+ expect(::PivotalTracker::Project).to receive(:find).with('project_id').and_return(project)
27
+ allow(project).to receive_message_chain(:stories, :all).and_return([last_story, first_story])
28
+ expect(wrapper.stories('project_id').first).to eq(first_story)
29
+ expect(wrapper.stories('project_id').last).to eq(last_story)
28
30
  end
29
31
  end
30
- end
32
+ end
@@ -4,15 +4,15 @@ describe 'TrelloWrapper' do
4
4
  let(:wrapper) { PivotalToTrello::TrelloWrapper.new('key', 'token') }
5
5
 
6
6
  before(:each) do
7
- IO.any_instance.stub(:puts)
7
+ allow_any_instance_of(IO).to receive(:puts)
8
8
  end
9
9
 
10
10
  context '#initialize' do
11
11
  it 'sets the auth credentials' do
12
12
  config = double
13
- Trello.should_receive(:configure).and_yield(config)
14
- config.should_receive(:developer_public_key=).with('key')
15
- config.should_receive(:member_token=).with('token')
13
+ expect(Trello).to receive(:configure).and_yield(config)
14
+ expect(config).to receive(:developer_public_key=).with('key')
15
+ expect(config).to receive(:member_token=).with('token')
16
16
  PivotalToTrello::TrelloWrapper.new('key', 'token')
17
17
  end
18
18
  end
@@ -22,93 +22,115 @@ describe 'TrelloWrapper' do
22
22
 
23
23
  it 'creates a new card if none exists' do
24
24
  story = mock_pivotal_story
25
- wrapper.should_receive(:get_card).and_return(nil)
26
- Trello::Card.should_receive(:create).with(
27
- :name => story.name,
28
- :desc => story.description,
29
- :list_id => 'list_id'
25
+ expect(wrapper).to receive(:get_card).and_return(nil)
26
+ expect(Trello::Card).to receive(:create).with(
27
+ name: story.name,
28
+ desc: story.description,
29
+ list_id: 'list_id',
30
30
  ).and_return(card)
31
- wrapper.create_card('list_id', story).should == card
31
+ expect(wrapper.create_card('list_id', story)).to eq(card)
32
32
  end
33
33
 
34
34
  it 'does not create a new card if one exists with the same name' do
35
- story = mock_pivotal_story(:name => 'My Card')
36
- Trello::List.stub_chain(:find, :cards).and_return([card])
37
- Trello::Card.should_not_receive(:create)
38
- wrapper.create_card('list_id', story).should == card
35
+ story = mock_pivotal_story(name: 'My Card')
36
+ allow(Trello::List).to receive_message_chain(:find, :cards).and_return([card])
37
+ expect(Trello::Card).not_to receive(:create)
38
+ expect(wrapper.create_card('list_id', story)).to eq(card)
39
39
  end
40
40
 
41
41
  it 'creates a new card if one exists with a different name' do
42
- story = mock_pivotal_story(:name => 'My Foo')
43
- Trello::List.stub_chain(:find, :cards).and_return([card])
44
- Trello::Card.should_receive(:create).with(
45
- :name => story.name,
46
- :desc => story.description,
47
- :list_id => 'list_id'
42
+ story = mock_pivotal_story(name: 'My Foo')
43
+ allow(Trello::List).to receive_message_chain(:find, :cards).and_return([card])
44
+ expect(Trello::Card).to receive(:create).with(
45
+ name: story.name,
46
+ desc: story.description,
47
+ list_id: 'list_id',
48
48
  ).and_return(card)
49
- wrapper.create_card('list_id', story).should == card
49
+ expect(wrapper.create_card('list_id', story)).to eq(card)
50
50
  end
51
51
 
52
52
  it 'adds comments' do
53
- note = OpenStruct.new(:text => 'My Note', :author => 'John Smith')
53
+ note = OpenStruct.new(text: 'My Note', author: 'John Smith')
54
54
  story = mock_pivotal_story
55
- story.stub_chain(:notes, :all).and_return([note])
56
- wrapper.should_receive(:get_card).and_return(nil)
57
- Trello::Card.should_receive(:create).and_return(card)
58
- card.should_receive(:add_comment).with('[John Smith] My Note')
59
- wrapper.create_card('list_id', story).should == card
55
+ allow(story).to receive_message_chain(:notes, :all).and_return([note])
56
+ expect(wrapper).to receive(:get_card).and_return(nil)
57
+ expect(Trello::Card).to receive(:create).and_return(card)
58
+ expect(card).to receive(:add_comment).with('[John Smith] My Note')
59
+ expect(wrapper.create_card('list_id', story)).to eq(card)
60
+ end
61
+
62
+ it 'adds tasks' do
63
+ task = OpenStruct.new(description: 'My Task', complete: false)
64
+ story = mock_pivotal_story
65
+ checklist = double(Trello::Checklist)
66
+ allow(story).to receive_message_chain(:tasks, :all).and_return([task])
67
+ expect(wrapper).to receive(:get_card).and_return(nil)
68
+ expect(Trello::Card).to receive(:create).and_return(card)
69
+ expect(Trello::Checklist).to receive(:create).with(name: 'Tasks', card_id: card.id).and_return(checklist)
70
+ expect(card).to receive(:add_checklist).with(checklist)
71
+ expect(checklist).to receive(:add_item).with(task.description, task.complete)
72
+ expect(wrapper.create_card('list_id', story)).to eq(card)
60
73
  end
61
74
  end
62
75
 
63
76
  context '#board_choices' do
64
77
  it 'returns a hash of Trello boards' do
65
- board = OpenStruct.new(:id => 'id', :name => 'My Board')
66
- Trello::Board.should_receive(:all).and_return([board])
67
- wrapper.board_choices.should == { 'id' => 'My Board'}
78
+ board = OpenStruct.new(id: 'id', name: 'My Board')
79
+ expect(Trello::Board).to receive(:all).and_return([board])
80
+ expect(wrapper.board_choices).to eq('id' => 'My Board')
68
81
  end
69
82
  end
70
83
 
71
84
  context '#list_choices' do
72
85
  it 'returns a hash of Trello lists' do
73
86
  board = double(Trello::Board)
74
- list = OpenStruct.new(:id => 'id', :name => 'My List')
75
- Trello::Board.should_receive(:find).with('board_id').and_return(board)
76
- board.should_receive(:lists).and_return([list])
77
- wrapper.list_choices('board_id').should == {
78
- 'id' => 'My List',
79
- false => "[don't import these stories]",
80
- }
87
+ list = OpenStruct.new(id: 'id', name: 'My List')
88
+ expect(Trello::Board).to receive(:find).with('board_id').and_return(board)
89
+ expect(board).to receive(:lists).and_return([list])
90
+ expect(wrapper.list_choices('board_id')).to eq( 'id' => 'My List',
91
+ false => "[don't import these stories]")
81
92
  end
82
93
  end
83
94
 
84
95
  context '#cards_for_list' do
85
96
  it 'returns a hash of Trello lists' do
86
97
  list = double(Trello::List)
87
- card = OpenStruct.new(:name => 'My Card', :desc => 'My Description')
88
- Trello::List.should_receive(:find).with('list_id').and_return(list)
89
- list.should_receive(:cards).and_return([card])
90
- expected = {'193060beddd00d64259bdc1271d6c5a330e92e7d' => card}
91
- wrapper.cards_for_list('list_id').should == expected
98
+ card = OpenStruct.new(name: 'My Card', desc: 'My Description')
99
+ expect(Trello::List).to receive(:find).with('list_id').and_return(list)
100
+ expect(list).to receive(:cards).and_return([card])
101
+ expected = { '193060beddd00d64259bdc1271d6c5a330e92e7d' => card }
102
+ expect(wrapper.cards_for_list('list_id')).to eq(expected)
92
103
  # Test caching.
93
- Trello::List.should_not_receive(:find)
94
- wrapper.cards_for_list('list_id').should == expected
104
+ expect(Trello::List).not_to receive(:find)
105
+ expect(wrapper.cards_for_list('list_id')).to eq(expected)
95
106
  end
96
107
  end
97
108
 
98
109
  context '#add_label' do
110
+ let(:board) { double(Trello::Board) }
111
+
112
+ before do
113
+ expect(Trello::Board).to receive(:find).with('board_id').and_return(board)
114
+ allow(board).to receive(:labels).and_return([])
115
+ end
116
+
99
117
  it 'adds a label if it does not already exist' do
100
- card = mock_trello_card
101
- card.stub(:labels => [])
102
- card.should_receive(:add_label).with('red')
103
- wrapper.add_label(card, 'red')
118
+ label = double(Trello::Label)
119
+ card = mock_trello_card(board_id: 'board_id')
120
+ allow(card).to receive_messages(labels: [])
121
+ expect(Trello::Label).to receive(:create).with(name: 'bug', board_id: 'board_id', color: 'red').and_return(label)
122
+ expect(card).to receive(:add_label).with(label)
123
+ wrapper.add_label(card, 'bug', 'red')
104
124
  end
105
125
 
106
126
  it 'does not add a label if it already exists' do
107
- card = mock_trello_card
108
- card.stub(:labels => [OpenStruct.new(:color => 'red')])
109
- card.should_not_receive(:add_label)
110
- wrapper.add_label(card, 'red')
127
+ label = double(Trello::Label, id: '1234', name: 'bug', color: 'red')
128
+ card = mock_trello_card(board_id: 'board_id')
129
+ allow(board).to receive(:labels).and_return([label])
130
+ allow(card).to receive_messages(labels: [label])
131
+ expect(card).not_to receive(:add_label)
132
+ wrapper.add_label(card, 'bug', 'red')
111
133
  end
112
134
  end
113
135
 
114
- end
136
+ end