taskmapper-bugzilla 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. data/.rbenv-gemsets +1 -0
  2. data/.rbenv-version +1 -0
  3. data/.rvmrc +1 -0
  4. data/.travis.yml +4 -0
  5. data/Gemfile +17 -0
  6. data/Gemfile.lock +56 -0
  7. data/LICENSE +22 -0
  8. data/README.md +80 -0
  9. data/Rakefile +41 -0
  10. data/VERSION +1 -0
  11. data/lib/provider/bugzilla.rb +46 -0
  12. data/lib/provider/comment.rb +69 -0
  13. data/lib/provider/project.rb +64 -0
  14. data/lib/provider/ticket.rb +118 -0
  15. data/lib/taskmapper-bugzilla.rb +35 -0
  16. data/spec/comments_spec.rb +32 -0
  17. data/spec/fixtures/vcr_cassettes/comments-all.yml +127 -0
  18. data/spec/fixtures/vcr_cassettes/comments-by-array.yml +124 -0
  19. data/spec/fixtures/vcr_cassettes/comments-by-id.yml +124 -0
  20. data/spec/fixtures/vcr_cassettes/create-a-ticket.yml +342 -0
  21. data/spec/fixtures/vcr_cassettes/init-tm-for-comments.yml +37 -0
  22. data/spec/fixtures/vcr_cassettes/load-all-projects.yml +256 -0
  23. data/spec/fixtures/vcr_cassettes/load-all-tickets.yml +271 -0
  24. data/spec/fixtures/vcr_cassettes/load-by-attributes.yml +271 -0
  25. data/spec/fixtures/vcr_cassettes/load-by-id.yml +89 -0
  26. data/spec/fixtures/vcr_cassettes/load-tickets-by-ids.yml +89 -0
  27. data/spec/fixtures/vcr_cassettes/loading-a-project.yml +38 -0
  28. data/spec/fixtures/vcr_cassettes/project-by-attributes.yml +256 -0
  29. data/spec/fixtures/vcr_cassettes/project-by-find-method.yml +42 -0
  30. data/spec/fixtures/vcr_cassettes/project-by-find-with-ids.yml +256 -0
  31. data/spec/fixtures/vcr_cassettes/project-for-comment.yml +38 -0
  32. data/spec/fixtures/vcr_cassettes/project-initialization.yml +37 -0
  33. data/spec/fixtures/vcr_cassettes/projects-by-id.yml +42 -0
  34. data/spec/fixtures/vcr_cassettes/projects-by-ids.yml +112 -0
  35. data/spec/fixtures/vcr_cassettes/taskmapper-instance.yml +37 -0
  36. data/spec/fixtures/vcr_cassettes/ticket-by-attribute.yml +35 -0
  37. data/spec/fixtures/vcr_cassettes/ticket-for-comment.yml +89 -0
  38. data/spec/fixtures/vcr_cassettes/ticketmaster-instance.yml +37 -0
  39. data/spec/fixtures/vcr_cassettes/tm-authentication.yml +37 -0
  40. data/spec/projects_spec.rb +40 -0
  41. data/spec/spec.opts +1 -0
  42. data/spec/spec_helper.rb +13 -0
  43. data/spec/taskmapper-bugzilla_spec.rb +18 -0
  44. data/spec/tickets_spec.rb +44 -0
  45. data/spec/vcr_setup.rb +7 -0
  46. data/taskmapper-bugzilla.gemspec +105 -0
  47. metadata +180 -0
data/.rbenv-gemsets ADDED
@@ -0,0 +1 @@
1
+ ticketmaster-bugzilla
data/.rbenv-version ADDED
@@ -0,0 +1 @@
1
+ 1.9.2-p290
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm 1.9.2@taskmapper-bugzilla --create
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.8.7
4
+ - 1.9.2
data/Gemfile ADDED
@@ -0,0 +1,17 @@
1
+ source "http://rubygems.org"
2
+ # Add dependencies required to use your gem here.
3
+ # Example:
4
+ # gem "activesupport", ">= 2.3.5"
5
+
6
+ gem "taskmapper", "~> 0.8"
7
+ gem "rubyzilla", "~> 0.1"
8
+ # Add dependencies to develop your gem here.
9
+ # Include everything needed to run rake, tests, features, etc.
10
+ group :development do
11
+ gem "rspec", "~> 2.8"
12
+ gem "fakeweb", "~> 1.3"
13
+ gem "vcr", "~> 1.11"
14
+ gem "jeweler", "~> 1.6"
15
+ gem "simplecov", "~> 0.5", :platforms => :ruby_19
16
+ gem "rcov", "~> 1.0", :platforms => :ruby_18
17
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,56 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ activemodel (3.2.3)
5
+ activesupport (= 3.2.3)
6
+ builder (~> 3.0.0)
7
+ activeresource (3.2.3)
8
+ activemodel (= 3.2.3)
9
+ activesupport (= 3.2.3)
10
+ activesupport (3.2.3)
11
+ i18n (~> 0.6)
12
+ multi_json (~> 1.0)
13
+ builder (3.0.0)
14
+ diff-lcs (1.1.3)
15
+ fakeweb (1.3.0)
16
+ git (1.2.5)
17
+ hashie (1.2.0)
18
+ i18n (0.6.0)
19
+ jeweler (1.6.4)
20
+ bundler (~> 1.0)
21
+ git (>= 1.2.5)
22
+ rake
23
+ multi_json (1.0.4)
24
+ rake (0.9.2.2)
25
+ rcov (1.0.0)
26
+ rspec (2.8.0)
27
+ rspec-core (~> 2.8.0)
28
+ rspec-expectations (~> 2.8.0)
29
+ rspec-mocks (~> 2.8.0)
30
+ rspec-core (2.8.0)
31
+ rspec-expectations (2.8.0)
32
+ diff-lcs (~> 1.1.2)
33
+ rspec-mocks (2.8.0)
34
+ rubyzilla (0.1.1)
35
+ simplecov (0.5.4)
36
+ multi_json (~> 1.0.3)
37
+ simplecov-html (~> 0.5.3)
38
+ simplecov-html (0.5.3)
39
+ taskmapper (0.8.0)
40
+ activeresource (~> 3.0)
41
+ activesupport (~> 3.0)
42
+ hashie (~> 1.2)
43
+ vcr (1.11.3)
44
+
45
+ PLATFORMS
46
+ ruby
47
+
48
+ DEPENDENCIES
49
+ fakeweb (~> 1.3)
50
+ jeweler (~> 1.6)
51
+ rcov (~> 1.0)
52
+ rspec (~> 2.8)
53
+ rubyzilla (~> 0.1)
54
+ simplecov (~> 0.5)
55
+ taskmapper (~> 0.8)
56
+ vcr (~> 1.11)
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2010 YOU
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ NONE
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,80 @@
1
+ # taskmapper-bugzilla
2
+
3
+ This is a provider for [taskmapper](http://ticketrb.com). It provides interoperability with [Bugzilla](http://bugzilla.org) and it's issue tracking system through the taskmapper gem.
4
+
5
+ # Usage and Examples
6
+
7
+ First we have to instantiate a new taskmapper instance, your bugzilla installation should have api access enable:
8
+ bugzilla = TaskMapper.new(:bugzilla, {:username=> 'foo', :password => "bar", :url => "https://bugzilla.mozilla.org"})
9
+
10
+ If you do not pass in the url, username and password, you won't get any information.
11
+
12
+ ## Finding Projects(Products)
13
+
14
+ projects = taskmapper.projects # All projects
15
+ projects = taskmapper.projects([1,2,3]) # A list of projects based on id
16
+ project = taskmapper.project(1) # Single project
17
+ project = taskmapper.project(:id => 1) # Single project based on attributes
18
+
19
+ ## Finding Tickets(Bugs)
20
+
21
+ tickets = project.tickets # All tickets
22
+ tickets = project.tickets([1,2,3]) # List of tickets based on id's
23
+ ticket = project.ticket(1) # Single ticket by id
24
+
25
+ ## Open Tickets
26
+
27
+ ticket = project.ticket!({:summary => "New ticket", :description=> "Body for the very new ticket", :component => "Canvas", :op_sys =>"Linux", :platform => "x86", ... }) # You can add all the attributes for a valid ticket, but the one in th example are the mandatory ones. Here is the list of valid attributes
28
+ product_id
29
+ id
30
+ component_id
31
+ summary
32
+ title
33
+ version
34
+ op_sys
35
+ platform
36
+ priority
37
+ description
38
+ alias
39
+ qa_contact
40
+ assignee
41
+ status
42
+ target_milestone
43
+ severity
44
+
45
+ ## Finding comments
46
+
47
+ comments = project.tickets.first.comments # All the tickets facility for searchs are available for comments as well
48
+ comments = project.ticket(1).comments([1,2,3]) # List of comments based on id's
49
+
50
+
51
+ ## Requirements
52
+
53
+ * rubygems (obviously)
54
+ * taskmapper gem (latest version preferred)
55
+ * jeweler gem (only if you want to repackage and develop)
56
+ * guitsaru-rubyzilla
57
+
58
+ The taskmapper gem should automatically be installed during the installation of this gem if it is not already installed.
59
+
60
+ ## Other Notes
61
+
62
+ Since this and the taskmapper gem is still primarily a work-in-progress, minor changes may be incompatible with previous versions. Please be careful about using and updating this gem in production.
63
+
64
+ If you see or find any issues, feel free to open up an issue report.
65
+
66
+
67
+ ## Note on Patches/Pull Requests
68
+
69
+ * Fork the project.
70
+ * Make your feature addition or bug fix.
71
+ * Add tests for it. This is important so we don't break it in a
72
+ future version unintentionally.
73
+ * Commit, do not mess with rakefile, version, or history.
74
+ (if you want to have your own version, that is fine but bump version in a commit by itself so we can ignore when I pull)
75
+ * Send us a pull request. Bonus points for topic branches.
76
+
77
+ ## Copyright
78
+
79
+ Copyright (c) 2010 The Hybrid Group. See LICENSE for details.
80
+
data/Rakefile ADDED
@@ -0,0 +1,41 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "taskmapper-bugzilla"
8
+ gem.summary = %Q{TaskMapper Provider for Bugzilla}
9
+ gem.description = %Q{Allows taskmapper to interact with Bugzilla.}
10
+ gem.email = "rafael@hybridgroup.com"
11
+ gem.homepage = "http://github.com/hybridgroup/taskmapper-bugzilla"
12
+ gem.authors = ["Rafael George"]
13
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
14
+ end
15
+ Jeweler::GemcutterTasks.new
16
+ rescue LoadError
17
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
18
+ end
19
+
20
+ require 'rspec/core'
21
+ require 'rspec/core/rake_task'
22
+ RSpec::Core::RakeTask.new(:spec) do |spec|
23
+ spec.pattern = FileList['spec/**/*_spec.rb']
24
+ end
25
+
26
+ RSpec::Core::RakeTask.new(:rcov) do |spec|
27
+ spec.pattern = 'spec/**/*_spec.rb'
28
+ spec.rcov = true
29
+ end
30
+
31
+ task :default => :spec
32
+
33
+ require 'rake/rdoctask'
34
+ Rake::RDocTask.new do |rdoc|
35
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
36
+
37
+ rdoc.rdoc_dir = 'rdoc'
38
+ rdoc.title = "taskmapper-redmine#{version}"
39
+ rdoc.rdoc_files.include('README*')
40
+ rdoc.rdoc_files.include('lib/**/*.rb')
41
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.3.0
@@ -0,0 +1,46 @@
1
+ require 'taskmapper'
2
+
3
+ module TaskMapper::Provider
4
+ # This is the Yoursystem Provider for taskmapper
5
+ module Bugzilla
6
+ include TaskMapper::Provider::Base
7
+ PROJECT_API = Rubyzilla::Product
8
+
9
+ # This is for cases when you want to instantiate using TaskMapper::Provider::Yoursystem.new(auth)
10
+ def self.new(auth = {})
11
+ TaskMapper.new(:bugzilla, auth)
12
+ end
13
+
14
+ # declare needed overloaded methods here
15
+ def authorize(auth = {})
16
+ @authentication ||= TaskMapper::Authenticator.new(auth)
17
+ auth = @authentication
18
+ if (auth.username.nil? || auth.url.nil? || auth.password.nil?)
19
+ raise "Please provide username, password and url"
20
+ end
21
+ url = auth.url.gsub(/\/$/,'')
22
+ unless url.split('/').last == 'xmlrpc.cgi'
23
+ auth.url = url+'/xmlrpc.cgi'
24
+ end
25
+ @bugzilla = Rubyzilla::Bugzilla.new(auth.url)
26
+ begin
27
+ @bugzilla.login(auth.username,auth.password)
28
+ rescue
29
+ warn 'Authentication was invalid'
30
+ end
31
+ end
32
+
33
+ def valid?
34
+ Rubyzilla::Bugzilla.logged_in?
35
+ end
36
+
37
+ def project(*options)
38
+ unless options.empty?
39
+ Project.find(options.first)
40
+ else
41
+ super
42
+ end
43
+ end
44
+
45
+ end
46
+ end
@@ -0,0 +1,69 @@
1
+ module TaskMapper::Provider
2
+ module Bugzilla
3
+ # The comment class for taskmapper-bugzilla
4
+ #
5
+ # Do any mapping between TaskMapper and your system's comment model here
6
+ # versions of the ticket.
7
+ #
8
+ COMMENT_API = Rubyzilla::Bug
9
+ class Comment < TaskMapper::Provider::Base::Comment
10
+ # declare needed overloaded methods here
11
+ def initialize(*object)
12
+ if object.first
13
+ object = object.first
14
+ unless object.is_a? Hash
15
+ @system_data = {:client => object}
16
+ hash = {:id => object.id,
17
+ :ticket_id => object.bug_id,
18
+ :body => object.text,
19
+ :author => object.creator,
20
+ :created_at => object.time,
21
+ :updated_at => object.time}
22
+
23
+ else
24
+ hash = object
25
+ end
26
+ super hash
27
+ end
28
+ end
29
+
30
+ def body
31
+ self[:text]
32
+ end
33
+
34
+ def created_at
35
+ begin
36
+ normalize_datetime(self[:time])
37
+ rescue
38
+ self[:created_at]
39
+ end
40
+ end
41
+
42
+ def updated_at
43
+ begin
44
+ normalize_datetime(self[:time])
45
+ rescue
46
+ self[:updated_at]
47
+ end
48
+ end
49
+
50
+ def self.find_by_id(ticket_id, id)
51
+ self.new COMMENT_API.new(ticket_id).comments(:comment_ids => [id]).first
52
+ end
53
+
54
+ def self.find(ticket_id, *options)
55
+ if options.first.empty?
56
+ COMMENT_API.new(ticket_id).comments.collect { |comment| self.new comment }
57
+ elsif options[0].first.is_a? Array
58
+ COMMENT_API.new(ticket_id).comments(:comment_ids => options[0].first).collect { |comment| self.new comment }
59
+ end
60
+ end
61
+
62
+ private
63
+ def normalize_datetime(datetime)
64
+ Time.mktime(datetime.year, datetime.month, datetime.day, datetime.hour, datetime.min, datetime.sec)
65
+ end
66
+
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,64 @@
1
+ module TaskMapper::Provider
2
+ module Bugzilla
3
+ # Project class for taskmapper-bugzilla
4
+ #
5
+ class Project < TaskMapper::Provider::Base::Project
6
+ # declare needed overloaded methods here
7
+ PRODUCT_API = Rubyzilla::Product
8
+
9
+ # TODO: Add created_at and updated_at
10
+ def initialize(*object)
11
+ if object.first
12
+ object = object.first
13
+ unless object.is_a? Hash
14
+ @system_data = {:client => object}
15
+ hash = {:id => object.id,
16
+ :name => object.name,
17
+ :description => object.name,
18
+ :created_at => nil,
19
+ :updated_at => nil}
20
+ else
21
+ hash = object
22
+ end
23
+ super(hash)
24
+ end
25
+ end
26
+
27
+ # copy from this.copy(that) copies that into this
28
+ def copy(project)
29
+ project.tickets.each do |ticket|
30
+ copy_ticket = self.ticket!(:title => ticket.title, :description => ticket.description)
31
+ ticket.comments.each do |comment|
32
+ copy_ticket.comment!(:body => comment.body)
33
+ sleep 1
34
+ end
35
+ end
36
+ end
37
+
38
+ def self.find_by_id(id)
39
+ self.new PRODUCT_API.new id
40
+ end
41
+
42
+ def self.find_by_attributes(attributes = {})
43
+ search_by_attribute(self.find_all, attributes)
44
+ end
45
+
46
+ def self.find_all(*options)
47
+ PRODUCT_API.list.collect { |product| self.new product }
48
+ end
49
+
50
+ def tickets(*options)
51
+ TaskMapper::Provider::Bugzilla::Ticket.find(self.id, options)
52
+ end
53
+
54
+ def ticket(*options)
55
+ TaskMapper::Provider::Bugzilla::Ticket.find_by_id(options.first)
56
+ end
57
+
58
+ def ticket!(*options)
59
+ TaskMapper::Provider::Bugzilla::Ticket.create(self.id,*options)
60
+ end
61
+
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,118 @@
1
+ module TaskMapper::Provider
2
+ module Bugzilla
3
+ # Ticket class for taskmapper-bugzilla
4
+ #
5
+
6
+ class Ticket < TaskMapper::Provider::Base::Ticket
7
+ # declare needed overloaded methods here
8
+ TICKETS_API = Rubyzilla::Product
9
+ def initialize(*object)
10
+ return super(object.first) if object.first.is_a? Hash
11
+ if object.first
12
+ object = object.first
13
+ unless object.is_a? Hash
14
+ @system_data = {:client => object}
15
+ hash = {:product_id => object.product_id,
16
+ :id => object.id,
17
+ :project_id => object.product_id,
18
+ :component_id => object.component_id,
19
+ :summary => object.summary,
20
+ :title => object.summary,
21
+ :version => object.version,
22
+ :op_sys => object.op_sys,
23
+ :platform => object.platform,
24
+ :priority => object.priority,
25
+ :description => object.description,
26
+ :alias => object.alias,
27
+ :qa_contact => object.qa_contact,
28
+ :assignee => object.assigned_to,
29
+ :requestor => object.qa_contact,
30
+ :status => object.status,
31
+ :target_milestone => object.target_milestone,
32
+ :severity => object.severity,
33
+ :created_at => nil,
34
+ :updated_at => nil}
35
+ else
36
+ hash = object
37
+ end
38
+ super hash
39
+ end
40
+ end
41
+
42
+ def title
43
+ self[:summary]
44
+ end
45
+
46
+ def description
47
+ self[:description]
48
+ end
49
+
50
+ def requestor
51
+ self[:requestor]
52
+ end
53
+
54
+ def assignee
55
+ self[:assignee]
56
+ end
57
+
58
+ def created_at
59
+ begin
60
+ normalize_datetime(self[:last_change_time])
61
+ rescue
62
+ self[:created_at]
63
+ end
64
+ end
65
+
66
+ def updated_at
67
+ begin
68
+ normalize_datetime(self[:last_change_time])
69
+ rescue
70
+ self[:updated_at]
71
+ end
72
+ end
73
+
74
+ def self.find_by_id(id)
75
+ bug = Rubyzilla::Bug.new id
76
+ self.new bug
77
+ end
78
+
79
+ def self.find(project_id, *options)
80
+ if options.first.empty?
81
+ TICKETS_API.new(project_id).bugs.collect { |bug| self.new bug }
82
+ elsif options[0].first.is_a? Array
83
+ options[0].first.collect { |bug_id| self.find_by_id bug_id }
84
+ elsif options[0].first.is_a? Hash
85
+ bugs = TICKETS_API.new(project_id).bugs.collect { |bug| self.new bug }
86
+ search_by_attribute(bugs, options[0].first)
87
+ end
88
+ end
89
+
90
+ def self.create(project_id, *options)
91
+ begin
92
+ bug = Rubyzilla::Bug.new
93
+ bug.product = TICKETS_API.new project_id
94
+ options.first.each_pair do |k, v|
95
+ bug.send "#{k}=", v
96
+ end
97
+ self.new bug.create
98
+ rescue
99
+ self.find(project_id, []).last
100
+ end
101
+ end
102
+
103
+ def comments(*options)
104
+ Comment.find(self.id, options)
105
+ end
106
+
107
+ def comment(*options)
108
+ Comment.find_by_id(self.id, options.first)
109
+ end
110
+
111
+ private
112
+ def normalize_datetime(datetime)
113
+ Time.mktime(datetime.year, datetime.month, datetime.day, datetime.hour, datetime.min, datetime.sec)
114
+ end
115
+
116
+ end
117
+ end
118
+ end