taskmapper-mingle 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.
@@ -0,0 +1,38 @@
1
+ module TaskMapper::Provider
2
+ # This is the Mingle Provider for taskmapper
3
+ module Mingle
4
+ include TaskMapper::Provider::Base
5
+ TICKET_API = MingleAPI::Card # The class to access the api's cards
6
+ PROJECT_API = MingleAPI::Project # The class to access the api's projects
7
+
8
+ # This is for cases when you want to instantiate using TaskMapper::Provider::Mingle.new(auth)
9
+ def self.new(auth = {})
10
+ TaskMapper.new(:mingle, auth)
11
+ end
12
+
13
+ # Providers must define an authorize method. This is used to initialize and set authentication
14
+ # parameters to access the API
15
+
16
+ def authorize(auth = {})
17
+ @authentication ||= TaskMapper::Authenticator.new(auth)
18
+ auth = @authentication
19
+ if auth.server.blank? and auth.login.blank? and auth.password.blank?
20
+ raise "Please provide server, login and password"
21
+ end
22
+ MingleAPI::Base.format = :xml
23
+ MingleAPI.authenticate(auth.server, auth.login, auth.password)
24
+ end
25
+ # declare needed overloaded methods here
26
+ def valid?
27
+ begin
28
+ PROJECT_API.find(:first)
29
+ true
30
+ rescue
31
+ false
32
+ end
33
+ end
34
+
35
+ end
36
+ end
37
+
38
+
@@ -0,0 +1,62 @@
1
+ module TaskMapper::Provider
2
+ module Mingle
3
+ # Project class for taskmapper-mingle
4
+ #
5
+ #
6
+ class Project < TaskMapper::Provider::Base::Project
7
+ API = MingleAPI::Project # The class to access the api's projects
8
+ # declare needed overloaded methods here
9
+
10
+ def id
11
+ self[:identifier]
12
+ end
13
+
14
+ def initialize(*options)
15
+ @system_data ||= {}
16
+ @cache ||= {}
17
+ first = options.first
18
+ case first
19
+ when Hash
20
+ super first.to_hash
21
+ else
22
+ @system_data[:client] = first
23
+ super first.attributes
24
+ end
25
+ end
26
+
27
+ def tickets(*options)
28
+ begin
29
+ if options.first.is_a? Hash
30
+ #options[0].merge!(:params => {:id => id})
31
+ super(*options)
32
+ elsif options.empty?
33
+ tickets = MingleAPI::Card.find(:all, :params => {:identifier => id}).collect { |ticket| TaskMapper::Provider::Mingle::Ticket.new ticket }
34
+ else
35
+ super(*options)
36
+ end
37
+ rescue
38
+ []
39
+ end
40
+ end
41
+
42
+ def ticket!(*options)
43
+ options[0].merge!(:identifier => id) if options.first.is_a?(Hash)
44
+ provider_parent(self.class)::Ticket.create(*options)
45
+ end
46
+
47
+ # copy from this.copy(that) copies that into this
48
+ def copy(project)
49
+ project.tickets.each do |ticket|
50
+ copy_ticket = self.ticket!(:name => ticket.title, :description => ticket.description)
51
+ ticket.comments.each do |comment|
52
+ copy_ticket.comment!(:content => comment.body)
53
+ sleep 1
54
+ end
55
+ end
56
+ end
57
+
58
+ end
59
+ end
60
+ end
61
+
62
+
@@ -0,0 +1,102 @@
1
+ module TaskMapper::Provider
2
+ module Mingle
3
+ # Ticket class for taskmapper-mingle
4
+ #
5
+ API = MingleAPI::Card
6
+
7
+ class Ticket < TaskMapper::Provider::Base::Ticket
8
+ # declare needed overloaded methods herea
9
+
10
+ def initialize(*object)
11
+ if object.first
12
+ args = object
13
+ object = args.shift
14
+ identifier = args.shift
15
+ @system_data = {:client => object}
16
+ unless object.is_a? Hash
17
+ hash = {:number => object.number,
18
+ :name => object.name,
19
+ :description => object.description,
20
+ :card_type_name => object.card_type.nil? ? "Card" : object.card_type.name,
21
+ :identifier => identifier,
22
+ :created_on => object.created_on,
23
+ :modified_on => object.modified_on,
24
+ :properties => object.properties}
25
+ else
26
+ hash = object
27
+ end
28
+ super hash
29
+ end
30
+ end
31
+
32
+ def self.create(*options)
33
+ card = API.new(*options)
34
+ ticket = self.new card
35
+ card.save
36
+ ticket
37
+ end
38
+
39
+ def self.find_by_id(identifier, number)
40
+ self.search(identifier, {'number' => number}).first
41
+ end
42
+
43
+ def self.search(identifier, options = {}, limit = 1000)
44
+ tickets = API.find(:all, :params => {:identifier => identifier}).collect { |ticket| self.new ticket, identifier }
45
+ search_by_attribute(tickets, options, limit)
46
+ end
47
+
48
+ def self.find_by_attributes(identifier, attributes = {})
49
+ self.search(identifier, attributes)
50
+ end
51
+
52
+ def number
53
+ self[:number].to_i
54
+ end
55
+
56
+ def id
57
+ self[:id].to_i
58
+ end
59
+
60
+ def name
61
+ self[:name]
62
+ end
63
+
64
+ def identifier
65
+ self[:identifier]
66
+ end
67
+
68
+ def title
69
+ self[:name]
70
+ end
71
+
72
+ def description
73
+ self[:description]
74
+ end
75
+
76
+ def status
77
+ self.properties[1].value
78
+ end
79
+
80
+ def comments(*options)
81
+ begin
82
+ if options.empty?
83
+ comments = MingleAPI::Comment.find(:all, :params => {:identifier => identifier, :number => number}).collect { |comment| TaskMapper::Provider::Mingle::Comment.new comment }
84
+ else
85
+ super(*options)
86
+ end
87
+ rescue
88
+ []
89
+ end
90
+ end
91
+
92
+ #def comment(*options)
93
+
94
+ def comment!(*options)
95
+ options[0].update(:identifier => identifier, :number => number) if options.first.is_a?(Hash)
96
+ Comment.create(*options)
97
+ end
98
+
99
+ end
100
+
101
+ end
102
+ end
@@ -0,0 +1,5 @@
1
+ require File.dirname(__FILE__) + '/mingle/mingle-api'
2
+
3
+ %w{ mingle ticket project comment }.each do |f|
4
+ require File.dirname(__FILE__) + '/provider/' + f + '.rb';
5
+ end
@@ -0,0 +1,40 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "TaskMapper::Provider::Mingle::Comment" do
4
+ before(:all) do
5
+ headers = {'Authorization' => 'Basic MDAwMDAwOg==', 'Accept' => 'application/xml'}
6
+ headers_post = {'Authorization' => 'Basic MDAwMDAwOg==', 'Content-Type' => 'application/xml'}
7
+ ActiveResource::HttpMock.respond_to do |mock|
8
+ mock.get '/api/v2/projects/test_project.xml', headers, fixture_for('projects/test_project'), 200
9
+ mock.get '/api/v2/projects/test_project/cards.xml', headers, fixture_for('cards'), 200
10
+ mock.get '/api/v2/projects/test_project/cards/42.xml', headers, fixture_for('cards/42'), 200
11
+ mock.get '/api/v2/projects/test_project/cards/42/comments.xml', headers, fixture_for('comments'), 200
12
+ mock.post '/api/v2/projects/test_project/cards/42/comments.xml?comment[content]=New%20comment%20created.', headers_post, fixture_for('comments/create'), 200
13
+ end
14
+ @identifier = 'test_project'
15
+ @number = 42
16
+ end
17
+
18
+ before(:each) do
19
+ @taskmapper = TaskMapper.new(:mingle, {:name => 'anymoto', :login => '000000', :server => 'localhost:8080'})
20
+ @project = @taskmapper.project(@identifier)
21
+ @ticket = @project.ticket(@number)
22
+ @ticket.identifier = @project.identifier
23
+ @klass = TaskMapper::Provider::Mingle::Comment
24
+ end
25
+
26
+ it "should be able to load all comments" do
27
+ @comments = @ticket.comments
28
+ @comments.should be_an_instance_of(Array)
29
+ @comments.first.should be_an_instance_of(@klass)
30
+ end
31
+
32
+ it "should return the class" do
33
+ @ticket.comment.should == @klass
34
+ end
35
+
36
+ it "should be able to create a comment" do
37
+ @comment = @ticket.comment!(:content => 'New comment created.')
38
+ @comment.should be_an_instance_of(@klass)
39
+ end
40
+ end
@@ -0,0 +1,83 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <cards type="array">
3
+ <card>
4
+ <name>Ticket 1</name>
5
+ <description>
6
+ </description>
7
+ <card_type>
8
+ <name>Story</name>
9
+ </card_type>
10
+ <id type="integer">409</id>
11
+ <number type="integer">42</number>
12
+ <project url="http://myserver.com/api/v2/projects/test_project.xml">
13
+ <name>test project</name>
14
+ <identifier>test_project</identifier>
15
+ </project>
16
+ <version type="integer">1</version>
17
+ <project_card_rank type="integer">1</project_card_rank>
18
+ <created_on type="datetime">2009-10-14T09:14:54Z</created_on>
19
+ <modified_on type="datetime">2009-10-14T09:14:54Z</modified_on>
20
+ <modified_by url="http://myserver.com/api/v2/users/1.xml">
21
+ <name>anne</name>
22
+ <login>anne</login>
23
+ </modified_by>
24
+ <created_by url="http://myserver.com/api/v2/users/2.xml">
25
+ <name>jane</name>
26
+ <login>jane</login>
27
+ </created_by>
28
+ <properties type="array">
29
+ <property type_description="Managed text list" hidden="false">
30
+ <name>Status</name>
31
+ <value>Closed</value>
32
+ </property>
33
+ <property type_description="Managed number list" hidden="false">
34
+ <name>Estimate</name>
35
+ <value>4</value>
36
+ </property>
37
+ <property type_description="Managed text list" hidden="false">
38
+ <name>Priority</name>
39
+ <value nil="true"/>
40
+ </property>
41
+ </properties>
42
+ </card>
43
+ <card>
44
+ <name>Automatically update event status when event date has passed</name>
45
+ <description>
46
+ </description>
47
+ <card_type>
48
+ <name>Story</name>
49
+ </card_type>
50
+ <id type="integer">410</id>
51
+ <number type="integer">43</number>
52
+ <project url="http://myserver.com/api/v2/projects/test_project.xml">
53
+ <name>test project</name>
54
+ <identifier>test_project</identifier>
55
+ </project>
56
+ <version type="integer">1</version>
57
+ <project_card_rank type="integer">1</project_card_rank>
58
+ <created_on type="datetime">2009-10-14T09:14:54Z</created_on>
59
+ <modified_on type="datetime">2009-10-14T09:14:54Z</modified_on>
60
+ <modified_by url="http://myserver.com/api/v2/users/1.xml">
61
+ <name>anne</name>
62
+ <login>anne</login>
63
+ </modified_by>
64
+ <created_by url="http://myserver.com/api/v2/users/2.xml">
65
+ <name>jane</name>
66
+ <login>jane</login>
67
+ </created_by>
68
+ <properties type="array">
69
+ <property type_description="Managed text list" hidden="false">
70
+ <name>Status</name>
71
+ <value>Closed</value>
72
+ </property>
73
+ <property type_description="Managed number list" hidden="false">
74
+ <name>Estimate</name>
75
+ <value>4</value>
76
+ </property>
77
+ <property type_description="Managed text list" hidden="false">
78
+ <name>Priority</name>
79
+ <value nil="true"/>
80
+ </property>
81
+ </properties>
82
+ </card>
83
+ </cards>
@@ -0,0 +1,41 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <card>
3
+ <name>As an API user, I would like to lookup a card in Mingle, given that I know the card number.</name>
4
+ <description>
5
+ </description>
6
+ <card_type>
7
+ <name>Story</name>
8
+ </card_type>
9
+ <number type="integer">42</number>
10
+ <project url="http://myserver.com/api/v2/projects/test_project.xml">
11
+ <name>test project</name>
12
+ <identifier>test_project</identifier>
13
+ </project>
14
+ <version type="integer">1</version>
15
+ <project_card_rank type="integer">1</project_card_rank>
16
+ <created_on type="datetime">2009-10-14T09:14:54Z</created_on>
17
+ <modified_on type="datetime">2009-10-14T09:14:54Z</modified_on>
18
+ <modified_by url="http://myserver.com/api/v2/users/1.xml">
19
+ <name>anne</name>
20
+ <login>anne</login>
21
+ </modified_by>
22
+ <created_by url="http://myserver.com/api/v2/users/2.xml">
23
+ <name>jane</name>
24
+ <login>jane</login>
25
+ </created_by>
26
+ <properties type="array">
27
+ <property type_description="Managed text list" hidden="false">
28
+ <name>Status</name>
29
+ <value>Closed</value>
30
+ </property>
31
+ <property type_description="Managed number list" hidden="false">
32
+ <name>Estimate</name>
33
+ <value>4</value>
34
+ </property>
35
+ <property type_description="Managed text list" hidden="false">
36
+ <name>Priority</name>
37
+ <value nil="true"/>
38
+ </property>
39
+ </properties>
40
+ </card>
41
+
@@ -0,0 +1,42 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <card>
3
+ <name>Automatically update event status when event date has passed</name>
4
+ <description>
5
+ </description>
6
+ <card_type>
7
+ <name>Story</name>
8
+ </card_type>
9
+ <id type="integer">410</id>
10
+ <number type="integer">43</number>
11
+ <project url="http://localhost:8080/api/v2/projects/test_project.xml">
12
+ <name>test project</name>
13
+ <identifier>test_project</identifier>
14
+ </project>
15
+ <version type="integer">1</version>
16
+ <project_card_rank type="integer">1</project_card_rank>
17
+ <created_on type="datetime">2009-10-14T09:14:54Z</created_on>
18
+ <modified_on type="datetime">2009-10-14T09:14:54Z</modified_on>
19
+ <modified_by url="http://localhost:8080/api/v2/users/1.xml">
20
+ <name>anne</name>
21
+ <login>anne</login>
22
+ </modified_by>
23
+ <created_by url="http://localhost:8080/api/v2/users/2.xml">
24
+ <name>jane</name>
25
+ <login>jane</login>
26
+ </created_by>
27
+ <properties type="array">
28
+ <property type_description="Managed text list" hidden="false">
29
+ <name>Status</name>
30
+ <value>Closed</value>
31
+ </property>
32
+ <property type_description="Managed number list" hidden="false">
33
+ <name>Estimate</name>
34
+ <value>4</value>
35
+ </property>
36
+ <property type_description="Managed text list" hidden="false">
37
+ <name>Priority</name>
38
+ <value nil="true"/>
39
+ </property>
40
+ </properties>
41
+ </card>
42
+
@@ -0,0 +1,42 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <card>
3
+ <name>Show event details in event list</name>
4
+ <description>
5
+ </description>
6
+ <card_type>
7
+ <name>Story</name>
8
+ </card_type>
9
+ <id type="integer">411</id>
10
+ <number type="integer">44</number>
11
+ <project url="http://localhost:8080/api/v2/projects/test_project.xml">
12
+ <name>test project</name>
13
+ <identifier>test_project</identifier>
14
+ </project>
15
+ <version type="integer">1</version>
16
+ <project_card_rank type="integer">1</project_card_rank>
17
+ <created_on type="datetime">2009-10-14T09:14:54Z</created_on>
18
+ <modified_on type="datetime">2009-10-14T09:14:54Z</modified_on>
19
+ <modified_by url="http://localhost:8080/api/v2/users/1.xml">
20
+ <name>anne</name>
21
+ <login>anne</login>
22
+ </modified_by>
23
+ <created_by url="http://localhost:8080/api/v2/users/2.xml">
24
+ <name>jane</name>
25
+ <login>jane</login>
26
+ </created_by>
27
+ <properties type="array">
28
+ <property type_description="Managed text list" hidden="false">
29
+ <name>Status</name>
30
+ <value>Closed</value>
31
+ </property>
32
+ <property type_description="Managed number list" hidden="false">
33
+ <name>Estimate</name>
34
+ <value>4</value>
35
+ </property>
36
+ <property type_description="Managed text list" hidden="false">
37
+ <name>Priority</name>
38
+ <value nil="true"/>
39
+ </property>
40
+ </properties>
41
+ </card>
42
+