cartodb-4.42/spec/requests/carto/api/visualization_exports_controller_spec.rb
2024-04-06 05:25:13 +00:00

245 lines
9.3 KiB
Ruby

require 'spec_helper_min'
require_dependency 'carto/uuidhelper'
require 'factories/carto_visualizations'
require 'support/helpers'
require 'helpers/metrics_helper'
describe Carto::Api::VisualizationExportsController, type: :controller do
include Carto::UUIDHelper
include Carto::Factories::Visualizations
include HelperMethods
include MetricsHelper
def create_visualization_export_url(user = nil)
visualization_exports_url(user_domain: user ? user.username : nil, api_key: user ? user.api_key : nil)
end
before(:each) do
bypass_metrics
end
describe 'normal users' do
before(:all) do
@user = FactoryGirl.create(:carto_user, private_maps_enabled: true)
@user2 = FactoryGirl.create(:carto_user, private_maps_enabled: true)
end
after(:all) do
# This avoids connection leaking.
::User[@user.id].destroy
::User[@user2.id].destroy
end
describe '#create' do
before(:each) do
bypass_named_maps
@map, @table, @table_visualization, @visualization = create_full_visualization(@user)
carto_layer = @visualization.layers.find { |l| l.kind == 'carto' }
carto_layer.options[:user_name] = @user.username
carto_layer.save
end
after(:each) do
destroy_full_visualization(@map, @table, @table_visualization, @visualization)
end
it 'returns 404 for nonexisting visualizations' do
post_json create_visualization_export_url(@user), visualization_id: random_uuid do |response|
response.status.should eq 404
end
end
it 'returns 403 for non accessible visualizations' do
@visualization.privacy = Carto::Visualization::PRIVACY_PRIVATE
@visualization.save
post_json create_visualization_export_url(@user2), visualization_id: @visualization.id do |response|
response.status.should eq 403
end
end
it 'returns 403 for non accessible visualizations (private and protected) for anonymous users' do
@visualization.privacy = Carto::Visualization::PRIVACY_PRIVATE
@visualization.save
post_json create_visualization_export_url, visualization_id: @visualization.id do |response|
response.status.should eq 403
end
@visualization.privacy = Carto::Visualization::PRIVACY_PROTECTED
@visualization.save
post_json create_visualization_export_url, visualization_id: @visualization.id do |response|
response.status.should eq 403
end
end
it 'returns 422 if user_tables_ids param contains user table ids not related to the visualization' do
post_json create_visualization_export_url(@user),
visualization_id: @visualization.id, user_tables_ids: random_uuid do |response|
response.status.should eq 422
end
end
it 'returns 422 if visualization type is `table`' do
@visualization.update_attributes(type: Carto::Visualization::TYPE_CANONICAL)
post_json create_visualization_export_url(@user), visualization_id: @visualization.id do |response|
response.status.should eq 422
response.body[:errors].should match(/Only derived visualizations can be exported/)
end
end
it 'enqueues a job and returns the id' do
job_params = has_entries(
download_path: regexp_matches(/download$/),
job_id: regexp_matches(Carto::UUIDHelper::UUID_REGEXP)
)
Resque.expects(:enqueue).with(Resque::ExporterJobs, job_params).once
post_json create_visualization_export_url(@user), visualization_id: @visualization.id do |response|
response.status.should eq 201
visualization_export_id = response.body[:id]
visualization_export_id.should_not be_nil
visualization_export = Carto::VisualizationExport.find(visualization_export_id)
visualization_export.visualization_id.should eq @visualization.id
visualization_export.user_id.should eq @user.id
visualization_export.state.should eq Carto::VisualizationExport::STATE_PENDING
end
end
it 'enqueues a job and returns the id for anonymous, valid exports' do
@visualization.privacy = Carto::Visualization::PRIVACY_LINK
@visualization.save
Resque.expects(:enqueue).with(Resque::ExporterJobs, anything).once
post_json create_visualization_export_url, visualization_id: @visualization.id do |response|
response.status.should eq 201
visualization_export_id = response.body[:id]
visualization_export_id.should_not be_nil
visualization_export = Carto::VisualizationExport.find(visualization_export_id)
visualization_export.visualization_id.should eq @visualization.id
visualization_export.user_id.should be_nil
visualization_export.state.should eq Carto::VisualizationExport::STATE_PENDING
end
end
end
describe '#show' do
before(:all) do
bypass_named_maps
@visualization = FactoryGirl.create(:carto_visualization, user: @user)
@export = FactoryGirl.create(:visualization_export, visualization: @visualization, user: @user)
@anonymous_export = FactoryGirl.create(:visualization_export, visualization: @visualization, user: nil)
end
after(:all) do
@export.destroy
@visualization.destroy
end
def export_url(visualization_export_id, user = nil)
visualization_export_url(
user_domain: user ? user.username : nil,
api_key: user ? user.api_key : nil,
id: visualization_export_id
)
end
it 'returns 404 for nonexisting exports' do
get_json export_url(random_uuid, @user) do |response|
response.status.should eq 404
end
end
it 'returns 403 for exports from other user' do
get_json export_url(@export.id, @user2) do |response|
response.status.should eq 403
end
end
it 'returns the visualization export' do
get_json export_url(@export.id, @user) do |response|
response.status.should eq 200
visualization_export = response.body
visualization_export[:id].should eq @export.id
visualization_export[:visualization_id].should eq @export.visualization_id
visualization_export[:user_id].should eq @user.id
visualization_export[:state].should eq @export.state
end
end
it 'returns the visualization export for anonymous exports' do
get_json export_url(@anonymous_export.id) do |response|
response.status.should eq 200
visualization_export = response.body
visualization_export[:id].should eq @anonymous_export.id
visualization_export[:user_id].should be_nil
end
end
end
describe '#download' do
before(:all) do
bypass_named_maps
@visualization = FactoryGirl.create(:carto_visualization, user: @user)
@export = FactoryGirl.create(:visualization_export, visualization: @visualization, user: @user)
@anonymous_export = FactoryGirl.create(:visualization_export, visualization: @visualization, user: nil)
end
after(:all) do
@export.destroy
@visualization.destroy
end
def download_url(visualization_export_id, user = nil)
visualization_export_download_url(
user_domain: user ? user.username : nil,
api_key: user ? user.api_key : nil,
visualization_export_id: visualization_export_id
)
end
it 'returns 404 for nonexisting exports' do
get_json download_url(random_uuid, @user) do |response|
response.status.should eq 404
end
end
it 'returns 403 for exports from other user' do
get_json download_url(@export.id, @user2) do |response|
response.status.should eq 403
end
end
it 'downloads the visualization export' do
Carto::Api::VisualizationExportsController.any_instance.expects(:send_file).
with(@export.file, type: 'application/zip')
Carto::Api::VisualizationExportsController.any_instance.stubs(:render)
get URI::encode("/u/#{@user.username}/#{@export.url}?api_key=#{@user.api_key}"), nil, nil
response.status.should eq 200
end
end
end
describe 'shared visualizations' do
include_context 'visualization creation helpers'
include_context 'organization with users helper'
it 'allows exporting a private map shared with a user' do
visualization = FactoryGirl.create(:carto_private_visualization, user: @carto_org_user_1)
share_visualization(CartoDB::Visualization::Member.new(id: visualization.id).fetch, @org_user_2)
Resque.expects(:enqueue).with(Resque::ExporterJobs, anything).once
post_json create_visualization_export_url(@carto_org_user_2), visualization_id: visualization.id do |res|
res.status.should eq 201
visualization_export_id = res.body[:id]
visualization_export_id.should_not be_nil
visualization_export = Carto::VisualizationExport.find(visualization_export_id)
visualization_export.visualization_id.should eq visualization.id
visualization_export.user_id.should eq @carto_org_user_2.id
visualization_export.state.should eq Carto::VisualizationExport::STATE_PENDING
end
end
end
end