Commit ca16c373 authored by Timothy Andrew's avatar Timothy Andrew

Extract code from `Namespace#clean_path` for ghost user generation.

1. Create a `Uniquify` class, which generalizes the process of generating unique
   strings, by accepting a function that defines what "uniqueness" means in a
   given context.

2. WIP: Make sure tests for `Namespace` pass, add more if necessary.

3. WIP: Add tests for `Uniquify`
parent ff19bbd3
class Uniquify
# Return a version of the given 'base' string that is unique
# by appending a counter to it. Uniqueness is determined by
# repeated calls to `exists_fn`.
#
# If `base` is a function/proc, we expect that calling it with a
# candidate counter returns a string to test/return.
def string(base, exists_fn)
@counter = nil
if base.respond_to?(:call)
increment_counter! while exists_fn[base.call(@counter)]
base.call(@counter)
else
increment_counter! while exists_fn["#{base}#{@counter}"]
"#{base}#{@counter}"
end
end
private
def increment_counter!
@counter = @counter ? @counter.next : 1
end
end
...@@ -98,14 +98,8 @@ class Namespace < ActiveRecord::Base ...@@ -98,14 +98,8 @@ class Namespace < ActiveRecord::Base
# Work around that by setting their username to "blank", followed by a counter. # Work around that by setting their username to "blank", followed by a counter.
path = "blank" if path.blank? path = "blank" if path.blank?
counter = 0 uniquify = Uniquify.new
base = path uniquify.string(path, -> (s) { Namespace.find_by_path_or_name(s) })
while Namespace.find_by_path_or_name(path)
counter += 1
path = "#{base}#{counter}"
end
path
end end
end end
......
...@@ -351,20 +351,19 @@ class User < ActiveRecord::Base ...@@ -351,20 +351,19 @@ class User < ActiveRecord::Base
ghost_user || ghost_user ||
begin begin
users = Enumerator.new do |y| uniquify = Uniquify.new
n = nil
loop do username = uniquify.string("ghost", -> (s) { User.find_by_username(s) })
user = User.new(
username: "ghost#{n}", password: Devise.friendly_token, email = uniquify.string(
email: "ghost#{n}@example.com", name: "Ghost User", state: :ghost -> (n) { "ghost#{n}@example.com" },
) -> (s) { User.find_by_email(s) }
)
y.yield(user)
n = n ? n.next : 0 User.create(
end username: username, password: Devise.friendly_token,
end email: email, name: "Ghost User", state: :ghost
)
users.lazy.select { |user| user.valid? }.first.tap(&:save!)
end end
end end
end end
......
...@@ -1513,7 +1513,7 @@ describe User, models: true do ...@@ -1513,7 +1513,7 @@ describe User, models: true do
ghost = User.ghost ghost = User.ghost
expect(ghost).to be_persisted expect(ghost).to be_persisted
expect(ghost.username).to eq('ghost0') expect(ghost.username).to eq('ghost1')
end end
end end
...@@ -1523,7 +1523,7 @@ describe User, models: true do ...@@ -1523,7 +1523,7 @@ describe User, models: true do
ghost = User.ghost ghost = User.ghost
expect(ghost).to be_persisted expect(ghost).to be_persisted
expect(ghost.email).to eq('ghost0@example.com') expect(ghost.email).to eq('ghost1@example.com')
end end
end end
end end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment