Waitr and Jira integration not producing desired output - ruby

I wrote a Ruby script to check if the layer found in DOM in Firebug for the page www.jira.com is matching with the hash values declared in my script. Below is the Ruby script I have written:
require 'watir'
browser = Watir::Browser.new(:chrome)
browser.goto('https://jira.com')
JIRA_DATA_LAYER = {
'jira' => {
'event' => ['gtm.js', 'gtm.load'],
'gtm.start' => '1468949036556',
}
}
def get_jira_data_layer(get_data_layer)
result = []
get_data_layer.each do |data_layer|
data_layer.each do |data_layer_key, data_layer_value|
result << {"#{data_layer_key}" => data_layer_value}
end
end
return result
end
def compare_jira_data_layer(layer, jira_name)
message = []
index = 0
JIRA_DATA_LAYER[jira_name].each do |jira_key, jira_value|
if layer.include?({jira_key => jira_value})
result = 'matches - PASS'
else
result = 'matches - FAIL'
end
index += 1
message.push("'#{jira_key} => #{jira_value}' #{result}")
end
return message.join("\n")
end
data_layer = browser.execute_script("return dataLayer")
get_data_layer = get_jira_data_layer(data_layer)
compare_data_layer = compare_jira_data_layer(get_data_layer, "jira")
puts compare_data_layer
I am getting the following output:
'event => ["gtm.js", "gtm.load"]' matches - FAIL
'gtm.start => 1468949036556' matches - FAIL
I want the following to be achieved:
'event => gtm.js' matches - FAIL
'gtm.start => 1468949036556' matches - FAIL

You could simply change the value for event key in JIRA_DATA_LAYER, but I guess it has to be that way.
Try to expand if sentence when checking key for this hash and use is_a? method to check whether value for particular key is array or not. If so, loop through each member of this array.

Related

Ruby script for json formatter [duplicate]

