alm-rest-api 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,22 @@
1
+ # Auto detect text files and perform LF normalization
2
+ * text=auto
3
+
4
+ # Custom for Visual Studio
5
+ *.cs diff=csharp
6
+ *.sln merge=union
7
+ *.csproj merge=union
8
+ *.vbproj merge=union
9
+ *.fsproj merge=union
10
+ *.dbproj merge=union
11
+
12
+ # Standard to msysgit
13
+ *.doc diff=astextplain
14
+ *.DOC diff=astextplain
15
+ *.docx diff=astextplain
16
+ *.DOCX diff=astextplain
17
+ *.dot diff=astextplain
18
+ *.DOT diff=astextplain
19
+ *.pdf diff=astextplain
20
+ *.PDF diff=astextplain
21
+ *.rtf diff=astextplain
22
+ *.RTF diff=astextplain
@@ -0,0 +1,163 @@
1
+ #################
2
+ ## Eclipse
3
+ #################
4
+
5
+ *.pydevproject
6
+ .project
7
+ .metadata
8
+ bin/
9
+ tmp/
10
+ *.tmp
11
+ *.bak
12
+ *.swp
13
+ *~.nib
14
+ local.properties
15
+ .classpath
16
+ .settings/
17
+ .loadpath
18
+
19
+ # External tool builders
20
+ .externalToolBuilders/
21
+
22
+ # Locally stored "Eclipse launch configurations"
23
+ *.launch
24
+
25
+ # CDT-specific
26
+ .cproject
27
+
28
+ # PDT-specific
29
+ .buildpath
30
+
31
+
32
+ #################
33
+ ## Visual Studio
34
+ #################
35
+
36
+ ## Ignore Visual Studio temporary files, build results, and
37
+ ## files generated by popular Visual Studio add-ons.
38
+
39
+ # User-specific files
40
+ *.suo
41
+ *.user
42
+ *.sln.docstates
43
+
44
+ # Build results
45
+ [Dd]ebug/
46
+ [Rr]elease/
47
+ *_i.c
48
+ *_p.c
49
+ *.ilk
50
+ *.meta
51
+ *.obj
52
+ *.pch
53
+ *.pdb
54
+ *.pgc
55
+ *.pgd
56
+ *.rsp
57
+ *.sbr
58
+ *.tlb
59
+ *.tli
60
+ *.tlh
61
+ *.tmp
62
+ *.vspscc
63
+ .builds
64
+ *.dotCover
65
+
66
+ ## TODO: If you have NuGet Package Restore enabled, uncomment this
67
+ #packages/
68
+
69
+ # Visual C++ cache files
70
+ ipch/
71
+ *.aps
72
+ *.ncb
73
+ *.opensdf
74
+ *.sdf
75
+
76
+ # Visual Studio profiler
77
+ *.psess
78
+ *.vsp
79
+
80
+ # ReSharper is a .NET coding add-in
81
+ _ReSharper*
82
+
83
+ # Installshield output folder
84
+ [Ee]xpress
85
+
86
+ # DocProject is a documentation generator add-in
87
+ DocProject/buildhelp/
88
+ DocProject/Help/*.HxT
89
+ DocProject/Help/*.HxC
90
+ DocProject/Help/*.hhc
91
+ DocProject/Help/*.hhk
92
+ DocProject/Help/*.hhp
93
+ DocProject/Help/Html2
94
+ DocProject/Help/html
95
+
96
+ # Click-Once directory
97
+ publish
98
+
99
+ # Others
100
+ [Bb]in
101
+ [Oo]bj
102
+ sql
103
+ TestResults
104
+ *.Cache
105
+ ClientBin
106
+ stylecop.*
107
+ ~$*
108
+ *.dbmdl
109
+ Generated_Code #added for RIA/Silverlight projects
110
+
111
+ # Backup & report files from converting an old project file to a newer
112
+ # Visual Studio version. Backup files are not needed, because we have git ;-)
113
+ _UpgradeReport_Files/
114
+ Backup*/
115
+ UpgradeLog*.XML
116
+
117
+
118
+
119
+ ############
120
+ ## Windows
121
+ ############
122
+
123
+ # Windows image file caches
124
+ Thumbs.db
125
+
126
+ # Folder config file
127
+ Desktop.ini
128
+
129
+
130
+ #############
131
+ ## Python
132
+ #############
133
+
134
+ *.py[co]
135
+
136
+ # Packages
137
+ *.egg
138
+ *.egg-info
139
+ dist
140
+ build
141
+ eggs
142
+ parts
143
+ bin
144
+ var
145
+ sdist
146
+ develop-eggs
147
+ .installed.cfg
148
+
149
+ # Installer logs
150
+ pip-log.txt
151
+
152
+ # Unit test / coverage reports
153
+ .coverage
154
+ .tox
155
+
156
+ #Translations
157
+ *.mo
158
+
159
+ #Mr Developer
160
+ .mr.developer.cfg
161
+
162
+ # Mac crap
163
+ .DS_Store
@@ -0,0 +1,8 @@
1
+ require 'rake/testtask'
2
+
3
+ Rake::TestTask.new do |t|
4
+ t.libs << 'test'
5
+ end
6
+
7
+ desc "Run tests"
8
+ task :default => :test
Binary file
@@ -0,0 +1,14 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'alm-rest-api'
3
+ s.version = '0.0.2'
4
+ s.date = '2012-12-14'
5
+ s.summary = "ALM!"
6
+ s.description = "ALM REST API Integration"
7
+ s.authors = ["Simon Zheng"]
8
+ s.email = 'xiaomengzheng@gmail.com'
9
+ s.require_paths = ["lib"]
10
+ s.files = `git ls-files`.split("\n")
11
+ #s.files = ["lib/alm-rest-api.rb"]
12
+ s.homepage =
13
+ 'http://rubygems.org/gems/alm-rest-api'
14
+ end
@@ -0,0 +1,154 @@
1
+ # alm-rest-api.rb
2
+
3
+ module ALM
4
+
5
+ # Logging in to our system is standard http login (basic authentication),
6
+ # where one must store the returned cookies for further use.
7
+ def self.login(loginUrl, username, password)
8
+ response = RestConnector.instance.httpBasicAuth(loginUrl, username, password)
9
+
10
+ return response.statusCode == '200'
11
+ end
12
+
13
+ def self.logout()
14
+ # note the get operation logs us out by setting authentication cookies to:
15
+ # LWSSO_COOKIE_KEY="" via server response header Set-Cookie
16
+ logoutUrl = RestConnector.instance.buildUrl("qcbin/authentication-point/logout")
17
+ response = RestConnector.instance.httpGet(logoutUrl, nil, nil)
18
+
19
+ return response.statusCode == '200'
20
+ end
21
+
22
+ def self.isAuthenticated()
23
+ isAuthenticateUrl = RestConnector.instance.buildUrl("qcbin/rest/is-authenticated")
24
+ response = RestConnector.instance.httpGet(isAuthenticateUrl, nil, nil)
25
+ responseCode = response.statusCode
26
+
27
+ # if already authenticated
28
+ # if not authenticated - get the address where to authenticate
29
+ # via WWW-Authenticate
30
+ if responseCode == "200"
31
+ ret = nil
32
+ elsif responseCode == "401"
33
+ authenticationHeader = response.responseHeaders["WWW-Authenticate"]
34
+ newUrl = authenticationHeader.split("=").at(1)
35
+ newUrl = newUrl.delete("\"")
36
+ newUrl = newUrl + "/authenticate"
37
+ ret = newUrl
38
+ end
39
+
40
+ return ret
41
+ end
42
+
43
+ # convenience method to do user login
44
+ def self.isLoggedIn(username, password)
45
+ authenticationPoint = isAuthenticated();
46
+ if (authenticationPoint != nil)
47
+ return login(authenticationPoint, username, password)
48
+ end
49
+ return true
50
+ end
51
+
52
+ # read all defects fields
53
+ def self.getDefectFields(required = false)
54
+ defectFieldsUrl = RestConnector.instance.buildEntityCollectionUrl("customization/entities/defect/field")
55
+ queryString = nil
56
+ if required
57
+ queryString = "required=true"
58
+ end
59
+ requestHeaders = Hash.new
60
+ requestHeaders["Accept"] = "application/xml"
61
+ response = RestConnector.instance.httpGet(defectFieldsUrl, queryString, requestHeaders)
62
+
63
+ defectFields = nil
64
+ if response.statusCode == '200'
65
+ defectFields = DefectFields::Fields.parse(response.toString())
66
+ end
67
+
68
+ return defectFields
69
+ end
70
+
71
+ # read pre-defined defects fields values
72
+ def self.getValueLists(defectFields = nil)
73
+ # ALM 11.0 the url is "customization/list"
74
+ valueListsUrl = RestConnector.instance.buildEntityCollectionUrl("customization/list")
75
+ queryString = nil
76
+ if defectFields
77
+ defectFields.fields.each do |field|
78
+ if field.list_id
79
+ if queryString == nil
80
+ queryString = "id=" + field.list_id.to_s
81
+ else
82
+ queryString = queryString + "," + field.list_id.to_s
83
+ end
84
+ end
85
+ end
86
+ end
87
+
88
+ requestHeaders = Hash.new
89
+ requestHeaders["Accept"] = "application/xml"
90
+ response = RestConnector.instance.httpGet(valueListsUrl, queryString, requestHeaders)
91
+
92
+ valueLists = nil
93
+ if response.statusCode == '200'
94
+ valueLists = ValueLists::Lists.parse(response.toString())
95
+ end
96
+
97
+ return valueLists
98
+ end
99
+
100
+ # create new defect
101
+ def self.createDefect(defect)
102
+ defectsUrl = RestConnector.instance.buildEntityCollectionUrl("defect")
103
+ requestHeaders = Hash.new
104
+ requestHeaders["Content-Type"] = "application/xml"
105
+ requestHeaders["Accept"] = "application/xml"
106
+
107
+ response = RestConnector.instance.httpPost(defectsUrl, defect.to_xml, requestHeaders)
108
+
109
+ defectId = nil
110
+ if response.statusCode == '201'
111
+ defectUrl = response.responseHeaders["Location"]
112
+ defectId = defectUrl.split('/').last
113
+ end
114
+
115
+ return defectId
116
+ end
117
+
118
+ # delete a defect
119
+ def self.deleteDefect(defectId)
120
+ defectUrl = RestConnector.instance.buildDefectUrl(defectId)
121
+ requestHeaders = Hash.new
122
+ requestHeaders["Accept"] = "application/xml"
123
+
124
+ response = RestConnector.instance.httpDelete(defectUrl, requestHeaders)
125
+
126
+ return response.statusCode == '200'
127
+ end
128
+
129
+ # attach a file
130
+ def self.attachWithMultipart(defectId, filePath)
131
+ attachmentUrl = RestConnector.instance.buildEntityCollectionUrl("attachment")
132
+ boundary = "AaB03x"
133
+ requestHeaders = Hash.new
134
+ requestHeaders["Content-Type"] = "multipart/form-data, boundary=#{boundary}"
135
+
136
+ #post_body = []
137
+ #post_body < < "--#{boundary}rn"
138
+ #post_body < < "Content-Disposition: form-data; name="datafile"; filename="#{File.basename(file)}"rn"
139
+ #post_body < < "Content-Type: text/plainrn"
140
+ #post_body < < "rn"
141
+ #post_body < < File.read(file)
142
+ #post_body < < "rn--#{boundary}--rn"
143
+
144
+ #Response response = RestConnector.instance.httpPost(attachmentUrl, post_body, requestHeaders)
145
+ end
146
+
147
+ end
148
+
149
+ require 'alm-rest-api/entity'
150
+ require 'alm-rest-api/defect-fields'
151
+ require 'alm-rest-api/value-lists'
152
+ require 'alm-rest-api/constants'
153
+ require 'alm-rest-api/response'
154
+ require 'alm-rest-api/rest-connector'
@@ -0,0 +1,12 @@
1
+ # These constants are used throughout the code to set the server to work with.
2
+ # To execute this code, change these settings to fit
3
+ # those of your server.
4
+ class ALM::Constants
5
+ HOST = "localhost"
6
+ PORT = "8080"
7
+ USERNAME = "sa"
8
+ PASSWORD = "C71a04t23"
9
+ DOMAIN = "DEFAULT"
10
+ PROJECT = "Simon"
11
+ VERSIONED = true
12
+ end
@@ -0,0 +1,33 @@
1
+ require 'happymapper'
2
+
3
+ module DefectFields
4
+
5
+ class Field
6
+ include HappyMapper
7
+
8
+ tag 'Field'
9
+ attribute :physical_name, String, :tag => 'PhysicalName'
10
+ attribute :name, String, :tag => 'Name'
11
+ attribute :label, String, :tag => 'Label'
12
+ element :active, Boolean, :tag => 'Active'
13
+ element :editable, Boolean, :tag => 'Editable'
14
+ element :size, Integer, :tag => 'Size'
15
+ element :filterable, Boolean, :tag => 'Filterable'
16
+ element :groupable, Boolean, :tag => 'Groupable'
17
+ element :history, Boolean, :tag => 'History'
18
+ element :list_id, Integer, :tag => 'List-Id'
19
+ element :type, String, :tag => 'Type'
20
+ element :supports_multivalue, Boolean, :tag => 'SupportsMultivalue'
21
+ element :required, Boolean, :tag => 'Required'
22
+ element :system, Boolean, :tag => 'System'
23
+ element :verify, Boolean, :tag => 'Verify'
24
+ element :virtual, Boolean, :tag => 'Virtual'
25
+ end
26
+
27
+ class Fields
28
+ include HappyMapper
29
+
30
+ tag 'Fields'
31
+ has_many :fields, Field
32
+ end
33
+ end
@@ -0,0 +1,30 @@
1
+ require 'happymapper'
2
+
3
+ class Field
4
+ include HappyMapper
5
+
6
+ tag 'Field'
7
+ attribute :name, String, :tag => 'Name'
8
+ element :value, String, :tag => 'Value'
9
+ end
10
+
11
+ class Fields
12
+ include HappyMapper
13
+
14
+ tag 'Fields'
15
+ has_many :fields, Field
16
+ end
17
+
18
+ class Entity
19
+ include HappyMapper
20
+
21
+ def initialize(type)
22
+ @type = type
23
+ @fields = Fields.new
24
+ @fields.fields = Array.new
25
+ end
26
+
27
+ tag 'Entity'
28
+ attribute :type, String, :tag => 'Type'
29
+ element :fields, Fields
30
+ end
@@ -0,0 +1,11 @@
1
+ class ALM::Response
2
+ attr_accessor :responseHeaders
3
+ attr_accessor :responseData
4
+ attr_accessor :failure
5
+ attr_accessor :statusCode
6
+
7
+ def toString()
8
+ return responseData
9
+ end
10
+
11
+ end
@@ -0,0 +1,147 @@
1
+ # rest-connector.rb
2
+
3
+ require 'net/http'
4
+ require 'uri'
5
+ require 'stringio'
6
+ require 'singleton'
7
+
8
+ class ALM::RestConnector
9
+ include Singleton
10
+
11
+ attr_accessor :cookies
12
+ attr_accessor :host
13
+ attr_accessor :port
14
+ attr_accessor :domain
15
+ attr_accessor :project
16
+
17
+ def init(cookies, host, port, domain, project)
18
+ @cookies = cookies
19
+ @host = host
20
+ @port = port
21
+ @domain = domain
22
+ @project = project
23
+ end
24
+
25
+ def buildEntityCollectionUrl(entityType)
26
+ return buildUrl('qcbin/rest/domains/' + domain + '/projects/' + project + '/' + entityType + 's')
27
+ end
28
+
29
+ def buildDefectUrl(defectId)
30
+ return buildUrl('qcbin/rest/domains/' + domain + '/projects/' + project + '/defects/' + defectId)
31
+ end
32
+
33
+ def buildUrl(path)
34
+ return "http://#{host}:#{port}/#{path}"
35
+ end
36
+
37
+ def httpPut(url, data, headers)
38
+ return doHttp('PUT', url, nil, data, headers, cookies)
39
+ end
40
+
41
+ def httpPost(url, data, headers)
42
+ return doHttp('POST', url, nil, data, headers, cookies)
43
+ end
44
+
45
+ def httpDelete(url, headers)
46
+ return doHttp('DELETE', url, nil, nil, headers, cookies)
47
+ end
48
+
49
+ def httpGet(url, queryString, headers)
50
+ return doHttp('GET', url, queryString, nil, headers, cookies)
51
+ end
52
+
53
+ def httpBasicAuth(url, username, password)
54
+ headers = {"username" => username, "password" => password}
55
+ return doHttp('AUTH', url, nil, nil, headers, cookies)
56
+ end
57
+
58
+ def getCookieString
59
+ s = StringIO.new
60
+ if (!cookies.empty?)
61
+ cookies.each{|key,value|
62
+ s << key << '=' << value << ';'
63
+ }
64
+ end
65
+
66
+ return s.string
67
+ end
68
+
69
+ private
70
+
71
+ def doHttp(type, url, queryString, data, headers, cookies)
72
+ if (queryString != nil && !queryString.empty?)
73
+ url.concat('?' + queryString)
74
+ end
75
+
76
+ uri = URI.parse(url)
77
+ http = Net::HTTP.new(uri.host, uri.port)
78
+
79
+ case type
80
+ when "POST"
81
+ request = Net::HTTP::Post.new(uri.request_uri)
82
+ when "GET"
83
+ request = Net::HTTP::Get.new(uri.request_uri)
84
+ when "PUT"
85
+ request = Net::HTTP::Put.new(uri.request_uri)
86
+ when "DELETE"
87
+ request = Net::HTTP::Delete.new(uri.request_uri)
88
+ when "AUTH"
89
+ request = Net::HTTP::Get.new(uri.request_uri)
90
+ request.basic_auth(headers["username"], headers["password"])
91
+ end
92
+
93
+ cookieString = getCookieString()
94
+ prepareHttpRequest(request, headers, data, cookieString)
95
+
96
+ response = http.request(request)
97
+
98
+ res = retrieveHtmlResponse(response)
99
+ updateCookies(res)
100
+
101
+ return res
102
+ end
103
+
104
+ def prepareHttpRequest(request, headers, data, cookieString)
105
+ contentType = nil
106
+ if (cookieString != nil && !cookieString.empty?)
107
+ request["Cookie"] = cookieString
108
+ end
109
+
110
+ if (headers != nil)
111
+ contentType = headers.delete("Content-Type")
112
+ headers.each{|key, value|
113
+ request[key] = value
114
+ }
115
+ end
116
+
117
+ if (data != nil)
118
+ if (contentType != nil)
119
+ request["Content-Type"] = contentType
120
+ request.body = data
121
+ end
122
+ end
123
+ end
124
+
125
+ def retrieveHtmlResponse(response)
126
+ res = ALM::Response.new
127
+ res.statusCode = response.code
128
+ res.responseHeaders = response
129
+ res.responseData = response.body
130
+
131
+ return res
132
+ end
133
+
134
+ def updateCookies(response)
135
+ newCookies = response.responseHeaders.get_fields('Set-Cookie')
136
+ if (newCookies != nil)
137
+ newCookies.each{|cookie|
138
+ c1 = cookie.split(';')[0]
139
+ c2 = c1.split('=')
140
+ key = c2[0]
141
+ value = c2[1]
142
+ cookies[key] = value
143
+ }
144
+ end
145
+ end
146
+
147
+ end
@@ -0,0 +1,43 @@
1
+ require 'happymapper'
2
+
3
+ module ValueLists
4
+
5
+ class Item
6
+ include HappyMapper
7
+
8
+ tag 'Item'
9
+ attribute :value, String, :tag => 'value'
10
+ end
11
+
12
+ class Items
13
+ include HappyMapper
14
+
15
+ tag 'Items'
16
+ has_many :items, Item
17
+ end
18
+
19
+ class List
20
+ include HappyMapper
21
+
22
+ tag 'List'
23
+ element :name, String, :tag => 'Name'
24
+ element :id, Integer, :tag => 'Id'
25
+ has_one :items, Items
26
+ end
27
+
28
+ class Lists
29
+ include HappyMapper
30
+
31
+ tag 'Lists'
32
+ has_many :lists, List
33
+ end
34
+
35
+ def self.getValuesById(id, valueLists)
36
+ valueLists.lists.each do |list|
37
+ if (list.id == id)
38
+ return list.items.items
39
+ end
40
+ end
41
+ end
42
+
43
+ end
@@ -0,0 +1,118 @@
1
+ require 'stringio'
2
+ require 'test/unit'
3
+ require 'alm-rest-api'
4
+
5
+ class TestALMRestAPI < Test::Unit::TestCase
6
+
7
+ def setup
8
+ ALM::RestConnector.instance.init(Hash.new,
9
+ ALM::Constants::HOST,
10
+ ALM::Constants::PORT,
11
+ ALM::Constants::DOMAIN,
12
+ ALM::Constants::PROJECT)
13
+ end
14
+
15
+ def test_AuthenticateLoginLogout
16
+ if false # change to true if you want run the test case
17
+ # Returns nil if authenticated. If not authenticated, returns
18
+ # a URL indicating where to login.
19
+ # We are not logged in, so call returns a URL
20
+ authenticationPoint = ALM.isAuthenticated()
21
+ assert_not_nil(authenticationPoint, "response from isAuthenticated means we're authenticated. that can't be.")
22
+
23
+ # now we login to previously returned URL.
24
+ loginResponse = ALM.login(authenticationPoint, ALM::Constants::USERNAME, ALM::Constants::PASSWORD)
25
+ assert(loginResponse, "failed to login.")
26
+ assert((ALM::RestConnector.instance.getCookieString.include? "LWSSO_COOKIE_KEY"), "login did not cause creation of Light Weight Single Sign On(LWSSO) cookie.")
27
+
28
+ # proof that we are indeed logged in
29
+ assert_nil(ALM.isAuthenticated(), "isAuthenticated returned not authenticated after login.")
30
+
31
+ # and now we logout
32
+ ALM.logout()
33
+
34
+ # And now we can see that we are indeed logged out
35
+ # because isAuthenticated once again returns a url, and not null.
36
+ assert_not_nil(ALM.isAuthenticated(), "isAuthenticated returned authenticated after logout.")
37
+ end
38
+ end
39
+
40
+ def test_GetDefectFields
41
+ if false # change to true if you want run the test case
42
+ loginResponse = ALM.isLoggedIn(ALM::Constants::USERNAME, ALM::Constants::PASSWORD)
43
+ assert(loginResponse, "failed to login.")
44
+
45
+ defectFields = ALM.getDefectFields(true)
46
+ valueLists = ALM.getValueLists(defectFields)
47
+ if defectFields
48
+ defectFields.fields.each do |field|
49
+ puts "Name = #{field.name}"
50
+ puts "Label = #{field.label}"
51
+ puts "Size = #{field.size}"
52
+ puts "Type = #{field.type}"
53
+ puts "Required = #{field.required}"
54
+ if (field.list_id && valueLists)
55
+ items = ValueLists.getValuesById(field.list_id, valueLists)
56
+ items.each do |item|
57
+ puts "Value = #{item.value}"
58
+ end
59
+ end
60
+ puts "--------------------------"
61
+ end
62
+
63
+ puts defectFields.to_xml
64
+ if valueLists
65
+ puts valueLists.to_xml
66
+ end
67
+ end
68
+
69
+ ALM.logout()
70
+ end
71
+ end
72
+
73
+ def test_CreateDeleteDefect
74
+ if true # change to true if you want run the test case
75
+ loginResponse = ALM.isLoggedIn(ALM::Constants::USERNAME, ALM::Constants::PASSWORD)
76
+ assert(loginResponse, "failed to login.")
77
+
78
+ defect = Entity.new("defect")
79
+
80
+ defectFields = ALM.getDefectFields(true)
81
+ valueLists = ALM.getValueLists(defectFields)
82
+ if defectFields
83
+ defectFields.fields.each do |field|
84
+ defectField = Field.new
85
+ defectField.name = field.name
86
+ type = field.type
87
+ case type
88
+ when "LookupList"
89
+ if valueLists
90
+ items = ValueLists.getValuesById(field.list_id, valueLists)
91
+ defectField.value = items.first.value
92
+ end
93
+ when "Date"
94
+ defectField.value = Time.now.strftime("%Y-%m-%d")
95
+ when "UsersList"
96
+ defectField.value = ALM::Constants::USERNAME
97
+ else
98
+ defectField.value = "0"
99
+ end
100
+ defect.fields.fields<<defectField
101
+ end
102
+
103
+ puts defect.to_xml
104
+
105
+ defectId = ALM.createDefect(defect)
106
+ assert_not_nil(defectId, "fail to create defect.")
107
+
108
+ if defectId
109
+ deleteResponse = ALM.deleteDefect(defectId)
110
+ assert(deleteResponse, "failed to delete defect.")
111
+ end
112
+ end
113
+
114
+ ALM.logout()
115
+ end
116
+ end
117
+
118
+ end
metadata ADDED
@@ -0,0 +1,77 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: alm-rest-api
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 2
10
+ version: 0.0.2
11
+ platform: ruby
12
+ authors:
13
+ - Simon Zheng
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2012-12-14 00:00:00 Z
19
+ dependencies: []
20
+
21
+ description: ALM REST API Integration
22
+ email: xiaomengzheng@gmail.com
23
+ executables: []
24
+
25
+ extensions: []
26
+
27
+ extra_rdoc_files: []
28
+
29
+ files:
30
+ - .gitattributes
31
+ - .gitignore
32
+ - Rakefile
33
+ - alm-rest-api-0.0.1.gem
34
+ - alm-rest-api.gemspec
35
+ - lib/alm-rest-api.rb
36
+ - lib/alm-rest-api/constants.rb
37
+ - lib/alm-rest-api/defect-fields.rb
38
+ - lib/alm-rest-api/entity.rb
39
+ - lib/alm-rest-api/response.rb
40
+ - lib/alm-rest-api/rest-connector.rb
41
+ - lib/alm-rest-api/value-lists.rb
42
+ - test/test_alm_rest_api.rb
43
+ homepage: http://rubygems.org/gems/alm-rest-api
44
+ licenses: []
45
+
46
+ post_install_message:
47
+ rdoc_options: []
48
+
49
+ require_paths:
50
+ - lib
51
+ required_ruby_version: !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ hash: 3
57
+ segments:
58
+ - 0
59
+ version: "0"
60
+ required_rubygems_version: !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ">="
64
+ - !ruby/object:Gem::Version
65
+ hash: 3
66
+ segments:
67
+ - 0
68
+ version: "0"
69
+ requirements: []
70
+
71
+ rubyforge_project:
72
+ rubygems_version: 1.8.10
73
+ signing_key:
74
+ specification_version: 3
75
+ summary: ALM!
76
+ test_files: []
77
+