Initial commit
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
module AccountTypesHelper
|
||||
def create_account_type(account_type_name)
|
||||
rate_limit = Carto::RateLimit.create!(maps_anonymous: Carto::RateLimitValues.new([0, 1, 2]),
|
||||
maps_static: Carto::RateLimitValues.new([3, 4, 5]),
|
||||
maps_static_named: Carto::RateLimitValues.new([6, 7, 8]),
|
||||
maps_dataview: Carto::RateLimitValues.new([9, 10, 11]),
|
||||
maps_dataview_search: Carto::RateLimitValues.new([9, 10, 11]),
|
||||
maps_analysis: Carto::RateLimitValues.new([12, 13, 14]),
|
||||
maps_tile: Carto::RateLimitValues.new([15, 16, 17, 30, 32, 34]),
|
||||
maps_attributes: Carto::RateLimitValues.new([18, 19, 20]),
|
||||
maps_named_list: Carto::RateLimitValues.new([21, 22, 23]),
|
||||
maps_named_create: Carto::RateLimitValues.new([24, 25, 26]),
|
||||
maps_named_get: Carto::RateLimitValues.new([27, 28, 29]),
|
||||
maps_named: Carto::RateLimitValues.new([30, 31, 32]),
|
||||
maps_named_update: Carto::RateLimitValues.new([33, 34, 35]),
|
||||
maps_named_delete: Carto::RateLimitValues.new([36, 37, 38]),
|
||||
maps_named_tiles: Carto::RateLimitValues.new([39, 40, 41]),
|
||||
maps_analysis_catalog: Carto::RateLimitValues.new([1, 1, 1]),
|
||||
sql_query: Carto::RateLimitValues.new([0, 1, 2]),
|
||||
sql_query_format: Carto::RateLimitValues.new([3, 4, 5]),
|
||||
sql_job_create: Carto::RateLimitValues.new([6, 7, 8]),
|
||||
sql_job_get: Carto::RateLimitValues.new([9, 10, 11]),
|
||||
sql_job_delete: Carto::RateLimitValues.new([12, 13, 14]),
|
||||
sql_copy_from: Carto::RateLimitValues.new([1, 1, 60]),
|
||||
sql_copy_to: Carto::RateLimitValues.new([1, 1, 60]))
|
||||
|
||||
account_type = Carto::AccountType.new
|
||||
account_type.rate_limit_id = rate_limit.id
|
||||
account_type.account_type = account_type_name || 'FREE'
|
||||
|
||||
account_type.save! unless Carto::AccountType.exists?(account_type.account_type)
|
||||
end
|
||||
|
||||
def create_account_type_fg(account_type)
|
||||
account_type ||= 'FREE'
|
||||
get_account_type(account_type) || new_account_type(account_type)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def get_account_type(account_type)
|
||||
Carto::AccountType.find(account_type)
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
end
|
||||
|
||||
def new_account_type(account_type)
|
||||
if account_type == 'PRO'
|
||||
FactoryGirl.create(:account_type_pro)
|
||||
else
|
||||
FactoryGirl.create(:account_type, account_type: account_type)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,49 @@
|
||||
require 'spec_helper_min'
|
||||
|
||||
describe ApplicationHelper do
|
||||
describe '#app_assets_base_url' do
|
||||
before(:each) do
|
||||
CartoDB.stubs(:protocol).returns('http')
|
||||
CartoDB.stubs(:http_port).returns(nil)
|
||||
end
|
||||
|
||||
describe 'with asset_host (SaaS)' do
|
||||
it 'returns asset_host' do
|
||||
Cartodb.stubs(:get_config).with(:app_assets, 'asset_host').returns('https://carto.global.ssl.fastly.net/cartodbui')
|
||||
|
||||
ApplicationHelper.app_assets_base_url.should eq 'https://carto.global.ssl.fastly.net/cartodbui/assets'
|
||||
end
|
||||
|
||||
it 'returns asset_host and adds the protocol if needed' do
|
||||
Cartodb.stubs(:get_config).with(:app_assets, 'asset_host').returns('//carto.global.ssl.fastly.net/cartodbui')
|
||||
|
||||
ApplicationHelper.app_assets_base_url.should eq 'http://carto.global.ssl.fastly.net/cartodbui/assets'
|
||||
end
|
||||
end
|
||||
|
||||
describe 'without asset_host' do
|
||||
before(:each) do
|
||||
Cartodb.stubs(:get_config).with(:app_assets, 'asset_host').returns('')
|
||||
request = mock
|
||||
request.stubs(:params).returns(user_domain: 'pepe')
|
||||
request.stubs(:host).returns('org.localhost.lan')
|
||||
|
||||
ApplicationHelper.stubs(:request).returns(request)
|
||||
end
|
||||
|
||||
it 'with subdomainful urls (OSS/dev) returns a subdomain' do
|
||||
CartoDB.stubs(:subdomainless_urls?).returns(false)
|
||||
CartoDB.stubs(:session_domain).returns('.localhost.lan')
|
||||
|
||||
ApplicationHelper.app_assets_base_url.should eq 'http://org.localhost.lan/assets'
|
||||
end
|
||||
|
||||
it 'with subdomainless urls (onpremise) returns the domain' do
|
||||
CartoDB.stubs(:subdomainless_urls?).returns(true)
|
||||
CartoDB.stubs(:session_domain).returns('localhost.lan')
|
||||
|
||||
ApplicationHelper.app_assets_base_url.should eq 'http://localhost.lan/assets'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,24 @@
|
||||
require 'active_support/core_ext/object/blank'
|
||||
require_relative '../../../app/helpers/carto/html_safe'
|
||||
|
||||
describe Carto::HtmlSafe do
|
||||
let(:html_safe) do
|
||||
class TestModule; include Carto::HtmlSafe; end.new
|
||||
end
|
||||
|
||||
it 'sets target="blank" for links' do
|
||||
link = 'http://www.carto.com'
|
||||
html_safe.markdown_html_safe("[text](#{link})").should eq "<p><a href=\"#{link}\" target=\"_blank\">text</a></p>\n"
|
||||
end
|
||||
|
||||
it 'does not set target="blank" for mailto markdown' do
|
||||
mailto = 'mailto:wadus@example.com'
|
||||
html_safe.markdown_html_safe("[text](#{mailto})").should eq "<p><a href=\"#{mailto}\">text</a></p>\n"
|
||||
end
|
||||
|
||||
it 'does not set target="blank" for mailto links' do
|
||||
mail = 'wadus@example.com'
|
||||
mailto = 'mailto:' + mail
|
||||
html_safe.markdown_html_safe("<#{mailto}>").should eq "<p><a href=\"#{mailto}\">#{mail}</a></p>\n"
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,55 @@
|
||||
require_relative '../simplecov_helper'
|
||||
require 'rails'
|
||||
require 'ostruct'
|
||||
require_relative '../rspec_configuration'
|
||||
require_relative '../../config/initializers/carto_db'
|
||||
|
||||
# Just "open" the modules so that we make sure they are defined,
|
||||
# but do not overwrite anything so that it doesn't affect other tests.
|
||||
module CartoDB
|
||||
module Cartodb; end
|
||||
end
|
||||
|
||||
describe 'CartoDB' do
|
||||
|
||||
describe '#ip?' do
|
||||
it 'detects ips' do
|
||||
CartoDB.ip?(nil).should == false
|
||||
CartoDB.ip?('').should == false
|
||||
CartoDB.ip?('.').should == false
|
||||
CartoDB.ip?('...').should == false
|
||||
CartoDB.ip?(192).should == false
|
||||
CartoDB.ip?('a').should == false
|
||||
CartoDB.ip?('a.b.c.d').should == false
|
||||
CartoDB.ip?('192.168.1.').should == false
|
||||
CartoDB.ip?('192.168.1.0').should == true
|
||||
end
|
||||
end
|
||||
|
||||
describe 'extract_subdomain' do
|
||||
it 'extracts subdomain without subdomainless_urls' do
|
||||
CartoDB::Cartodb.stubs(:config).returns(subdomainless_urls: false)
|
||||
CartoDB.stubs(:session_domain).returns('.localhost.lan')
|
||||
CartoDB.extract_subdomain(OpenStruct.new(host: 'localhost.lan', params: { user_domain: '' })).should == ''
|
||||
CartoDB.extract_subdomain(OpenStruct.new(host: 'localhost.lan', params: { user_domain: nil })).should == ''
|
||||
CartoDB.extract_subdomain(OpenStruct.new(host: 'auser.localhost.lan', params: { user_domain: 'auser' })).should == 'auser'
|
||||
CartoDB.extract_subdomain(OpenStruct.new(host: 'localhost.lan', params: { user_domain: 'auser' })).should == 'auser'
|
||||
CartoDB.extract_subdomain(OpenStruct.new(host: 'auser.localhost.lan', params: { user_domain: 'otheruser' })).should == 'otheruser'
|
||||
end
|
||||
|
||||
it 'extracts subdomain with subdomainless_urls' do
|
||||
CartoDB::Cartodb.stubs(:config).returns(subdomainless_urls: true)
|
||||
CartoDB.stubs(:session_domain).returns('localhost.lan')
|
||||
|
||||
CartoDB.extract_subdomain(OpenStruct.new(host: 'localhost.lan', params: { user_domain: '' })).should == ''
|
||||
CartoDB.extract_subdomain(OpenStruct.new(host: 'localhost.lan', params: { user_domain: nil })).should == ''
|
||||
CartoDB.extract_subdomain(OpenStruct.new(host: 'auser.localhost.lan', params: { user_domain: 'auser' })).should == 'auser'
|
||||
CartoDB.extract_subdomain(OpenStruct.new(host: 'localhost.lan', params: { user_domain: 'auser' })).should == 'auser'
|
||||
CartoDB.extract_subdomain(OpenStruct.new(host: 'auser.localhost.lan', params: { user_domain: 'otheruser' })).should == 'otheruser'
|
||||
|
||||
CartoDB.extract_subdomain(OpenStruct.new(host: '192.168.1.1', params: { user_domain: '' })).should == ''
|
||||
CartoDB.extract_subdomain(OpenStruct.new(host: '192.168.1.1', params: { user_domain: nil })).should == ''
|
||||
CartoDB.extract_subdomain(OpenStruct.new(host: '192.168.1.1', params: { user_domain: 'otheruser' })).should == 'otheruser'
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,31 @@
|
||||
module DatabaseConnectionHelper
|
||||
def with_connection(options)
|
||||
connection = ::Sequel.connect(options)
|
||||
begin
|
||||
yield connection
|
||||
ensure
|
||||
connection.disconnect
|
||||
end
|
||||
end
|
||||
|
||||
def with_connection_from_user(user, &block)
|
||||
options = ::SequelRails.configuration.environment_for(Rails.env).merge(
|
||||
'database' => user.database_name,
|
||||
'username' => user.database_username,
|
||||
'password' => user.database_password,
|
||||
'host' => user.database_host
|
||||
)
|
||||
with_connection options, &block
|
||||
end
|
||||
|
||||
def with_connection_from_api_key(api_key, &block)
|
||||
user = api_key.user
|
||||
options = ::SequelRails.configuration.environment_for(Rails.env).merge(
|
||||
'database' => user.database_name,
|
||||
'username' => api_key.db_role,
|
||||
'password' => api_key.db_password,
|
||||
'host' => user.database_host
|
||||
)
|
||||
with_connection options, &block
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,27 @@
|
||||
module FeatureFlagHelper
|
||||
def set_feature_flag(user, feature, state)
|
||||
user.reload
|
||||
previous_state = user.has_feature_flag?(feature)
|
||||
if state != previous_state
|
||||
ff = FeatureFlag[name: feature]
|
||||
ffu = FeatureFlagsUser[feature_flag_id: ff.id, user_id: user.id]
|
||||
if state
|
||||
unless ffu
|
||||
FeatureFlagsUser.new(feature_flag_id: ff.id, user_id: user.id).save
|
||||
end
|
||||
else
|
||||
ff.update restricted: false unless ff.restricted
|
||||
ffu.delete if ffu
|
||||
end
|
||||
user.reload
|
||||
end
|
||||
previous_state
|
||||
end
|
||||
|
||||
def with_feature_flag(user, feature, state)
|
||||
user.reload
|
||||
previous_state = set_feature_flag user, feature, state
|
||||
yield
|
||||
set_feature_flag user, feature, previous_state if state != previous_state
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,140 @@
|
||||
module FileServerHelper
|
||||
def serve_file(file_path, options = {})
|
||||
port = get_unused_port
|
||||
|
||||
require 'webrick'
|
||||
server = WEBrick::HTTPServer.new(
|
||||
AccessLog: [],
|
||||
Logger: WEBrick::Log::new("/dev/null", 7), # comment this line if weird things happen
|
||||
Port: port,
|
||||
DocumentRoot: File.dirname(file_path),
|
||||
RequestCallback: Proc.new do |_req, res|
|
||||
options[:headers].each { |k, v| res[k] = v } unless options[:headers].nil?
|
||||
unless options[:headers].nil? || options[:headers]['content-type'].nil?
|
||||
res.content_type = options[:headers]['content-type']
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
trap("INT") { server.shutdown }
|
||||
|
||||
a = Thread.new { server.start }
|
||||
|
||||
begin
|
||||
yield "http://localhost:#{port}/#{File.basename(file_path)}" if block_given?
|
||||
rescue => e
|
||||
raise e
|
||||
ensure
|
||||
b = Thread.new { server.shutdown }
|
||||
|
||||
b.join
|
||||
a.join
|
||||
end
|
||||
end
|
||||
|
||||
def get_unused_port
|
||||
used_ports_command = `netstat -tln | tail -n +3 | awk '{ print $4 }' | cut -f2 -d ':'`
|
||||
used_ports = used_ports_command.split("\n").map(&:to_i)
|
||||
|
||||
(10000..65535).each do |port|
|
||||
return port if !used_ports.include?(port)
|
||||
end
|
||||
|
||||
raise "No ports available on machine."
|
||||
end
|
||||
|
||||
def stub_download(url:, filepath:, headers: {}, content_disposition: true)
|
||||
Typhoeus.stub(url).and_return(response_for(filepath, headers, content_disposition: content_disposition))
|
||||
end
|
||||
|
||||
def stub_failed_download(options)
|
||||
url = options.fetch(:url)
|
||||
filepath = options.fetch(:filepath)
|
||||
headers = options.fetch(:headers, {})
|
||||
|
||||
Typhoeus.stub(url).and_return(failed_response_for(filepath, headers))
|
||||
end
|
||||
|
||||
def response_for(filepath, headers = {}, content_disposition: true)
|
||||
response = Typhoeus::Response.new(
|
||||
code: 200,
|
||||
body: File.new(filepath).read.to_s,
|
||||
headers: headers.merge(headers_for(filepath, content_disposition: content_disposition))
|
||||
)
|
||||
response
|
||||
end
|
||||
|
||||
def failed_response_for(_filepath, headers={})
|
||||
Typhoeus::Response.new(code: 404, body: nil, headers: {})
|
||||
end
|
||||
|
||||
def headers_for(filepath, content_disposition: true)
|
||||
return {} unless content_disposition
|
||||
filename = filepath.split('/').last
|
||||
{ "Content-Disposition" => "attachment; filename=#{filename}" }
|
||||
end
|
||||
|
||||
def stub_arcgis_response_with_file(
|
||||
absolute_filepath,
|
||||
absolute_metadata_filepath = File.expand_path('spec/fixtures/arcgis_metadata.json')
|
||||
)
|
||||
# Metadata of a layer
|
||||
Typhoeus.stub(/\/arcgis\/rest\/services\/Planning\/EPI_Primary_Planning_Layers\/MapServer\/2\?f=json/) do
|
||||
body = File.read(absolute_metadata_filepath)
|
||||
Typhoeus::Response.new(
|
||||
code: 200,
|
||||
headers: { 'Content-Type' => 'application/json' },
|
||||
body: body
|
||||
)
|
||||
end
|
||||
|
||||
# IDs list of a layer
|
||||
Typhoeus.stub(/\/arcgis\/rest\/(.*)query\?where=/) do
|
||||
json_file = JSON.parse(File.read(absolute_filepath))
|
||||
Typhoeus::Response.new(
|
||||
code: 200,
|
||||
headers: { 'Content-Type' => 'application/json' },
|
||||
body: JSON.dump(
|
||||
objectIdFieldName: "OBJECTID",
|
||||
objectIds: json_file['features'].map { |f| f['attributes']['OBJECTID'] }
|
||||
)
|
||||
)
|
||||
end
|
||||
|
||||
Typhoeus.stub(/\/arcgis\/rest\/(.*)query$/) do |request|
|
||||
response_body = File.read(absolute_filepath)
|
||||
response_body = ::JSON.parse(response_body)
|
||||
|
||||
request_body = request.options[:body]
|
||||
|
||||
requested_object_id = nil
|
||||
lower_match = nil
|
||||
upper_match = nil
|
||||
if request_body[:objectIds]
|
||||
requested_object_id = request_body[:objectIds]
|
||||
else
|
||||
lower_match = /OBJECTID\s+>=(\d+)/ =~ request.options[:body][:where]
|
||||
upper_match = /OBJECTID\s+<=(\d+)/ =~ request.options[:body][:where]
|
||||
end
|
||||
|
||||
response_body['features'] = response_body['features'].select do |f|
|
||||
object_id = f['attributes']['OBJECTID']
|
||||
if requested_object_id
|
||||
object_id == requested_object_id
|
||||
elsif lower_match && upper_match
|
||||
object_id >= lower_match[1].to_i && object_id <= upper_match[1].to_i
|
||||
elsif lower_match
|
||||
object_id >= lower_match[1].to_i
|
||||
elsif upper_match
|
||||
object_id <= upper_match[1].to_i
|
||||
end
|
||||
end
|
||||
|
||||
Typhoeus::Response.new(
|
||||
code: 200,
|
||||
headers: { 'Content-Type' => 'application/json' },
|
||||
body: ::JSON.dump(response_body)
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,5 @@
|
||||
module MetricsHelper
|
||||
def bypass_metrics
|
||||
Carto::Tracking::Events::Event.any_instance.stubs(:report!).returns(true)
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,15 @@
|
||||
module NamedMapsHelper
|
||||
def bypass_named_maps
|
||||
Carto::NamedMaps::Api.any_instance.stubs(show: nil, create: true, update: true, destroy: true)
|
||||
end
|
||||
|
||||
def bypass_named_maps_requests
|
||||
mocked_response = mock
|
||||
mocked_response.stubs(code: 200, response_body: '{}')
|
||||
|
||||
mocked_http_client = Carto::Http::Client.get('named_maps')
|
||||
mocked_http_client.stubs(:perform_request).returns(mocked_response)
|
||||
|
||||
Carto::NamedMaps::Api.any_instance.stubs(http_client: mocked_http_client, show: nil)
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,117 @@
|
||||
module RateLimitsHelper
|
||||
def expect_rate_limits_saved_to_redis(username)
|
||||
map_prefix = "limits:rate:store:#{username}:maps:"
|
||||
sql_prefix = "limits:rate:store:#{username}:sql:"
|
||||
|
||||
$limits_metadata.LRANGE("#{map_prefix}anonymous", 0, 2).should == ["0", "1", "2"]
|
||||
$limits_metadata.LRANGE("#{map_prefix}static", 0, 2).should == ["3", "4", "5"]
|
||||
$limits_metadata.LRANGE("#{map_prefix}static_named", 0, 2).should == ["6", "7", "8"]
|
||||
$limits_metadata.LRANGE("#{map_prefix}dataview", 0, 2).should == ["9", "10", "11"]
|
||||
$limits_metadata.LRANGE("#{map_prefix}dataview_search", 0, 2).should == ["9", "10", "11"]
|
||||
$limits_metadata.LRANGE("#{map_prefix}analysis", 0, 2).should == ["12", "13", "14"]
|
||||
$limits_metadata.LRANGE("#{map_prefix}tile", 0, 5).should == ["15", "16", "17", "30", "32", "34"]
|
||||
$limits_metadata.LRANGE("#{map_prefix}attributes", 0, 2).should == ["18", "19", "20"]
|
||||
$limits_metadata.LRANGE("#{map_prefix}named_list", 0, 2).should == ["21", "22", "23"]
|
||||
$limits_metadata.LRANGE("#{map_prefix}named_create", 0, 2).should == ["24", "25", "26"]
|
||||
$limits_metadata.LRANGE("#{map_prefix}named_get", 0, 2).should == ["27", "28", "29"]
|
||||
$limits_metadata.LRANGE("#{map_prefix}named", 0, 2).should == ["30", "31", "32"]
|
||||
$limits_metadata.LRANGE("#{map_prefix}named_update", 0, 2).should == ["33", "34", "35"]
|
||||
$limits_metadata.LRANGE("#{map_prefix}named_delete", 0, 2).should == ["36", "37", "38"]
|
||||
$limits_metadata.LRANGE("#{map_prefix}named_tiles", 0, 2).should == ["39", "40", "41"]
|
||||
$limits_metadata.LRANGE("#{map_prefix}analysis_catalog", 0, 2).should == ["1", "1", "1"]
|
||||
$limits_metadata.LRANGE("#{sql_prefix}query", 0, 2).should == ["0", "1", "2"]
|
||||
$limits_metadata.LRANGE("#{sql_prefix}query_format", 0, 2).should == ["3", "4", "5"]
|
||||
$limits_metadata.LRANGE("#{sql_prefix}job_create", 0, 2).should == ["6", "7", "8"]
|
||||
$limits_metadata.LRANGE("#{sql_prefix}job_get", 0, 2).should == ["9", "10", "11"]
|
||||
$limits_metadata.LRANGE("#{sql_prefix}job_delete", 0, 2).should == ["12", "13", "14"]
|
||||
$limits_metadata.LRANGE("#{sql_prefix}copy_from", 0, 2).should == ["1", "1", "60"]
|
||||
$limits_metadata.LRANGE("#{sql_prefix}copy_to", 0, 2).should == ["1", "1", "60"]
|
||||
end
|
||||
|
||||
def expect_rate_limits_custom_saved_to_redis(username)
|
||||
map_prefix = "limits:rate:store:#{username}:maps:"
|
||||
sql_prefix = "limits:rate:store:#{username}:sql:"
|
||||
|
||||
$limits_metadata.LRANGE("#{map_prefix}anonymous", 0, 2).should == ["10", "11", "12"]
|
||||
$limits_metadata.LRANGE("#{map_prefix}static", 0, 2).should == ["13", "14", "15"]
|
||||
$limits_metadata.LRANGE("#{map_prefix}static_named", 0, 2).should == ["16", "17", "18"]
|
||||
$limits_metadata.LRANGE("#{map_prefix}dataview", 0, 2).should == ["19", "110", "111"]
|
||||
$limits_metadata.LRANGE("#{map_prefix}dataview_search", 0, 2).should == ["19", "110", "111"]
|
||||
$limits_metadata.LRANGE("#{map_prefix}analysis", 0, 2).should == ["112", "113", "114"]
|
||||
$limits_metadata.LRANGE("#{map_prefix}tile", 0, 5).should == ["115", "116", "117", "230", "232", "234"]
|
||||
$limits_metadata.LRANGE("#{map_prefix}attributes", 0, 2).should == ["118", "119", "120"]
|
||||
$limits_metadata.LRANGE("#{map_prefix}named_list", 0, 2).should == ["121", "122", "123"]
|
||||
$limits_metadata.LRANGE("#{map_prefix}named_create", 0, 2).should == ["124", "125", "126"]
|
||||
$limits_metadata.LRANGE("#{map_prefix}named_get", 0, 2).should == ["127", "128", "129"]
|
||||
$limits_metadata.LRANGE("#{map_prefix}named", 0, 2).should == ["130", "131", "132"]
|
||||
$limits_metadata.LRANGE("#{map_prefix}named_update", 0, 2).should == ["133", "134", "135"]
|
||||
$limits_metadata.LRANGE("#{map_prefix}named_delete", 0, 2).should == ["136", "137", "138"]
|
||||
$limits_metadata.LRANGE("#{map_prefix}named_tiles", 0, 2).should == ["139", "140", "141"]
|
||||
$limits_metadata.LRANGE("#{map_prefix}analysis_catalog", 0, 2).should == ["11", "11", "11"]
|
||||
$limits_metadata.LRANGE("#{sql_prefix}query", 0, 2).should == ["10", "11", "12"]
|
||||
$limits_metadata.LRANGE("#{sql_prefix}query_format", 0, 2).should == ["13", "14", "15"]
|
||||
$limits_metadata.LRANGE("#{sql_prefix}job_create", 0, 2).should == ["16", "17", "18"]
|
||||
$limits_metadata.LRANGE("#{sql_prefix}job_get", 0, 2).should == ["19", "110", "111"]
|
||||
$limits_metadata.LRANGE("#{sql_prefix}job_delete", 0, 2).should == ["112", "113", "114"]
|
||||
$limits_metadata.LRANGE("#{sql_prefix}copy_from", 0, 2).should == ["11", "11", "160"]
|
||||
$limits_metadata.LRANGE("#{sql_prefix}copy_to", 0, 2).should == ["11", "11", "160"]
|
||||
end
|
||||
|
||||
def expect_rate_limits_pro_saved_to_redis(username)
|
||||
map_prefix = "limits:rate:store:#{username}:maps:"
|
||||
sql_prefix = "limits:rate:store:#{username}:sql:"
|
||||
|
||||
$limits_metadata.LRANGE("#{map_prefix}anonymous", 0, 2).should == ["1", "1", "2"]
|
||||
$limits_metadata.LRANGE("#{map_prefix}static", 0, 2).should == ["2", "4", "5"]
|
||||
$limits_metadata.LRANGE("#{map_prefix}static_named", 0, 2).should == ["3", "7", "8"]
|
||||
$limits_metadata.LRANGE("#{map_prefix}dataview", 0, 2).should == ["4", "10", "11"]
|
||||
$limits_metadata.LRANGE("#{map_prefix}dataview_search", 0, 2).should == ["4", "10", "11"]
|
||||
$limits_metadata.LRANGE("#{map_prefix}analysis", 0, 2).should == ["5", "13", "14"]
|
||||
$limits_metadata.LRANGE("#{map_prefix}tile", 0, 5).should == ["6", "16", "17", "30", "32", "34"]
|
||||
$limits_metadata.LRANGE("#{map_prefix}attributes", 0, 2).should == ["7", "19", "20"]
|
||||
$limits_metadata.LRANGE("#{map_prefix}named_list", 0, 2).should == ["8", "22", "23"]
|
||||
$limits_metadata.LRANGE("#{map_prefix}named_create", 0, 2).should == ["9", "25", "26"]
|
||||
$limits_metadata.LRANGE("#{map_prefix}named_get", 0, 2).should == ["10", "28", "29"]
|
||||
$limits_metadata.LRANGE("#{map_prefix}named", 0, 2).should == ["11", "31", "32"]
|
||||
$limits_metadata.LRANGE("#{map_prefix}named_update", 0, 2).should == ["12", "34", "35"]
|
||||
$limits_metadata.LRANGE("#{map_prefix}named_delete", 0, 2).should == ["13", "37", "38"]
|
||||
$limits_metadata.LRANGE("#{map_prefix}named_tiles", 0, 2).should == ["14", "40", "41"]
|
||||
$limits_metadata.LRANGE("#{map_prefix}analysis_catalog", 0, 2).should == ["111", "111", "111"]
|
||||
$limits_metadata.LRANGE("#{sql_prefix}query", 0, 2).should == ["1", "1", "2"]
|
||||
$limits_metadata.LRANGE("#{sql_prefix}query_format", 0, 2).should == ["2", "4", "5"]
|
||||
$limits_metadata.LRANGE("#{sql_prefix}job_create", 0, 2).should == ["3", "7", "8"]
|
||||
$limits_metadata.LRANGE("#{sql_prefix}job_get", 0, 2).should == ["4", "10", "11"]
|
||||
$limits_metadata.LRANGE("#{sql_prefix}job_delete", 0, 2).should == ["5", "13", "14"]
|
||||
$limits_metadata.LRANGE("#{sql_prefix}copy_from", 0, 2).should == ["2", "2", "61"]
|
||||
$limits_metadata.LRANGE("#{sql_prefix}copy_to", 0, 2).should == ["2", "2", "61"]
|
||||
end
|
||||
|
||||
def expect_rate_limits_exist(username)
|
||||
map_prefix = "limits:rate:store:#{username}:maps:"
|
||||
sql_prefix = "limits:rate:store:#{username}:sql:"
|
||||
|
||||
$limits_metadata.EXISTS("#{map_prefix}anonymous").should eq 0
|
||||
$limits_metadata.EXISTS("#{map_prefix}static").should eq 0
|
||||
$limits_metadata.EXISTS("#{map_prefix}static_named").should eq 0
|
||||
$limits_metadata.EXISTS("#{map_prefix}dataview").should eq 0
|
||||
$limits_metadata.EXISTS("#{map_prefix}dataview_search").should eq 0
|
||||
$limits_metadata.EXISTS("#{map_prefix}analysis").should eq 0
|
||||
$limits_metadata.EXISTS("#{map_prefix}tile").should eq 0
|
||||
$limits_metadata.EXISTS("#{map_prefix}attributes").should eq 0
|
||||
$limits_metadata.EXISTS("#{map_prefix}named_list").should eq 0
|
||||
$limits_metadata.EXISTS("#{map_prefix}named_create").should eq 0
|
||||
$limits_metadata.EXISTS("#{map_prefix}named_get").should eq 0
|
||||
$limits_metadata.EXISTS("#{map_prefix}named").should eq 0
|
||||
$limits_metadata.EXISTS("#{map_prefix}named_update").should eq 0
|
||||
$limits_metadata.EXISTS("#{map_prefix}named_delete").should eq 0
|
||||
$limits_metadata.EXISTS("#{map_prefix}named_tiles").should eq 0
|
||||
$limits_metadata.EXISTS("#{map_prefix}analysis_catalog").should eq 0
|
||||
$limits_metadata.EXISTS("#{sql_prefix}query").should eq 0
|
||||
$limits_metadata.EXISTS("#{sql_prefix}query_format").should eq 0
|
||||
$limits_metadata.EXISTS("#{sql_prefix}job_create").should eq 0
|
||||
$limits_metadata.EXISTS("#{sql_prefix}job_get").should eq 0
|
||||
$limits_metadata.EXISTS("#{sql_prefix}job_delete").should eq 0
|
||||
$limits_metadata.EXISTS("#{sql_prefix}copy_from").should eq 0
|
||||
$limits_metadata.EXISTS("#{sql_prefix}copy_to").should eq 0
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,54 @@
|
||||
module SpecHelperHelpers
|
||||
def clean_redis_databases
|
||||
$tables_metadata.flushdb
|
||||
$api_credentials.flushdb
|
||||
$users_metadata.flushdb
|
||||
end
|
||||
|
||||
def clean_metadata_database
|
||||
if ENV['STELLAR'].present?
|
||||
SequelRails.connection.disconnect
|
||||
system "#{ENV['STELLAR']} restore"
|
||||
else
|
||||
protected_tables = [:schema_migrations, :spatial_ref_sys]
|
||||
SequelRails.connection.tables.each do |t|
|
||||
if !protected_tables.include?(t)
|
||||
begin
|
||||
SequelRails.connection.run("TRUNCATE TABLE \"#{t}\" CASCADE")
|
||||
rescue Sequel::DatabaseError => e
|
||||
raise e unless e.message =~ /PG::Error: ERROR: relation ".*" does not exist/
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def close_pool_connections
|
||||
# To avoid Travis and connection leaks
|
||||
$pool.close_connections!
|
||||
end
|
||||
|
||||
def drop_leaked_test_user_databases
|
||||
user_database_names = SequelRails.connection[
|
||||
"SELECT datname FROM pg_database WHERE datistemplate IS FALSE AND datallowconn IS TRUE AND datname like 'cartodb_test_user_%'"
|
||||
]
|
||||
|
||||
user_database_names.map(:datname).each do |user_database_name|
|
||||
puts "Dropping leaked test database #{user_database_name}"
|
||||
CartoDB::UserModule::DBService.terminate_database_connections(
|
||||
user_database_name, ::SequelRails.configuration.environment_for(Rails.env)['host']
|
||||
)
|
||||
SequelRails.connection.run("drop database \"#{user_database_name}\"")
|
||||
end
|
||||
end
|
||||
|
||||
def delete_database_test_users
|
||||
usernames = SequelRails.connection['SELECT u.usename FROM pg_catalog.pg_user u'].map do |r|
|
||||
r.values.first
|
||||
end
|
||||
|
||||
usernames.each do |username|
|
||||
SequelRails.connection.run("drop user \"#{username}\"") if username =~ /^test_cartodb_user_/
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,9 @@
|
||||
module StorageHelper
|
||||
def bypass_storage(identifier: 'es/co/bar.png', url: "https://manolo.es/#{identifier}")
|
||||
Carto::Storage.instance.stubs(:s3_enabled?).returns(false)
|
||||
Carto::StorageOptions::Local.any_instance
|
||||
.stubs(:upload)
|
||||
.returns([identifier, url])
|
||||
Carto::StorageOptions::Local.any_instance.stubs(:remove)
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,11 @@
|
||||
def stub_domainful(subdomain)
|
||||
CartoDB.stubs(:session_domain).returns('.localhost.lan')
|
||||
CartoDB.stubs(:subdomainless_urls?).returns(false)
|
||||
host! "#{subdomain}.localhost.lan"
|
||||
end
|
||||
|
||||
def stub_subdomainless
|
||||
CartoDB.stubs(:session_domain).returns('localhost.lan')
|
||||
CartoDB.stubs(:subdomainless_urls?).returns(true)
|
||||
host! "localhost.lan"
|
||||
end
|
||||
@@ -0,0 +1,33 @@
|
||||
# These helpers are meant to be used in tests to generate random data which may collide, e.g: usernames
|
||||
# The methods are parameter-less in purpose, so it is easier to modify the name generation if needed
|
||||
module UniqueNamesHelper
|
||||
@@item_count = 0
|
||||
|
||||
def unique_string
|
||||
sprintf '%08d', unique_integer
|
||||
end
|
||||
|
||||
def unique_email
|
||||
r = unique_string
|
||||
"e#{r}@d#{r}.com"
|
||||
end
|
||||
|
||||
def unique_name(prefix)
|
||||
prefix + unique_string
|
||||
end
|
||||
|
||||
def unique_integer
|
||||
@@item_count += 1
|
||||
test_run_id * 1000000 + @@item_count
|
||||
end
|
||||
|
||||
def test_run_id
|
||||
@@test_run_id ||= if ENV['PARALLEL_SEQ']
|
||||
ENV['PARALLEL_SEQ'].to_i
|
||||
elsif ENV['CHECK_SPEC']
|
||||
ENV['CHECK_SPEC'].to_i
|
||||
else
|
||||
0
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,49 @@
|
||||
require 'spec_helper_min'
|
||||
require_relative '../simplecov_helper'
|
||||
require_relative '../rspec_configuration'
|
||||
require_relative '../../lib/carto/url_validator'
|
||||
|
||||
class Carto::UrlValidatorInstance
|
||||
include Carto::UrlValidator
|
||||
end
|
||||
|
||||
describe 'UUIDHelper' do
|
||||
before(:each) do
|
||||
@url_validator = Carto::UrlValidatorInstance.new
|
||||
end
|
||||
|
||||
it 'raises an error if the URL is not valid at all' do
|
||||
expect { @url_validator.validate_url!("foo://bar-zzz.com") }
|
||||
.to raise_error(Carto::UrlValidator::InvalidUrlError)
|
||||
end
|
||||
|
||||
it 'raises an error if it points to a non-standard port' do
|
||||
expect { @url_validator.validate_url!("http://example.com:8080") }
|
||||
.to raise_error(Carto::UrlValidator::InvalidUrlError)
|
||||
end
|
||||
|
||||
it 'raises an error if the IP is blacklisted' do
|
||||
@url_validator.instance_variable_set("@blacklisted_ip_ranges", [IPAddr.new("169.254.169.1")])
|
||||
expect { @url_validator.validate_url!("http://169.254.169.1/blob/blub.csv") }
|
||||
.to raise_error(Carto::UrlValidator::InvalidUrlError)
|
||||
end
|
||||
|
||||
it 'raises an error if the IP belongs to a blacklisted range' do
|
||||
@url_validator.instance_variable_set("@blacklisted_ip_ranges", [IPAddr.new("10.0.0.0/8")])
|
||||
expect { @url_validator.validate_url!("http://10.0.0.92/blob/blub.csv") }
|
||||
.to raise_error(Carto::UrlValidator::InvalidUrlError)
|
||||
end
|
||||
|
||||
it 'does nothing if everything is ok' do
|
||||
@url_validator.instance_variable_set("@blacklisted_ip_ranges", [IPAddr.new("169.254.169.1")])
|
||||
@url_validator.validate_url!("http://169.254.169.2/foo.csv")
|
||||
@url_validator.validate_url!("http://example.com/foo.csv")
|
||||
@url_validator.validate_url!("https://example.com/bar.kml")
|
||||
@url_validator.validate_url!("http://example.com/foo.csv:80")
|
||||
@url_validator.validate_url!("https://example.com/bar.kml:443")
|
||||
end
|
||||
|
||||
it 'allows ftp' do
|
||||
expect { @url_validator.validate_url!("ftp://example.com") }.to_not raise_error
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,39 @@
|
||||
require_relative '../simplecov_helper'
|
||||
require_relative '../rspec_configuration.rb'
|
||||
require_relative '../../lib/carto/uuidhelper'
|
||||
|
||||
class Carto::UUIDHelperInstance
|
||||
include Carto::UUIDHelper
|
||||
end
|
||||
|
||||
describe 'UUIDHelper' do
|
||||
|
||||
before(:each) do
|
||||
@uuid_helper = Carto::UUIDHelperInstance.new
|
||||
end
|
||||
|
||||
it 'validates a valid UUID' do
|
||||
@uuid_helper.is_uuid?('5b632a9e-ae07-11e4-ac8d-080027880ca6').should be(true)
|
||||
end
|
||||
|
||||
it 'validates a random UUID' do
|
||||
@uuid_helper.is_uuid?(SecureRandom.uuid).should be(true)
|
||||
end
|
||||
|
||||
it 'fails if content prepended' do
|
||||
@uuid_helper.is_uuid?("hi" + SecureRandom.uuid).should be(false)
|
||||
end
|
||||
|
||||
it 'fails if content appended' do
|
||||
@uuid_helper.is_uuid?(SecureRandom.uuid + "hola").should be(false)
|
||||
end
|
||||
|
||||
it 'fails if content prepended with newlines' do
|
||||
@uuid_helper.is_uuid?("hi\n" + SecureRandom.uuid).should be(false)
|
||||
end
|
||||
|
||||
it 'fails if content appended with newlines' do
|
||||
@uuid_helper.is_uuid?(SecureRandom.uuid + "\nhola").should be(false)
|
||||
end
|
||||
|
||||
end
|
||||
@@ -0,0 +1,31 @@
|
||||
module VisualizationDestructionHelper
|
||||
def expect_visualization_to_be_destroyed(visualization)
|
||||
visualization_id = visualization.id
|
||||
map_id = visualization.map.id
|
||||
layers_ids = visualization.layers.map(&:id)
|
||||
layers_user_tables_ids = visualization.layers.flat_map(&:layers_user_tables).map(&:id)
|
||||
widgets_ids = visualization.widgets.map(&:id)
|
||||
analyses_ids = visualization.analyses.map(&:id)
|
||||
overlays_ids = visualization.overlays.map(&:id)
|
||||
permission_id = visualization.permission.id
|
||||
mapcaps_ids = visualization.mapcaps.map(&:id)
|
||||
state_id = visualization.state.id
|
||||
snapshots_ids = visualization.snapshots.map(&:id)
|
||||
synchronization_id = visualization.synchronization.try(:id)
|
||||
|
||||
yield
|
||||
|
||||
expect(Carto::Visualization.exists?(visualization_id)).to be_false
|
||||
expect(Carto::Map.exists?(map_id)).to be_false
|
||||
expect(Carto::Permission.exists?(permission_id)).to be_false
|
||||
expect(Carto::State.exists?(state_id)).to be_false
|
||||
expect(Carto::Synchronization.exists?(synchronization_id)).to be_false if synchronization_id
|
||||
layers_ids.each { |id| expect(Carto::Layer.exists?(id)).to be_false }
|
||||
layers_user_tables_ids.each { |id| expect(Carto::LayersUserTable.exists?(id)).to be_false }
|
||||
widgets_ids.each { |id| expect(Carto::Widget.exists?(id)).to be_false }
|
||||
analyses_ids.each { |id| expect(Carto::Analysis.exists?(id)).to be_false }
|
||||
overlays_ids.each { |id| expect(Carto::Overlay.exists?(id)).to be_false }
|
||||
mapcaps_ids.each { |id| expect(Carto::Mapcap.exists?(id)).to be_false }
|
||||
snapshots_ids.each { |id| expect(Carto::Snapshot.exists?(id)).to be_false }
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user