Skip to content

Commit

Permalink
Added RandomUniqueId::Util.set_initial_ids that helps with testing ap…
Browse files Browse the repository at this point in the history
…ps that use rids.
  • Loading branch information
pupeno committed Oct 28, 2014
1 parent 37ea6b4 commit 4dd67e5
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 2 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
Authoritative changelog in README.md.

## Next version
- Added RandomUniqueId::Util.set_initial_ids.
- Started testing Ruby 2.1.2 and 2.1.3.
- Started testing Rails 4.1 (fixed some deprecation warnings).
- Improved documentation
- Improved documentation.

## Version 0.2.1 (May 27, 2014)
- Internal refactorings.
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,10 @@ records. For example:
## Changelog

### Next version
- Added RandomUniqueId::Util.set_initial_ids.
- Started testing Ruby 2.1.2 and 2.1.3.
- Started testing Rails 4.1 (fixed some deprecation warnings).
- Improved documentation
- Improved documentation.

### Version 0.2.1 (May 27, 2014)
- Internal refactorings.
Expand Down
38 changes: 38 additions & 0 deletions lib/random_unique_id/util.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Copyright © 2014, Watu

# Some utilities that might be useful if you are using RandomUniqueId. This file needs to be explicitely included:
#
# require "random_unique_id/util"
module RandomUniqueId::Util
# Set the initial automatic ids on the database (also known as sequences) to a higher number than 1. The reason to use
# this is in case you want to test for id leakage in HTML. For example, you create a blog post, display it, and search
# the HTML for the id of the blog post, author, featured image, and so on. If these ids are low, like 1 or 10, the
# likelihood of false positives is very high, but if they are larger numbers, like 10001, then it becomes very
# unlikely (but not impossible).
#
# @param [Hash] options
# @option options [Boolean] :verbose whether to print messages to the console about what's going on or not.
# @option options [Integer] :initial_id initial id at which the sequences will be set.
def self.set_initial_ids(options={})
options.reverse_merge!(verbose: false, initial_id: 10000)
verbose = options[:verbose]
initial_id = options[:initial_id]

sql_connection = ActiveRecord::Base.connection
case sql_connection.adapter_name
when "PostgreSQL"
puts "== Setting initial ids to #{initial_id} or the next available one".ljust(79, "=") if verbose
sequences = sql_connection.select_values("SELECT c.relname FROM pg_class c WHERE c.relkind = 'S'")
sequences.each do |sequence|
print "-- Setting initial id for #{sequence} to..." if verbose
next_id = [initial_id, sql_connection.select_values("SELECT nextval('#{sequence}')").first.to_i].max
print "#{next_id}..." if verbose
sql_connection.execute("SELECT setval('#{sequence}', #{next_id})")
puts " done." if verbose
end
puts "== Setting initial ids to #{initial_id} (done) ".ljust(79, "=") if verbose
else
raise "Don't know how to set initial ids for #{sql_connection.adapter_name}. Would you like to contribute? https://github.com/watu/random_unique_id"
end
end
end
28 changes: 28 additions & 0 deletions test/random_unique_id/util_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Copyright © 2014, Watu

require_relative "../test_helper"

require "random_unique_id/util"

class RandomUniqueId::UtilTest < MiniTest::Unit::TestCase
should "raise an exception for unknown adapters" do
sql_connection = stub("connection", adapter_name: "dBASE")
ActiveRecord::Base.expects(:connection).returns(sql_connection)
assert_raises RuntimeError do
RandomUniqueId::Util.set_initial_ids
end
end

should "set initial ids in PostgreSQL" do
sql_connection = mock("connection")
sql_connection.stubs(:adapter_name).returns("PostgreSQL")
sequences = ["sequence_1", "sequence_2"]
sql_connection.expects(:select_values).with("SELECT c.relname FROM pg_class c WHERE c.relkind = 'S'").returns(sequences)
sql_connection.expects(:select_values).with("SELECT nextval('sequence_1')").returns(["1"])
sql_connection.expects(:execute).with("SELECT setval('sequence_1', 10000)")
sql_connection.expects(:select_values).with("SELECT nextval('sequence_2')").returns(["20000"])
sql_connection.expects(:execute).with("SELECT setval('sequence_2', 20000)")
ActiveRecord::Base.expects(:connection).returns(sql_connection)
RandomUniqueId::Util.set_initial_ids
end
end

0 comments on commit 4dd67e5

Please sign in to comment.