cartodb-4.29/spec/models/layer_shared_examples.rb
2020-06-15 10:58:47 +08:00

320 lines
9.9 KiB
Ruby

shared_examples_for 'Layer model' do
context "setups" do
it "should be preloaded with the correct default values" do
l = layer_class.create(Cartodb.config[:layer_opts]["data"]).reload
l.kind.should == 'carto'
l.options.should == Cartodb.config[:layer_opts]["data"]["options"]
l = layer_class.create(Cartodb.config[:layer_opts]["background"]).reload
l.kind.should == 'background'
l.options.should == Cartodb.config[:layer_opts]["background"]["options"]
end
it "should not allow to create layers of unkown types" do
expect { layer_class.create(kind: "wadus").save! }.to raise_error
end
it "should allow to be linked to many maps" do
table2 = Table.new
table2.user_id = @user.id
table2.save
layer = layer_class.create(kind: 'carto')
map = create_map(user_id: @user.id, table_id: @table.id)
map2 = create_map(user_id: @user.id, table_id: table2.id)
add_layer_to_entity(map, layer)
add_layer_to_entity(map2, layer)
layer.reload
map.layers.first.id.should == layer.id
map2.layers.first.id.should == layer.id
layer.maps.should include(map, map2)
end
it "should allow to be linked to many users" do
layer = layer_class.create(kind: 'carto')
add_layer_to_entity(@user, layer)
@user.reload.layers.map(&:id).should include(layer.id)
layer.users.map(&:id).should include(@user.id)
end
it "should set default order when adding layers to a map" do
map = create_map(user_id: @user.id, table_id: @table.id)
5.times do |i|
layer = layer_class.create(kind: 'carto')
add_layer_to_entity(map, layer)
layer.reload.order.should == i
end
end
it "should set default order when adding layers to a user" do
@user.layers.each(&:destroy)
@user.reload
5.times do |i|
layer = layer_class.create(kind: 'carto')
add_layer_to_entity(@user, layer)
layer.reload.order.should == i
end
end
context "when the type is cartodb and the layer is updated" do
before do
@map = create_map(user_id: @user.id, table_id: @table.id)
@layer = layer_class.create(kind: 'carto', options: { query: "select * from #{@table.name}" })
add_layer_to_entity(@map, @layer)
end
it "should invalidate its maps" do
CartoDB::Varnish.any_instance.stubs(:purge).returns(true)
@layer.maps.count.should eq 1
@layer.maps.each do |map|
map.expects(:notify_map_change).times(1)
end
@layer.save
end
end
context "when the type is not cartodb" do
before do
@map = create_map(user_id: @user.id, table_id: @table.id)
@layer = layer_class.create(kind: 'tiled')
add_layer_to_entity(@map, @layer)
end
it "should not invalidate its related tables varnish cache" do
@layer.maps.each do |map|
map.expects(:notify_map_change).times(1)
end
@layer.send(:affected_tables).each do |table|
table.expects(:update_cdb_tablemetadata).times(0)
end
@layer.save
end
end
it "should update updated_at after saving" do
layer = layer_class.create(kind: 'carto')
after = layer.updated_at
Delorean.jump(1.minute)
layer.options[:query] = 'SELECT * FROM arbitrary_change'
layer.save
after.should < layer.updated_at
Delorean.back_to_the_present
end
it "should correctly identify affected tables" do
table2 = Table.new
table2.user_id = @user.id
table2.save
map = create_map(user_id: @user.id, table_id: @table.id)
layer = layer_class.create(
kind: 'carto',
options: { query: "select * from #{@table.name}, #{table2.name};select 1;select * from #{table2.name}" }
)
add_layer_to_entity(map, layer)
layer.reload
layer.send(:affected_tables).map(&:name).should =~ [table2.name, @table.name]
end
it "should return empty affected tables when no tables are involved" do
map = create_map(user_id: @user.id, table_id: @table.id)
layer = layer_class.create(
kind: 'carto',
options: { query: "select 1" }
)
add_layer_to_entity(map, layer)
layer.send(:affected_tables).map(&:name).should =~ []
end
it 'includes table_name option in the results' do
map = create_map(user_id: @user.id, table_id: @table.id)
layer = layer_class.create(
kind: 'carto',
options: { query: "select 1", table_name: @table.name }
)
add_layer_to_entity(map, layer)
layer.reload
layer.send(:affected_tables).map(&:name).should =~ [@table.name]
end
end
describe '#base_layer?' do
it 'returns true if its kind is a base layer' do
layer = layer_class.new(kind: 'tiled')
layer.base_layer?.should == true
end
end
describe '#data_layer?' do
it 'returns true if its of a carto kind' do
layer = layer_class.new(kind: 'carto')
layer.data_layer?.should == true
end
end
describe '#rename_table' do
it 'renames table in layer options' do
table_name = 'table_name'
new_table_name = 'changed_name'
tile_style = "##{table_name} { color:red; }"
query = "SELECT * FROM table_name, other_table"
options = {
table_name: table_name,
tile_style: tile_style,
query: query
}
layer = layer_class.create(kind: 'carto', options: options)
layer.rename_table(table_name, new_table_name)
layer.save
layer.reload
options = layer.options
options.fetch('tile_style') .should =~ /#{new_table_name}/
options.fetch('tile_style') .should_not =~ /#{table_name}/
options.fetch('query') .should =~ /#{new_table_name}/
options.fetch('query') .should_not =~ /#{table_name}/
options.fetch('table_name') .should =~ /#{new_table_name}/
options.fetch('table_name') .should_not =~ /#{table_name}/
end
it "won't touch the query if it doesn't match" do
table_name = 'table_name'
new_table_name = 'changed_name'
tile_style = "##{table_name} { color:red; }"
query = "SELECT * FROM foo"
options = {
table_name: table_name,
tile_style: tile_style,
query: query
}
layer = layer_class.create(kind: 'carto', options: options)
layer.rename_table(table_name, new_table_name)
layer.save
layer.reload
layer.options.fetch('query').should == options.fetch(:query)
end
end
describe '#destroy' do
it 'invalidates the vizjson cache of all related maps' do
map = create_map(user_id: @user.id, table_id: @table.id)
layer = layer_class.create(kind: 'carto')
add_layer_to_entity(map, layer)
# TODO: should be once
map.class.any_instance.expects(:notify_map_change).at_least_once
layer.destroy
end
it 'deletes ternary relations' do
map = create_map(user_id: @user.id, table_id: @table.id)
layer = layer_class.create(kind: 'carto')
layer.options[:query] = "SELECT * FROM #{@table.name}"
layer.register_table_dependencies
add_layer_to_entity(map, layer)
add_layer_to_entity(@user, layer)
layer.destroy
Carto::LayersMap.where(layer_id: layer.id).exists?.should be_false
Carto::LayersUser.where(layer_id: layer.id).exists?.should be_false
Carto::LayersUserTable.where(layer_id: layer.id).exists?.should be_false
end
end
describe '#uses_private_tables?' do
it 'returns true if any of the affected tables is private' do
layers = @table.table_visualization.data_layers
layers.length.should == 1
layers.first.uses_private_tables?.should be_true
@table.privacy = UserTable::PRIVACY_PUBLIC
@table.save
@user.reload
layers.first.reload
layers.first.uses_private_tables?.should be_false
end
end
context 'viewer role' do
after(:each) do
@user.viewer = false
@user.save
end
it "can't update layers" do
map = create_map(user_id: @user.id, table_id: @table.id)
layer = layer_class.create(kind: 'carto')
add_layer_to_entity(map, layer)
@user.viewer = true
@user.save
layer.reload
layer.kind = 'torque'
saved = begin
layer.save
rescue
false
end
saved.should be_false
end
end
describe '#LayerNodeStyle cache' do
before(:each) do
@map = create_map(user_id: @user.id, table_id: @table.id)
@layer = layer_class.create(kind: 'carto')
add_layer_to_entity(@map, @layer)
end
after(:each) do
@layer.destroy
@map.destroy
end
it 'saves styles for layers with source_id' do
@layer.options['source'] = 'a0'
@layer.save
lns = LayerNodeStyle.where(layer_id: @layer.id).first
lns.should be
lns.tooltip.should eq @layer.tooltip || {}
lns.infowindow.should eq @layer.infowindow || {}
lns.options['tile_style'].should eq @layer.options['tile_style']
lns.options['sql_wrap'].should eq @layer.options['sql_wrap']
lns.options['style_properties'].should eq @layer.options['style_properties']
end
it 'does not save styles for layers with source_id' do
@layer.options['source'] = nil
@layer.save
LayerNodeStyle.where(layer_id: @layer.id).count.should eq 0
end
it 'saves styles for torque layers' do
@layer.kind = 'torque'
@layer.options['source'] = 'a0'
@layer.save
lns = LayerNodeStyle.where(layer_id: @layer.id).first
lns.should be
lns.tooltip.should eq @layer.tooltip || {}
lns.infowindow.should eq @layer.infowindow || {}
lns.options['tile_style'].should eq @layer.options['tile_style']
lns.options['sql_wrap'].should eq @layer.options['sql_wrap']
lns.options['style_properties'].should eq @layer.options['style_properties']
end
end
end