Commit 58f138de authored by Ash McKenzie's avatar Ash McKenzie

Merge branch 'username_suggests' into 'master'

[Backend] API for username suggestions

See merge request gitlab-org/gitlab-ee!15048
parents 859130d6 26119429
......@@ -109,6 +109,7 @@ Rails.application.routes.draw do
Gitlab.ee do
draw :smartcard
draw :jira_connect
draw :username
end
Gitlab.ee do
......
# frozen_string_literal: true
class UsernamesController < ApplicationController
skip_before_action :authenticate_user!, only: [:suggest]
def suggest
if validate_params
username = ::User.username_suggestion(params[:name])
render json: { username: username }, status: :ok
else
render json: { message: 'Invalid input provided' }, status: :bad_request
end
end
private
def validate_params
!params[:name].blank?
end
end
......@@ -13,6 +13,7 @@ module EE
DEFAULT_ROADMAP_LAYOUT = 'months'.freeze
DEFAULT_GROUP_VIEW = 'details'.freeze
MAX_USERNAME_SUGGESTION_ATTEMPTS = 15
prepended do
EMAIL_OPT_IN_SOURCE_ID_GITLAB_COM = 1
......@@ -126,6 +127,19 @@ module EE
joins(:smartcard_identities)
.find_by(smartcard_identities: { subject: certificate_subject, issuer: certificate_issuer })
end
def username_suggestion(base_name)
suffix = nil
base_name = base_name.parameterize(separator: '_')
MAX_USERNAME_SUGGESTION_ATTEMPTS.times do |attempt|
username = "#{base_name}#{suffix}"
return username unless ::Namespace.find_by_path_or_name(username)
suffix = attempt + 1
end
''
end
end
def cannot_be_admin_and_auditor
......
---
title: Adds an api to generate suggestions for username
merge_request: 15048
author:
type: added
# frozen_string_literal: true
scope :username do
get 'suggestion', to: 'usernames#suggest'
end
# frozen_string_literal: true
require 'spec_helper'
describe UsernamesController do
describe 'GET #suggest' do
context 'namespace does not exist' do
it 'returns JSON with the suggested username' do
get :suggest, params: { name: 'Arthur' }
expected_json = { username: 'arthur' }.to_json
expect(response.body).to eq(expected_json)
end
end
context 'namespace exists' do
before do
create(:user, name: 'disney')
end
it 'returns JSON with the parameterized username and suffix as a suggestion' do
get :suggest, params: { name: 'Disney' }
expected_json = { username: 'disney1' }.to_json
expect(response.body).to eq(expected_json)
end
end
context 'no name provided' do
it 'returns bad request response' do
get :suggest
expect(response.status).to eq(400)
end
end
end
end
......@@ -597,4 +597,59 @@ describe User do
end
end
end
describe '.username_suggestion' do
context 'namespace with input name does not exist' do
let(:name) { 'Arthur Morgan' }
it 'returns the parameterized name' do
username = described_class.username_suggestion(name)
expect(username).to eq('arthur_morgan')
end
end
context 'namespace with input name exists' do
let(:name) { 'Disney' }
before do
create(:user, name: 'disney')
end
it 'returns the parameterized name with a suffix' do
username = described_class.username_suggestion(name)
expect(username).to eq('disney1')
end
end
context 'namespace with input name and suffix exists' do
let(:name) { 'Disney' }
before do
create(:user, name: 'disney')
create(:user, name: 'disney1')
end
it 'loops through parameterized name with suffixes, until it finds one that does not exist' do
username = described_class.username_suggestion(name)
expect(username).to eq('disney2')
end
end
context 'when max attempts for suggestion is exceeded' do
let(:name) { 'Disney' }
let(:max_attempts) { described_class::MAX_USERNAME_SUGGESTION_ATTEMPTS }
before do
allow(::Namespace).to receive(:find_by_path_or_name).with("disney").and_return(true)
max_attempts.times { |count| allow(::Namespace).to receive(:find_by_path_or_name).with("disney#{count}").and_return(true) }
end
it 'returns an empty response' do
username = described_class.username_suggestion(name)
expect(username).to eq('')
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