diff --git a/README.md b/README.md index 7f8c247..35d929f 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ ## License -Copyright (c) Rally Software Development Corp. 2013 Distributed under the MIT License. +Copyright (c) Rally Software Development Corp. 2015 Distributed under the MIT License. ## Warranty @@ -16,7 +16,7 @@ RallyAPI (rally_api) -- a wrapper for Rally's REST Web Services API [![Stories in Ready](http://badge.waffle.io/RallyTools/RallyRestToolkitForRuby.png)](http://waffle.io/RallyTools/RallyRestToolkitForRuby) -RallyAPI is a wrapper of Rally's Web Service API Json endpoints using rest-client and native json parsing +RallyAPI is a wrapper of Rally's Web Service API JSON endpoints using rest-client and native json parsing Check the examples directory for more detailed samples. ### Installation @@ -70,8 +70,8 @@ A Rally API Key can be used for user authentication. If an API Key is provided, test_query = RallyAPI::RallyQuery.new() test_query.type = "defect" test_query.fetch = "Name" - test_query.workspace = {"_ref" => "https://rally1.rallydev.com/slm/webservice/1.25/workspace/12345.js" } #optional - test_query.project = {"_ref" => "https://rally1.rallydev.com/slm/webservice/1.25/project/12345.js" } #optional + test_query.workspace = {"_ref" => "https://rally1.rallydev.com/slm/webservice/v2.0/workspace/12345" } #optional + test_query.project = {"_ref" => "https://rally1.rallydev.com/slm/webservice/v2.0/project/12345" } #optional test_query.page_size = 200 #optional - default is 200 test_query.limit = 1000 #optional - default is 99999 test_query.project_scope_up = false @@ -114,8 +114,8 @@ A Rally API Key can be used for user authentication. If an API Key is provided, #If you query with a specific fetch string, for example query defect and fetch Name,Severity,Description #You will *only* get back those fields defect.Priority will be nil, but may not be null in Rally #Use object.read or @rally.read to make sure you read the whole object if you want what is in Rally - # This is done for speed - lazy loading (going back to get a value from Rally) can be unneccessarily slow - # *Pick you fetch strings wisely* fetch everything you need and don't rely on read if you don't need it the speed is worth it. + # This is done for speed - lazy loading (going back to get a value from Rally) can be unnecessarily slow + # *Pick your fetch strings wisely* fetch everything you need and don't rely on read if you don't need it, the speed is worth it. ### Creating an Artifact obj = {} @@ -147,12 +147,16 @@ A Rally API Key can be used for user authentication. If an API Key is provided, story1.rank_to_top ### Revision History + + Version 1.2.0 (April 2015) - set default WSAPI version to 2.0, fix paging issue in reread, + can now use DisplayName for custom fields in create and update operations. + Set httpclient gem runtime dependency to '= 2.5.0'. + + Version 1.1.2 (October 2014) - Set httpclient gem runtime dependency to '~> 2.4.0'. + + Version 1.1.1 (October 2014) - Relax httpclient gem runtime dependency to '>= 2.3.0'. + Version 1.1.0 (September 2014) - Appends workspace to Rally API requests to enable correct retrieval of allowed values from a user's non-default workspace. Updates gem development dependencies and test files structure. - Version 1.1.1 (October 2014) - Relax version requirement of httpclient runtime - dependency to '>= 2.3.0'. - - Version 1.1.2 (October 2014) - Change version requirement of httpclient runtime - dependency to '~> 2.4.0'. diff --git a/lib/rally_api.rb b/lib/rally_api.rb index 136bdf4..ddc76f8 100644 --- a/lib/rally_api.rb +++ b/lib/rally_api.rb @@ -1,4 +1,4 @@ -#Copyright (c) 2002-2012 Rally Software Development Corp. All Rights Reserved. +#Copyright (c) 2002-2015 Rally Software Development Corp. All Rights Reserved. #Your use of this Software is governed by the terms and conditions #of the applicable Subscription Agreement between your company and #Rally Software Development Corp. diff --git a/lib/rally_api/custom_http_header.rb b/lib/rally_api/custom_http_header.rb index c592292..47960e0 100644 --- a/lib/rally_api/custom_http_header.rb +++ b/lib/rally_api/custom_http_header.rb @@ -1,4 +1,4 @@ -#Copyright (c) 2002-2012 Rally Software Development Corp. All Rights Reserved. +#Copyright (c) 2002-2015 Rally Software Development Corp. All Rights Reserved. #Your use of this Software is governed by the terms and conditions #of the applicable Subscription Agreement between your company and #Rally Software Development Corp. diff --git a/lib/rally_api/lookback_api_query.rb b/lib/rally_api/lookback_api_query.rb index 5b1dc72..bed2cf2 100644 --- a/lib/rally_api/lookback_api_query.rb +++ b/lib/rally_api/lookback_api_query.rb @@ -1,5 +1,5 @@ # :stopdoc: -#Copyright (c) 2002-2012 Rally Software Development Corp. All Rights Reserved. +#Copyright (c) 2002-2015 Rally Software Development Corp. All Rights Reserved. #Your use of this Software is governed by the terms and conditions #of the applicable Subscription Agreement between your company and #Rally Software Development Corp. diff --git a/lib/rally_api/rally_collection.rb b/lib/rally_api/rally_collection.rb index d5ab955..9cd602b 100644 --- a/lib/rally_api/rally_collection.rb +++ b/lib/rally_api/rally_collection.rb @@ -1,5 +1,5 @@ # :stopdoc: -#Copyright (c) 2002-2012 Rally Software Development Corp. All Rights Reserved. +#Copyright (c) 2002-2015 Rally Software Development Corp. All Rights Reserved. #Your use of this Software is governed by the terms and conditions #of the applicable Subscription Agreement between your company and #Rally Software Development Corp. diff --git a/lib/rally_api/rally_json_connection.rb b/lib/rally_api/rally_json_connection.rb index 499d239..e84cdbc 100644 --- a/lib/rally_api/rally_json_connection.rb +++ b/lib/rally_api/rally_json_connection.rb @@ -2,7 +2,7 @@ require 'json' # :stopdoc: -#Copyright (c) 2002-2012 Rally Software Development Corp. All Rights Reserved. +#Copyright (c) 2002-2015 Rally Software Development Corp. All Rights Reserved. #Your use of this Software is governed by the terms and conditions #of the applicable Subscription Agreement between your company and #Rally Software Development Corp. diff --git a/lib/rally_api/rally_object.rb b/lib/rally_api/rally_object.rb index 3197861..94768a0 100644 --- a/lib/rally_api/rally_object.rb +++ b/lib/rally_api/rally_object.rb @@ -1,5 +1,5 @@ # :stopdoc: -#Copyright (c) 2002-2012 Rally Software Development Corp. All Rights Reserved. +#Copyright (c) 2002-2015 Rally Software Development Corp. All Rights Reserved. #Your use of this Software is governed by the terms and conditions #of the applicable Subscription Agreement between your company and #Rally Software Development Corp. @@ -15,14 +15,15 @@ class RallyObject def initialize(rally_rest, json_hash, warnings = {}) # handle that we might not get a _ref or a _type - if !json_hash["_type"].nil? || !json_hash["_ref"].nil? - @type = json_hash["_type"] || json_hash["_ref"].split("/")[-2] - else - @type = "unknown" - end + @type = "unknown" + if json_hash["_type"] && !json_hash["_type"].empty? + @type = json_hash["_type"] + elsif json_hash["_ref"] && !json_hash["_ref"].empty? + @type = json_hash["_ref"].split("/")[-2] + end @rally_object = json_hash - @rally_rest = rally_rest - @warnings = warnings[:warnings] + @rally_rest = rally_rest + @warnings = warnings[:warnings] end def update(fields, params = {}) @@ -150,21 +151,6 @@ def method_missing(sym, *args) ret_val end - #def get_val(field) - # return_val = rally_object[field] - # - # if return_val.class == Hash - # return RallyObject.new(@rally_rest, return_val) - # end - # - # if return_val.class == Array - # make_object_array(field) - # return_val = rally_object[field] - # end - # - # return_val - #end - def get_val(field) return_val = @rally_object[field] return_val = @rally_object["c_#{field}"] if return_val.nil? diff --git a/lib/rally_api/rally_query.rb b/lib/rally_api/rally_query.rb index ed52292..e98b9ae 100644 --- a/lib/rally_api/rally_query.rb +++ b/lib/rally_api/rally_query.rb @@ -1,5 +1,5 @@ # :stopdoc: -#Copyright (c) 2002-2012 Rally Software Development Corp. All Rights Reserved. +#Copyright (c) 2002-2015 Rally Software Development Corp. All Rights Reserved. #Your use of this Software is governed by the terms and conditions #of the applicable Subscription Agreement between your company and #Rally Software Development Corp. diff --git a/lib/rally_api/rally_query_result.rb b/lib/rally_api/rally_query_result.rb index 9b31eaf..4007dfc 100644 --- a/lib/rally_api/rally_query_result.rb +++ b/lib/rally_api/rally_query_result.rb @@ -1,5 +1,5 @@ # :stopdoc: -#Copyright (c) 2002-2012 Rally Software Development Corp. All Rights Reserved. +#Copyright (c) 2002-2015 Rally Software Development Corp. All Rights Reserved. #Your use of this Software is governed by the terms and conditions #of the applicable Subscription Agreement between your company and #Rally Software Development Corp. diff --git a/lib/rally_api/rally_rest_json.rb b/lib/rally_api/rally_rest_json.rb index 1bc0aba..78c4e0e 100644 --- a/lib/rally_api/rally_rest_json.rb +++ b/lib/rally_api/rally_rest_json.rb @@ -5,7 +5,7 @@ #require "rally_query_result" # -- -#Copyright (c) 2002-2012 Rally Software Development Corp. All Rights Reserved. +#Copyright (c) 2002-2015 Rally Software Development Corp. All Rights Reserved. #Your use of this Software is governed by the terms and conditions #of the applicable Subscription Agreement between your company and #Rally Software Development Corp. @@ -44,7 +44,7 @@ module RallyAPI #Main Class to instantiate when using the tool class RallyRestJson - DEFAULT_WSAPI_VERSION = "1.43" + DEFAULT_WSAPI_VERSION = "v2.0" attr_accessor :rally_url, :rally_workspace_name, :rally_project_name, :wsapi_version, :rally_headers, :rally_default_workspace, :rally_default_project, :low_debug, :proxy_info, @@ -96,12 +96,13 @@ def initialize(args) end def send_request(url = nil, args = nil, params = {}) + url += '.js' if @wsapi_version !~ /^v2/ && url !~ /\.js$/ # append ".js" if it is needed if params[:workspace].nil? && rally_workspace_object params[:workspace] = rally_workspace_object['_ref'] end if params[:workspace] wksp_id = params[:workspace].match(/workspace\/(\d*)/)[1] - url += "?/workspace=/workspace/#{wksp_id}" + url += "?workspace=workspace/#{wksp_id}" end @rally_connection.send_request(url, args, params) end @@ -181,15 +182,15 @@ def create(type, fields, params = {}) params[:workspace] = ws_ref fields = RallyAPI::RallyRestJson.fix_case(fields) if @rally_rest_api_compat - object2create = { type => check_fields(fields) } + postable_fields = check_fields(fields) + postable_fields = adjust_for_custom(type, postable_fields) if @wsapi_version =~ /^v2/ + object2create = { type => postable_fields } args = { :method => :post, :payload => object2create } - #json_response = @rally_connection.create_object(make_create_url(rally_type), args, object2create) json_response = send_request(make_create_url(type), args, params) #todo - check for warnings RallyObject.new(self, json_response["CreateResult"]["Object"], warnings(json_response)).read() end - def read(type, obj_id, params = {}) type = check_type(type) ref = check_id(type.to_s, obj_id) @@ -224,7 +225,7 @@ def read_collection(collection_hash, params = {}) pagesize = params[:pagesize] || 200 full_collection = [] start.step(collection_count, pagesize).each do |page_start| - page = reread(collection_hash, {:pagesize => 200, :startindex => page_start}) + page = reread(collection_hash, {:pagesize => 200, :start => page_start}) full_collection.concat(page["Results"]) end {"Results" => full_collection} @@ -234,7 +235,9 @@ def update(type, obj_id, fields, params = {}) type = check_type(type) ref = check_id(type.to_s, obj_id) fields = RallyAPI::RallyRestJson.fix_case(fields) if @rally_rest_api_compat - json_update = {type.to_s => check_fields(fields)} + update_fields = check_fields(fields) + update_fields = adjust_for_custom(type.to_s, update_fields) if @wsapi_version =~ /^v2/ + json_update = {type.to_s => update_fields} args = {:method => :post, :payload => json_update} json_response = send_request(ref, args, params) #todo check for warnings on json_response["OperationResult"] @@ -247,8 +250,8 @@ def update(type, obj_id, fields, params = {}) #test_query = RallyAPI::RallyQuery.new() #test_query.type = :defect #test_query.fetch = "Name" - #test_query.workspace = {"_ref" => "https://rally1.rallydev.com/slm/webservice/1.25/workspace/12345.js" } #optional - #test_query.project = {"_ref" => "https://rally1.rallydev.com/slm/webservice/1.25/project/12345.js" } #optional + #test_query.workspace = {"_ref" => "https://rally1.rallydev.com/slm/webservice/v2.0/workspace/12345" } #optional + #test_query.project = {"_ref" => "https://rally1.rallydev.com/slm/webservice/v2.0/project/12345" } #optional #test_query.page_size = 200 #optional - default is 200 #test_query.limit = 1000 #optional - default is 99999 #test_query.project_scope_up = false @@ -279,6 +282,7 @@ def find(query_obj = RallyQuery.new) end query_url = make_query_url(@rally_url, @wsapi_version, check_type(query_obj.type.to_s)) + query_url += '.js' if @wsapi_version !~ /^v2/ query_params = query_obj.make_query_params args = {:method => :get} json_response = @rally_connection.get_all_json_results(query_url, args, query_params, query_obj.limit) @@ -290,7 +294,7 @@ def adjust_find_threads(num_threads) end #rankAbove=%2Fhierarchicalrequirement%2F4624552599 - #{"hierarchicalrequirement":{"_ref":"https://rally1.rallydev.com/slm/webservice/1.27/hierarchicalrequirement/4616818613.js"}} + #{"hierarchicalrequirement":{"_ref":"https://rally1.rallydev.com/slm/webservice/v2.0/hierarchicalrequirement/4616818613"}} def rank_above(ref_to_rank, relative_ref) ref = ref_to_rank params = {} @@ -389,28 +393,33 @@ def pre_init() end def make_get_url(type) - "#{@rally_url}/webservice/#{@wsapi_version}/#{type}.js" + "#{@rally_url}/webservice/#{@wsapi_version}/#{type}" end def security_url - "#{@rally_url}/webservice/#{@wsapi_version}/security/authorize.js" + "#{@rally_url}/webservice/#{@wsapi_version}/security/authorize" end def make_read_url(type,oid) - "#{@rally_url}/webservice/#{@wsapi_version}/#{type}/#{oid}.js" + "#{@rally_url}/webservice/#{@wsapi_version}/#{type}/#{oid}" end def make_create_url(type) - "#{@rally_url}/webservice/#{@wsapi_version}/#{type}/create.js" + "#{@rally_url}/webservice/#{@wsapi_version}/#{type}/create" end def make_query_url(rally_url, wsapi_version, type) - "#{rally_url}/webservice/#{wsapi_version}/#{type}.js" + "#{rally_url}/webservice/#{wsapi_version}/#{type}" end def short_ref(long_ref) - ref_pieces = long_ref.split("/") - "/#{ref_pieces[-2]}/#{ref_pieces[-1].split(".js")[0]}" + if @wsapi_version =~ /^v2/ + path_components = long_ref.split("/") + path_components[-2..-1].join("/") + else + ref_pieces = long_ref.split("/") + "/#{ref_pieces[-2]}/#{ref_pieces[-1].split(".js")[0]}" + end end def warnings(json_obj) @@ -425,12 +434,16 @@ def check_type(type_name) return type_name end - #ref should be like https://rally1.rallydev.com/slm/webservice/1.25/defect/12345.js + #ref should be like https://rally1.rallydev.com/slm/webservice/v2.0/defect/12345 def has_ref?(json_object) if json_object["_ref"].nil? return false end - return true if json_object["_ref"] =~ /^https:\/\/\S*(\/slm\/webservice)\S*.js$/ + if @wsapi_version =~ /^v2/ + return true if json_object["_ref"] =~ /^https:\/\/\S*(\/slm\/webservice)\S*$/ + else + return true if json_object["_ref"] =~ /^https:\/\/\S*(\/slm\/webservice)\S*.js$/ + end false end @@ -460,7 +473,7 @@ def ref_by_formatted_id(type, fid) nil end - #eg https://rally1.rallydev.com/slm/webservice/1.25/defect/12345.js + #eg https://rally1.rallydev.com/slm/webservice/v2.0/defect/12345 def get_type_from_ref(ref) ref.split("/")[-2] end @@ -468,6 +481,7 @@ def get_type_from_ref(ref) def check_fields(fields) fields.each do |key, val| fields[key] = make_ref_field(val) + if val.class == Time fields[key] = val.iso8601 end @@ -493,6 +507,25 @@ def make_ref_field(val) val end + def adjust_for_custom(type, fields) + # only needed for when using WSAPI v2.x or later, custom fields must be prefixed with 'c_' + begin + type_custom_fields = custom_fields_for(type) + rescue => ex + return fields + end + transform = {} + fields.each do |name, value| + is_custom = type_custom_fields.select {|fn| fn.downcase == name.downcase} + if is_custom.length > 0 + transform[is_custom.first.last] = value + else + transform[name] = value + end + end + transform + end + def self.fix_case(values) values.inject({}) do |new_values, (key, value)| new_values[camel_case_word(key)] = value.is_a?(Hash) ? fix_case(value) : value diff --git a/lib/rally_api/version.rb b/lib/rally_api/version.rb index dd8d0c5..9964fc7 100644 --- a/lib/rally_api/version.rb +++ b/lib/rally_api/version.rb @@ -1,8 +1,8 @@ # :nodoc: -#Copyright (c) 2002-2012 Rally Software Development Corp. All Rights Reserved. +#Copyright (c) 2002-2015 Rally Software Development Corp. All Rights Reserved. #Your use of this Software is governed by the terms and conditions #of the applicable Subscription Agreement between your company and #Rally Software Development Corp. module RallyAPI - VERSION = "1.1.2" + VERSION = "1.2.0" end diff --git a/rally_api.gemspec b/rally_api.gemspec index 618ae90..5980ef0 100644 --- a/rally_api.gemspec +++ b/rally_api.gemspec @@ -5,8 +5,8 @@ require "rally_api/version" Gem::Specification.new do |s| s.name = "rally_api" s.version = RallyAPI::VERSION - s.authors = ["Dave Smith", "Rylee Keys-DuMars"] - s.email = ["dsmith@rallydev.com", "rylee@rallydev.com"] + s.authors = ["Dave Smith", "Rylee Keys", "Kip Lehman"] + s.email = ["dsmith@rallydev.com", "rylee@rallydev.com", "klehman@rallydev.com"] s.homepage = "https://github.com/RallyTools/RallyRestToolkitForRuby" s.summary = "A wrapper for the Rally Web Services API using json" s.description = "API wrapper for Rally's JSON REST web services api" @@ -17,14 +17,15 @@ Gem::Specification.new do |s| s.has_rdoc = false - s.add_dependency('httpclient', '~> 2.4.0') + s.add_dependency('httpclient', '2.5.0') + s.add_development_dependency('simplecov', '0.9.1') - s.add_development_dependency('rspec', '3.1.0') - s.add_development_dependency('rake', '10.3.2') - s.add_development_dependency('pry', '0.10.1') + s.add_development_dependency('rspec', '3.1.0') + s.add_development_dependency('rake', '10.3.2') + s.add_development_dependency('pry', '0.10.1') #s.files = `git ls-files`.split("\n") - s.files = %w(README.md Rakefile) + Dir.glob("{lib}/**/*.rb").delete_if { |item| item.include?(".svn") } + s.files = %w(README.md Rakefile) + Dir.glob("{lib}/**/*.rb") #s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") #s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) } s.require_paths = ["lib"] diff --git a/spec/rally_api_create_spec.rb b/spec/rally_api_create_spec.rb index a187547..5905c47 100644 --- a/spec/rally_api_create_spec.rb +++ b/spec/rally_api_create_spec.rb @@ -43,9 +43,7 @@ def setup_test_defect(fields = {}) else obj = {} obj["Name"] = "Test with a weblink" - obj[weblink_field_name] = { - "LinkID"=>"123", "DisplayString"=>"The Label" - } + obj[weblink_field_name] = { "LinkID"=>"123", "DisplayString"=>"The Label" } new_de = @rally.create(:defect, setup_test_defect(obj)) expect(new_de.Name).to eq(obj["Name"]) expect(new_de[weblink_field_name]["LinkID"]).to eq("123") diff --git a/spec/rally_api_general_spec.rb b/spec/rally_api_general_spec.rb index 0ccc1fd..0dda9da 100644 --- a/spec/rally_api_general_spec.rb +++ b/spec/rally_api_general_spec.rb @@ -6,9 +6,9 @@ def find_tag(tagname) tg_query = RallyAPI::RallyQuery.new() - tg_query.type = :tag + tg_query.type = :tag tg_query.query_string = "(Name = \"#{tagname}\")" - tg_query.limit=20 + tg_query.limit = 20 tg_result = @rally.find(tg_query) tg_result.first @@ -54,59 +54,54 @@ def find_tag(tagname) end context '#allowed_values', allowed_values: true do - context 'in default workspace' do - it 'gets allowed values' do - allowed_sevs = @rally.allowed_values("Defect", "Severity") - expect(allowed_sevs.length).to be > 2 - allowed_states = @rally.allowed_values(:story, "ScheduleState") - expect(allowed_states.length).to be > 3 - found = false - allowed_states.each_key do |st| - found = true if st == "Accepted" - end - expect(found).to be true - allowed_hr_states = @rally.allowed_values("HierarchicalRequirement", "ScheduleState") - expect(allowed_hr_states.length).to be > 3 - end - end - context 'in non-default workspace' do - let(:headers) do - RallyAPI::CustomHttpHeader.new( { :name => "Rally Rspec Utils", - :version => 'v2.0', - :vendor => "Rally" } ) + it 'gets allowed values in the default workspace' do + allowed_sevs = @rally.allowed_values("Defect", "Severity") + expect(allowed_sevs.length).to be > 2 + allowed_states = @rally.allowed_values(:story, "ScheduleState") + expect(allowed_states.length).to be > 3 + found = false + allowed_states.each_key do |st| + found = true if st == "Accepted" end + expect(found).to be true + allowed_hr_states = @rally.allowed_values("HierarchicalRequirement", "ScheduleState") + expect(allowed_hr_states.length).to be > 3 + end - it 'gets workspace-scoped allowed values in WSAPI v2.0' do - # Note: This test requires that the non-default workspace has different - # allowed values for Defect ScheduleState - - # Setup - @conf = YAML.load_file('spec/support/configs/APIconfig_nondefaultws.yml') - # Connect to default workspace - d_config = - { :base_url => @conf['RallyURL'] + '/slm', - :username => @conf['Username'], - :password => @conf['Password'], - :workspace => @conf['Default_WS'], - :version => 'v2.0', - :headers => headers, - :debug => false } - d_rally = RallyAPI::RallyRestJson.new(d_config) - d_workspace = d_rally.find_workspace(d_config['Workspace']) - # Connect to non-default workspace with unique allowed values - nd_config = d_config.merge(workspace: @conf['NonDefault_WS']) - nd_rally = RallyAPI::RallyRestJson.new(nd_config) - nd_workspace = nd_rally.find_workspace(nd_config['Workspace']) - - # Get allowed-values that are unique to each workspace - default_ws_values = d_rally.allowed_values("Defect", "ScheduleState", d_workspace) - nondefault_ws_values = nd_rally.allowed_values("Defect", "ScheduleState", nd_workspace) - - # Verify this non-default workspace has different allowed values - expect(default_ws_values).not_to eq(nondefault_ws_values) - end + it 'gets workspace-scoped allowed values in WSAPI v2.0' do + # Note: This test requires that the non-default workspace has different + # allowed values for Defect ScheduleState + + # Setup + @conf = YAML.load_file('spec/support/configs/APIconfig_nondefaultws.yml') + hdr_info ={ name: "Rally Rspec Utils", version: 'v2.0', vendor: "Rally" } + headers = RallyAPI::CustomHttpHeader.new(hdr_info) + # Connect to default workspace + d_config = + { :base_url => @conf['RallyURL'], + :username => @conf['Username'], + :password => @conf['Password'], + :workspace => @conf['Default_WS'], + :version => 'v2.0', + :headers => headers, + :debug => false } + d_rally = RallyAPI::RallyRestJson.new(d_config) + d_workspace = d_rally.find_workspace(d_config[:workspace]) + + # Connect to non-default workspace with unique allowed values + nd_config = d_config.merge(workspace: @conf['NonDefaultWS']) + nd_rally = RallyAPI::RallyRestJson.new(nd_config) + nd_workspace = nd_rally.find_workspace(nd_config[:workspace]) + + # Get allowed-values that are unique to each workspace + default_ws_values = d_rally.allowed_values("Defect", "ScheduleState", d_workspace) + nondefault_ws_values = nd_rally.allowed_values("Defect", "ScheduleState", nd_workspace) + + # Verify this non-default workspace has different allowed values + expect(default_ws_values).not_to eq(nondefault_ws_values) end + end it "should get the field list for defect" do diff --git a/spec/rally_api_read_spec.rb b/spec/rally_api_read_spec.rb index 5f9b103..bcfa7e7 100644 --- a/spec/rally_api_read_spec.rb +++ b/spec/rally_api_read_spec.rb @@ -50,8 +50,10 @@ q.order = "Rank FooBar" end # TODO: Update to ensure an appropriate warning is generated in WSAPI 2.0 - expect(defects.warnings.first).to match(/Please update your client to use the latest version of the API/) - expect(defects.warnings.length).to eq(1) + if @rally.wsapi_version != 'v2.0' + expect(defects.warnings.first).to match(/Please update your client to use the latest version of the API/) + expect(defects.warnings.length).to eq(1) + end end it "should conduct a find with an invalid order" do @@ -69,8 +71,10 @@ q.order = "" end # TODO: Update to ensure an appropriate warning is generated in WSAPI 2.0 - expect(defects.warnings.first).to match(/Please update your client to use the latest version of the API/) - expect(defects.warnings.length).to eq(1) + if @rally.wsapi_version != 'v2.0' + expect(defects.warnings.first).to match(/Please update your client to use the latest version of the API/) + expect(defects.warnings.length).to eq(1) + end # Warning: No sort criteria has been defined. The sort order will be unpredictable. # Between 10/10 and 10/21 end