365 lines
12 KiB
Ruby
365 lines
12 KiB
Ruby
|
require_relative '../../spec_helper'
|
||
|
require_relative '../../../app/controllers/admin/pages_controller'
|
||
|
require_relative '../../factories/organizations_contexts'
|
||
|
require_relative '../../factories/carto_visualizations'
|
||
|
|
||
|
def app
|
||
|
CartoDB::Application.new
|
||
|
end #app
|
||
|
|
||
|
describe Admin::PagesController do
|
||
|
include Rack::Test::Methods
|
||
|
include Warden::Test::Helpers
|
||
|
|
||
|
JSON_HEADER = {'CONTENT_TYPE' => 'application/json'}
|
||
|
|
||
|
before(:all) do
|
||
|
|
||
|
@non_org_user_name = 'development'
|
||
|
|
||
|
@org_name = 'foobar'
|
||
|
@org_user_name = 'foo'
|
||
|
|
||
|
@other_org_user_name = 'other'
|
||
|
|
||
|
@belongs_to_org = true
|
||
|
@user_org = true
|
||
|
end
|
||
|
|
||
|
describe '#index' do
|
||
|
before(:each) do
|
||
|
host! "#{@org_name}.localhost.lan"
|
||
|
end
|
||
|
|
||
|
it 'returns 404 if user does not belongs to host organization' do
|
||
|
user = prepare_user(@non_org_user_name)
|
||
|
|
||
|
get "/u/#{@non_org_user_name}", {}, JSON_HEADER
|
||
|
|
||
|
last_response.status.should == 404
|
||
|
|
||
|
user.delete
|
||
|
end
|
||
|
|
||
|
it 'returns 200 if it is an org user and belongs to host organization' do
|
||
|
user = prepare_user(@org_user_name, @user_org, @belongs_to_org)
|
||
|
|
||
|
get "/u/#{@org_user_name}", {}, JSON_HEADER
|
||
|
|
||
|
last_response.status.should == 200
|
||
|
|
||
|
user.delete
|
||
|
end
|
||
|
|
||
|
it 'redirects_to dashboard if organization user is logged in' do
|
||
|
user = prepare_user(@org_user_name, @user_org, @belongs_to_org)
|
||
|
|
||
|
login_as(user, scope: user.username)
|
||
|
|
||
|
get "/u/#{@org_user_name}", {}, JSON_HEADER
|
||
|
|
||
|
last_response.status.should == 302
|
||
|
|
||
|
follow_redirect!
|
||
|
|
||
|
uri = URI.parse(last_request.url)
|
||
|
uri.host.should == "#{@org_name}.localhost.lan"
|
||
|
uri.path.should == "/u/#{@org_user_name}/dashboard"
|
||
|
|
||
|
user.delete
|
||
|
end
|
||
|
|
||
|
it 'redirects if it is an org user but gets called without organization' do
|
||
|
user = prepare_user(@org_user_name, @user_org, @belongs_to_org)
|
||
|
|
||
|
host! "#{@org_user_name}.localhost.lan"
|
||
|
get "", {}, JSON_HEADER
|
||
|
|
||
|
last_response.status.should == 302
|
||
|
follow_redirect!
|
||
|
last_response.status.should == 200
|
||
|
|
||
|
user.delete
|
||
|
end
|
||
|
|
||
|
it 'returns 404 if it is an org user but does NOT belong to host organization' do
|
||
|
user = prepare_user(@other_org_user_name, @user_org, !@belongs_to_org)
|
||
|
|
||
|
get "/u/#{@other_org_user_name}", {}, JSON_HEADER
|
||
|
|
||
|
last_response.status.should == 404
|
||
|
|
||
|
user.delete
|
||
|
end
|
||
|
|
||
|
it 'returns 404 if user does NOT exist' do
|
||
|
get '/u/non-exitant-user', {}, JSON_HEADER
|
||
|
|
||
|
last_response.status.should == 404
|
||
|
end
|
||
|
|
||
|
it 'redirects to user feed home if current user and current viewer are different' do
|
||
|
anyuser = prepare_user('anyuser')
|
||
|
anyviewer = prepare_user('anyviewer')
|
||
|
login_as(anyviewer, scope: anyviewer.username)
|
||
|
host! "#{anyuser.username}.localhost.lan"
|
||
|
|
||
|
get '', {}, JSON_HEADER
|
||
|
|
||
|
last_response.status.should == 302
|
||
|
follow_redirect!
|
||
|
last_response.status.should == 200
|
||
|
uri = URI.parse(last_request.url)
|
||
|
uri.host.should == 'anyuser.localhost.lan'
|
||
|
uri.path.should == '/me'
|
||
|
|
||
|
[anyuser, anyviewer].each(&:delete)
|
||
|
end
|
||
|
|
||
|
it 'redirects to user feed if not logged in' do
|
||
|
user = prepare_user('anyuser')
|
||
|
host! 'anyuser.localhost.lan'
|
||
|
|
||
|
get '', {}, JSON_HEADER
|
||
|
|
||
|
last_response.status.should == 302
|
||
|
uri = URI.parse(last_response.location)
|
||
|
uri.host.should == 'anyuser.localhost.lan'
|
||
|
uri.path.should == '/me'
|
||
|
follow_redirect!
|
||
|
last_response.status.should == 200
|
||
|
|
||
|
user.delete
|
||
|
end
|
||
|
|
||
|
it 'redirects to local login page if no user is specified and Central is not enabled' do
|
||
|
Cartodb.with_config(cartodb_central_api: {}) do
|
||
|
user = prepare_user('anyuser')
|
||
|
host! 'localhost.lan'
|
||
|
CartoDB.stubs(:session_domain).returns('localhost.lan')
|
||
|
CartoDB.stubs(:subdomainless_urls?).returns(true)
|
||
|
|
||
|
get '', {}, JSON_HEADER
|
||
|
|
||
|
last_response.status.should == 302
|
||
|
uri = URI.parse(last_response.location)
|
||
|
uri.host.should == 'localhost.lan'
|
||
|
uri.path.should == '/login'
|
||
|
follow_redirect!
|
||
|
last_response.status.should == 200
|
||
|
|
||
|
user.delete
|
||
|
end
|
||
|
end
|
||
|
|
||
|
it 'redirects to Central login page if no user is specified and Central is enabled' do
|
||
|
central_host = 'somewhere.lan'
|
||
|
central_port = 4321
|
||
|
Cartodb.with_config(
|
||
|
cartodb_central_api: {
|
||
|
'host' => central_host,
|
||
|
'port' => central_port,
|
||
|
'username' => 'api',
|
||
|
'password' => 'test'
|
||
|
}
|
||
|
) do
|
||
|
user = prepare_user('anyuser')
|
||
|
host! 'localhost.lan'
|
||
|
CartoDB.stubs(:session_domain).returns('localhost.lan')
|
||
|
CartoDB.stubs(:subdomainless_urls?).returns(true)
|
||
|
|
||
|
get '', {}, JSON_HEADER
|
||
|
|
||
|
last_response.status.should == 302
|
||
|
uri = URI.parse(last_response.location)
|
||
|
uri.host.should == 'localhost.lan'
|
||
|
uri.path.should == '/login'
|
||
|
follow_redirect!
|
||
|
|
||
|
last_response.status.should == 302
|
||
|
uri = URI.parse(last_response.location)
|
||
|
uri.host.should == central_host
|
||
|
uri.port.should == central_port
|
||
|
uri.path.should == '/login'
|
||
|
follow_redirect!
|
||
|
|
||
|
user.delete
|
||
|
end
|
||
|
end
|
||
|
|
||
|
it 'redirects and loads the dashboard if the user is logged in' do
|
||
|
anyuser = prepare_user('anyuser')
|
||
|
host! 'localhost.lan'
|
||
|
login_as(anyuser, scope: anyuser.username)
|
||
|
CartoDB.stubs(:session_domain).returns('localhost.lan')
|
||
|
CartoDB.stubs(:subdomainless_urls?).returns(true)
|
||
|
|
||
|
get '', {}, JSON_HEADER
|
||
|
|
||
|
last_response.status.should == 302
|
||
|
uri = URI.parse(last_response.location)
|
||
|
uri.host.should == 'localhost.lan'
|
||
|
uri.path.should == '/user/anyuser/dashboard'
|
||
|
|
||
|
anyuser.delete
|
||
|
end
|
||
|
|
||
|
it 'extracts username from redirection for dashboard with subdomainless' do
|
||
|
# we use this to avoid generating the static assets in CI
|
||
|
Admin::VisualizationsController.any_instance.stubs(:render).returns('')
|
||
|
|
||
|
username = 'endedwithu'
|
||
|
anyuser = prepare_user(username)
|
||
|
host! 'localhost.lan'
|
||
|
login_as(anyuser, scope: anyuser.username)
|
||
|
CartoDB.stubs(:session_domain).returns('localhost.lan')
|
||
|
CartoDB.stubs(:subdomainless_urls?).returns(true)
|
||
|
|
||
|
get '', {}, JSON_HEADER
|
||
|
|
||
|
last_response.status.should == 302
|
||
|
uri = URI.parse(last_response.location)
|
||
|
uri.host.should == 'localhost.lan'
|
||
|
uri.path.should == "/user/#{username}/dashboard"
|
||
|
|
||
|
login_as(anyuser, scope: anyuser.username)
|
||
|
location = last_response.location
|
||
|
User.any_instance.stubs(:db_size_in_bytes).returns(0)
|
||
|
get location
|
||
|
last_response.status.should == 200
|
||
|
|
||
|
anyuser.delete
|
||
|
end
|
||
|
|
||
|
it 'redirects to login without login' do
|
||
|
host! 'localhost.lan'
|
||
|
|
||
|
get '', {}, JSON_HEADER
|
||
|
|
||
|
uri = URI.parse(last_response.location)
|
||
|
uri.host.should == 'localhost.lan'
|
||
|
uri.path.should == "/login"
|
||
|
end
|
||
|
end
|
||
|
|
||
|
describe '#sitemap' do
|
||
|
include Carto::Factories::Visualizations
|
||
|
it 'should return 404 if no user or organization is provided' do
|
||
|
get '/sitemap.xml'
|
||
|
last_response.status.should == 404
|
||
|
end
|
||
|
|
||
|
describe 'for organizations' do
|
||
|
include_context 'organization with users helper'
|
||
|
|
||
|
before(:each) do
|
||
|
host! "#{@carto_organization.name}.localhost.lan:#{Cartodb.config[:http_port]}"
|
||
|
end
|
||
|
|
||
|
it 'returns an empty body if there are not visualizations' do
|
||
|
get public_sitemap_url(user_domain: @carto_organization.name)
|
||
|
document = Nokogiri::XML(last_response.body)
|
||
|
document.child.child.text.should eq "\n"
|
||
|
end
|
||
|
|
||
|
it 'returns public and published visualizations' do
|
||
|
private_attrs = { privacy: Carto::Visualization::PRIVACY_PRIVATE }
|
||
|
create_full_visualization(@carto_org_user_1, visualization_attributes: private_attrs)
|
||
|
unpublished_attrs = { privacy: Carto::Visualization::PRIVACY_PUBLIC, version: 3 }
|
||
|
create_full_visualization(@carto_org_user_1, visualization_attributes: unpublished_attrs)
|
||
|
public_attrs = { privacy: Carto::Visualization::PRIVACY_PUBLIC }
|
||
|
_, _, _, visualization = create_full_visualization(@carto_org_user_1, visualization_attributes: public_attrs)
|
||
|
get public_sitemap_url(user_domain: @carto_organization.name)
|
||
|
last_response.status.should eq 200
|
||
|
document = Nokogiri::XML(last_response.body)
|
||
|
url_and_dates = document.search('url').map { |url| [url.at('loc').text, url.at('lastmod').text] }
|
||
|
url_and_dates.count.should eq 1
|
||
|
|
||
|
url1 = public_visualizations_public_map_url(user_domain: @carto_org_user_1.username, id: visualization.id)
|
||
|
url_and_dates.map { |url_and_date| url_and_date[0] }.should eq [url1.gsub(/\/user\/[^\/]*\//, '/')]
|
||
|
end
|
||
|
end
|
||
|
|
||
|
describe 'for users' do
|
||
|
include_context 'users helper'
|
||
|
|
||
|
before(:each) do
|
||
|
host! "#{@carto_user1.username}.localhost.lan:#{Cartodb.config[:http_port]}"
|
||
|
end
|
||
|
|
||
|
it 'returns public and published visualizations' do
|
||
|
private_attrs = { privacy: Carto::Visualization::PRIVACY_PRIVATE }
|
||
|
create_full_visualization(@carto_user1, visualization_attributes: private_attrs)
|
||
|
unpublished_attrs = { privacy: Carto::Visualization::PRIVACY_PUBLIC, version: 3 }
|
||
|
create_full_visualization(@carto_user1, visualization_attributes: unpublished_attrs)
|
||
|
public_attrs = { privacy: Carto::Visualization::PRIVACY_PUBLIC }
|
||
|
_, _, _, visualization = create_full_visualization(@carto_user1, visualization_attributes: public_attrs)
|
||
|
get public_sitemap_url(user_domain: @carto_user1.username)
|
||
|
last_response.status.should eq 200
|
||
|
document = Nokogiri::XML(last_response.body)
|
||
|
url_and_dates = document.search('url').map { |url| [url.at('loc').text, url.at('lastmod').text] }
|
||
|
url_and_dates.count.should eq 1
|
||
|
|
||
|
url1 = public_visualizations_public_map_url(id: visualization.id)
|
||
|
url_and_dates.map { |url_and_date| url_and_date[0] }.should eq [url1.gsub(/\/user\/[^\/]*\//, '/')]
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
describe '#datasets' do
|
||
|
include_context 'users helper'
|
||
|
|
||
|
before(:each) do
|
||
|
host! "#{@carto_user1.username}.localhost.lan:#{Cartodb.config[:http_port]}"
|
||
|
Carto::Visualization.find_each(&:destroy)
|
||
|
end
|
||
|
|
||
|
it 'returns 200 if a dataset has no table' do
|
||
|
FactoryGirl.create(:table_visualization, user_id: @carto_user1.id, privacy: Carto::Visualization::PRIVACY_PUBLIC)
|
||
|
Carto::Visualization.count.should eql 1
|
||
|
visualization = Carto::Visualization.first
|
||
|
visualization.table.should be_nil
|
||
|
|
||
|
get public_datasets_home_url(user_domain: @carto_user1.username)
|
||
|
|
||
|
last_response.status.should == 200
|
||
|
last_response.body.should =~ /doesn\'t have any items/
|
||
|
end
|
||
|
end
|
||
|
|
||
|
def mock_explore_feature_flag
|
||
|
anyuser = prepare_user('anyuser')
|
||
|
::User.any_instance.stubs(:has_feature_flag?)
|
||
|
.with('explore_site')
|
||
|
.returns(true)
|
||
|
::User.stubs(:where).returns(anyuser)
|
||
|
anyuser.stubs(:first).returns(anyuser)
|
||
|
anyuser
|
||
|
end
|
||
|
|
||
|
def prepare_user(user_name, org_user=false, belongs_to_org=false)
|
||
|
user = create_user(
|
||
|
username: user_name,
|
||
|
email: "#{user_name}@example.com",
|
||
|
password: 'longer_than_MIN_PASSWORD_LENGTH',
|
||
|
fake_user: true,
|
||
|
quota_in_bytes: 10000000
|
||
|
)
|
||
|
|
||
|
user.stubs(:username => user_name, :organization_user? => org_user)
|
||
|
|
||
|
if org_user
|
||
|
org = mock
|
||
|
org.stubs(name: @org_name)
|
||
|
org.stubs(password_expiration_in_d: nil)
|
||
|
user.stubs(organization: org)
|
||
|
Organization.stubs(:where).with(name: @org_name).returns([org])
|
||
|
Organization.stubs(:where).with(name: @org_user_name).returns([org])
|
||
|
::User.any_instance.stubs(:belongs_to_organization?).with(org).returns(belongs_to_org)
|
||
|
end
|
||
|
|
||
|
user
|
||
|
end
|
||
|
|
||
|
end
|