This question already has answers here:
How do I push unique copies of array into another array?
(2 answers)
Ruby Arrays: Why is the value I print correct, but the value I push incorrect?
(1 answer)
Closed 4 months ago.
I am making json formater for sonarqube, here is my script:
require 'json'
tr_report = File.open('./tes.json').read
tr_report.gsub!(/\r\n?/, "\n")
sq_generic_format = {'issues' => []}
sq_issue_format = {
'engineId' => '', # CONST='brakeman'
'ruleId' => '', #[check_name (warning_code)] warning_type [confidence]
'severity':'MAJOR', # MAJOR
'type':'VULNERABILITY', # CONST='VULNERABILITY'
'primaryLocation' => {},
'effortMinutes' => 0, #CONST=0
}
primary_location_format = {
'message' => '', # message + CONST='\nCode:' + code + CONST='\nUser Input:' + user_input + CONST='\nLink: ' + link
'filePath' => '', # file
'textRange' => {}
}
text_range_format = {
'startLine' => 1,# line
'endLine' => 1,# line
'startColumn' => 0,
'endColumn' => 1
}
issues = []
tr_report.each_line do |line|
tr_data = JSON.parse(line)
# puts tr_data
# puts parsed["SourceMetadata"]["Data"]["Filesystem"]["file"]
issue = sq_issue_format
issue['engineId'] = 'trufflehog'
issue['ruleId'] = 'Sensitive Data Exposure - %s' %[tr_data['Raw']]
issue['severity'] = 'MAJOR' # MAJOR
issue['type'] = 'VULNERABILITY' # CONST='VULNERABILITY'
issue['effortMinutes'] = 0
issue['primaryLocation'] = {}
# filling up nested data lvl1 ^
primary_location = primary_location_format
primary_location['message'] = 'Sensitive Data Exposure'
primary_location['filePath'] = tr_data["SourceMetadata"]["Data"]["Filesystem"]["file"] # file
primary_location['textRange'] = {}
# filling up nested data lvl2 ^
text_range = text_range_format
# text_range['startLine'] = w['line']
# text_range['endLine'] = w['line']
# sticking all together
primary_location['textRange'] = text_range
issue['primaryLocation'] = primary_location
issues.append(issue)
end
# puts issues
sq_generic_format['issues'] = issues
puts JSON.dump(sq_generic_format)
File.write('./trufflehog-sq-report.json', JSON.dump(sq_generic_format))
and here is my jsonline tes.json:
{"SourceMetadata":{"Data":{"Filesystem":{"file":"../ruby/railsgoat/dependency-check-report.html"}}},"SourceID":15,"SourceType":15,"SourceName":"trufflehog - filesystem","DetectorType":9,"DetectorName":"Gitlab","Verified":false,"Raw":"vulnerable-to-driveby-","Redacted":"","ExtraData":null,"StructuredData":null}
{"SourceMetadata":{"Data":{"Filesystem":{"file":"../ruby/railsgoat/dependency-check-report.html"}}},"SourceID":15,"SourceType":15,"SourceName":"trufflehog - filesystem","DetectorType":800,"DetectorName":"Atera","Verified":false,"Raw":"39a6bda16ef9583fba2696cc3efde0da","Redacted":"","ExtraData":null,"StructuredData":null}
But everytime I try run it, I always got the first line of the parse, I cant get the next line and make the result redundace. how to capture my parse for the next line? and not just the first line.
Also i make a simple script to parse the jsonl, and it successfully like my expected. here is the script:
require 'json'
text=File.open('tes.json').read
text.gsub!(/\r\n?/, "\n")
text.each_line do |line|
parsed = JSON.parse(line)
puts parsed["Raw"]
end
result:
vulnerable-to-driveby-
39a6bda16ef9583fba2696cc3efde0da
The current result: its parse just only the first line,
expected result: I got all of the parse properly.
My expected result for my formatter script:
{"issues":[{"engineId":"trufflehog","ruleId":"Sensitive Data Exposure - vulnerable-to-driveby-","severity":"MAJOR","type":"VULNERABILITY","primaryLocation":{"message":"Sensitive Data Exposure","filePath":"../ruby/railsgoat/dependency-check-report.html","textRange":{"startLine":1,"endLine":1,"startColumn":0,"endColumn":1}},"effortMinutes":0,"severity":"MAJOR","type":"VULNERABILITY"},{"engineId":"trufflehog","ruleId":"Sensitive Data Exposure - 39a6bda16ef9583fba2696cc3efde0da","severity":"MAJOR","type":"VULNERABILITY","primaryLocation":{"message":"Sensitive Data Exposure","filePath":"../ruby/railsgoat/dependency-check-report.html","textRange":{"startLine":1,"endLine":1,"startColumn":0,"endColumn":1}},"effortMinutes":0,"severity":"MAJOR","type":"VULNERABILITY"}]}
and here what i got right now:
{"issues":[{"engineId":"trufflehog","ruleId":"Sensitive Data Exposure - 39a6bda16ef9583fba2696cc3efde0da","severity":"MAJOR","type":"VULNERABILITY","primaryLocation":{"message":"Sensitive Data Exposure","filePath":"../ruby/railsgoat/dependency-check-report.html","textRange":{"startLine":1,"endLine":1,"startColumn":0,"endColumn":1}},"effortMinutes":0,"severity":"MAJOR","type":"VULNERABILITY"},{"engineId":"trufflehog","ruleId":"Sensitive Data Exposure - 39a6bda16ef9583fba2696cc3efde0da","severity":"MAJOR","type":"VULNERABILITY","primaryLocation":{"message":"Sensitive Data Exposure","filePath":"../ruby/railsgoat/dependency-check-report.html","textRange":{"startLine":1,"endLine":1,"startColumn":0,"endColumn":1}},"effortMinutes":0,"severity":"MAJOR","type":"VULNERABILITY"}]}
PS: see the ruleId for the difference.
First, I ran your json through a formatter and it was reported as invalid. If you're going to have multiple objects you should use an array. So I've adjusted it to be: [{...},{...}]. (this is because JSON expects there to only be 1 root eleemnt.)
I think it's easiest to then say, you're doing the work that the JSON.parser is already meant to do. You can iterate through the object directly off the parser: JSON.parse(File.read("/tmp/tes.json")).map{ |obj| obj["Raw"] }
This gives me the results of => ["vulnerable-to-driveby-", "39a6bda16ef9583fba2696cc3efde0da"]

