taskmapper-bugzilla 0.3.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.
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