taskmapper-mingle 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+