Ruby - no implicit conversion of Array into String

I am getting an error when executing my test.
Failure/Error: expect(industry_sic_code).to include page.sic_code
TypeError:
no implicit conversion of Array into String
# ./spec/os/bal/company/company_filter_clean_harbors_industries_stub.rb:62:in `block (2 levels) in <top (required)>'
The Method:
def sic_code
subtables = #b.table(:class => 'industry-codes').tables(:class => 'industry-code-table')
subtables.each do |subtable|
if subtable.tbody.h4.text == "US SIC 1987:"
subtable.tr.next_siblings.each do |tr|
codes = tr.cell
puts codes.text.to_s
end
end
end
end
The Test:
it 'Given I search for a random Clean Harbors Industry' do
#Pick a random clean industry from the file
data = CSV.foreach(file_path, headers: true).map{ |row| row.to_h }
random = data.sample
random_industry = random["Class"]
industry_sic_code = random["SIC Code"]
end
it 'Then the result has the expected SIC code' do
page = DetailPage.new(#b)
page.view
expect(industry_sic_code).to include page.sic_code
end
I have tried to implicitly change each variable to a string but it still complain about the array issue.
When I include some puts statments, I get some really wonky responses. The method itself returns the expected result.
When I used the method in the test I end up with the code gibberish below.
here are the sic codes from the method
5511
Here are the codes from the test
#<Watir::Table:0x00007fa3cb23f020>
#<Watir::Table:0x00007fa3cb23ee40>
#<Watir::Table:0x00007fa3cb23ec88>
#<Watir::Table:0x00007fa3cb23ead0>
#<Watir::Table:0x00007fa3cb23e918>
#<Watir::Table:0x00007fa3cb23e738>
#<Watir::Table:0x00007fa3cb23e580>
Your sic_code method returns subtables array, that's why you have this error. It doesn't matter that the method puts something, every method in ruby implicitly returns result of its last line, in your case it is subtables.each do ... end, so you have an array.
You need to explicitly return needed value. Not sure if I correctly understood what are you doing in your code, but try something like this:
def sic_code
subtables = #b.table(:class => 'industry-codes').tables(:class => 'industry-code-table')
result = [] # you need to collect result somewhere to return it later
subtables.each do |subtable|
if subtable.tbody.h4.text == "US SIC 1987:"
subtable.tr.next_siblings.each do |tr|
codes = tr.cell
result << codes.text.to_s
end
end
end
result.join(', ')
end

Code not actually asserting in RSpec?

I'm new to Ruby and in various open source software I've noticed a number of "statements" in some RSpec descriptions that appear not to accomplish what they intended, like they wanted to make an assertion, but didn't. Are these coding errors or is there some RSpec or Ruby magic I'm missing? (Likelihood of weirdly overloaded operators?)
The examples, with #??? added to the suspect lines:
(rubinius/spec/ruby/core/array/permutation_spec.rb)
it "returns no permutations when the given length has no permutations" do
#numbers.permutation(9).entries.size == 0 #???
#numbers.permutation(9) { |n| #yielded << n }
#yielded.should == []
end
(discourse/spec/models/topic_link_spec.rb)
it 'works' do
# ensure other_topic has a post
post
url = "http://#{test_uri.host}/t/#{other_topic.slug}/#{other_topic.id}"
topic.posts.create(user: user, raw: 'initial post')
linked_post = topic.posts.create(user: user, raw: "Link to another topic: #{url}")
TopicLink.extract_from(linked_post)
link = topic.topic_links.first
expect(link).to be_present
expect(link).to be_internal
expect(link.url).to eq(url)
expect(link.domain).to eq(test_uri.host)
link.link_topic_id == other_topic.id #???
expect(link).not_to be_reflection
...
(chef/spec/unit/chef_fs/parallelizer.rb)
context "With :ordered => false (unordered output)" do
it "An empty input produces an empty output" do
parallelize([], :ordered => false) do
sleep 10
end.to_a == [] #???
expect(elapsed_time).to be < 0.1
end
(bosh/spec/external/aws_bootstrap_spec.rb)
it "configures ELBs" do
load_balancer = elb.load_balancers.detect { |lb| lb.name == "cfrouter" }
expect(load_balancer).not_to be_nil
expect(load_balancer.subnets.sort {|s1, s2| s1.id <=> s2.id }).to eq([cf_elb1_subnet, cf_elb2_subnet].sort {|s1, s2| s1.id <=> s2.id })
expect(load_balancer.security_groups.map(&:name)).to eq(["web"])
config = Bosh::AwsCliPlugin::AwsConfig.new(aws_configuration_template)
hosted_zone = route53.hosted_zones.detect { |zone| zone.name == "#{config.vpc_generated_domain}." }
record_set = hosted_zone.resource_record_sets["\\052.#{config.vpc_generated_domain}.", 'CNAME'] # E.g. "*.midway.cf-app.com."
expect(record_set).not_to be_nil
record_set.resource_records.first[:value] == load_balancer.dns_name #???
expect(record_set.ttl).to eq(60)
end
I don't think there is any special behavior. I think you've found errors in the test code.
This doesn't work because there's no assertion, only a comparison:
#numbers.permutation(9).entries.size == 0
It would need to be written as:
#numbers.permutation(9).entries.size.should == 0
Or using the newer RSpec syntax:
expect(#numbers.permutation(9).entries.size).to eq(0)

Get value from JSON response in Ruby

I am making a JSON call to a Ruby on Rails server via a client side ruby script, which returns the following JSON:
get_data.rb
require 'net/http'
require 'open-uri'
require 'json'
def get_functions(serial_number, function)
request_uri = "http://localhost:3000/devices/#{serial_number}"
buffer = open(request_uri).read
result = JSON.parse(buffer)
puts result
end
{ "serial_number" => "111aaa",
"device_functions" => [
{ "can_scan" => true,
"can_halt" => true
}
],
"host_options" => [
{ "exclude_ip" => "10.10.10.100-110",
"scan_ip" => "10.10.10.1"
}
]
}
Now, I'm wanting to just extract certain values from the response to determine what can/cannot be done on the client side:
scan.rb
if get_functions('111aaa', 'can_scan')
result = %x( ping 10.10.10.1 )
else
result = "Not allowed to perform action!"
end
I'm stuck with how I can extract the value of can_scan from my JSON in get_data.rb for my get_functions method to be able to run its if statement correctly.
Your get_functions is returning nil as the last line is an I/O operation (puts). Change your function to:
def get_functions(serial_number, function)
request_uri = "http://localhost:3000/devices/#{serial_number}"
buffer = open(request_uri).read
result = JSON.parse(buffer)
puts result
result
end
And access the Hash:
result = get_functions(serial_number, function)
result["device_functions"].first["can_scan"]

Dynamically check if a field in JSON is nil without using eval

Here's an extract of the code that I am using:
def retrieve(user_token, quote_id, check="quotes")
end_time = Time.now + 15
match = false
until Time.now > end_time || match
#response = http_request.get(quote_get_url(quote_id, user_token))
eval("match = !JSON.parse(#response.body)#{field(check)}.nil?")
end
match.eql?(false) ? nil : #response
end
private
def field (check)
hash = {"quotes" => '["quotes"][0]',
"transaction-items" => '["quotes"][0]["links"]["transactionItems"]'
}
hash[check]
end
I was informed that using eval in this manner is not good practice. Could anyone suggest a better way of dynamically checking the existence of a JSON node (field?). I want this to do:
psudo: match = !JSON.parse(#response.body) + dynamic-path + .nil?
Store paths as arrays of path elements (['quotes', 0]). With a little helper function you'll be able to avoid eval. It is, indeed, completely inappropriate here.
Something along these lines:
class Hash
def deep_get(path)
path.reduce(self) do |memo, path_element|
return unless memo
memo[path_element]
end
end
end
path = ['quotes', 0]
hash = JSON.parse(response.body)
match = !hash.deep_get(path).nil?

Resources