require_relative '../../spec_helper_min' describe CartoDB::Visualization::CommonDataService do before(:all) do @user = FactoryGirl.create(:valid_user) end after(:all) do @user.destroy end before(:each) do remote_visualizations(@user).each(&:destroy) end def service CartoDB::Visualization::CommonDataService.new end def remote_visualizations(user) Carto::Visualization.where(user_id: user.id, type: Carto::Visualization::TYPE_REMOTE) end def dataset(name, description: 'A very creative description') { name: name, description: description, tags: ['Awesome', 'Data'], license: '', source: 'Myself', attributions: 'Be nice to each other', display_name: name, url: 'http://example.org', geometry_types: '{ST_MultiPolygon}', rows: 1000, size: 1000000 }.stringify_keys end def stub_datasets(datasets) CommonDataSingleton.instance.stubs(:datasets).returns(datasets) end it 'should import common data datasets' do stub_datasets([dataset('ds1')]) added, updated, not_modified, deleted, failed = service.load_common_data_for_user(@user, 'some_url') expect(added).to eq 1 expect(updated).to eq 0 expect(not_modified).to eq 0 expect(deleted).to eq 0 expect(failed).to eq 0 expect(remote_visualizations(@user).count).to eq 1 remote_visualization = remote_visualizations(@user).first expect(remote_visualization.name).to eq 'ds1' expect(remote_visualization.external_source.geometry_types).to eq ["ST_MultiPolygon"] end it 'should import common data datasets within an ActiveRecord transaction (see #12488)' do # This would trigger an exception because of data integrity expect { ActiveRecord::Base.transaction do stub_datasets([dataset('ds1')]) service.load_common_data_for_user(@user, 'some_url') end }.not_to raise_error end it 'should update common data datasets' do stub_datasets([dataset('ds1')]) service.load_common_data_for_user(@user, 'some_url') stub_datasets([dataset('ds1', description: 'desc')]) added, updated, not_modified, deleted, failed = service.load_common_data_for_user(@user, 'some_url') expect(added).to eq 0 expect(updated).to eq 1 expect(not_modified).to eq 0 expect(deleted).to eq 0 expect(failed).to eq 0 expect(remote_visualizations(@user).count).to eq 1 expect(remote_visualizations(@user).first.name).to eq 'ds1' expect(remote_visualizations(@user).first.description).to eq 'desc' end it 'should not touch unmodified common data datasets' do stub_datasets([dataset('ds1')]) service.load_common_data_for_user(@user, 'some_url') added, updated, not_modified, deleted, failed = service.load_common_data_for_user(@user, 'some_url') expect(added).to eq 0 expect(updated).to eq 0 expect(not_modified).to eq 1 expect(deleted).to eq 0 expect(failed).to eq 0 expect(remote_visualizations(@user).count).to eq 1 expect(remote_visualizations(@user).first.name).to eq 'ds1' end it 'should delete removed common data datasets' do stub_datasets([dataset('ds1'), dataset('ds2')]) service.load_common_data_for_user(@user, 'some_url') expect(remote_visualizations(@user).count).to eq 2 Carto::ExternalSource.count.should eq 2 stub_datasets([dataset('ds1')]) added, updated, not_modified, deleted, failed = service.load_common_data_for_user(@user, 'some_url') expect(added).to eq 0 expect(updated).to eq 0 expect(not_modified).to eq 1 expect(deleted).to eq 1 expect(failed).to eq 0 Carto::ExternalSource.count.should eq 1 expect(remote_visualizations(@user).count).to eq 1 expect(remote_visualizations(@user).first.name).to eq 'ds1' end it 'should not delete anything if common data datasets fetching fails or it\'s empty' do stub_datasets([dataset('ds1'), dataset('ds2')]) service.load_common_data_for_user(@user, 'some_url') expect(remote_visualizations(@user).count).to eq 2 Carto::ExternalSource.count.should eq 2 stub_datasets([]) service.load_common_data_for_user(@user, 'some_url').should be_nil Carto::ExternalSource.count.should eq 2 expect(remote_visualizations(@user).count).to eq 2 common_data_singleton_mock = mock common_data_singleton_mock.stubs(:datasets).raises("error!") CommonDataSingleton.stubs(:instance).returns(common_data_singleton_mock) service.load_common_data_for_user(@user, 'some_url').should be_nil Carto::ExternalSource.count.should eq 2 expect(remote_visualizations(@user).count).to eq 2 end it 'should fail when missing some fields, but still import the rest' do stub_datasets([dataset('ds1'), {}]) added, updated, not_modified, deleted, failed = service.load_common_data_for_user(@user, 'some_url') expect(added).to eq 1 expect(updated).to eq 0 expect(not_modified).to eq 0 expect(deleted).to eq 0 expect(failed).to eq 1 expect(remote_visualizations(@user).count).to eq 1 expect(remote_visualizations(@user).first.name).to eq 'ds1' end describe 'destroying common data remote visualizations' do it 'delete remote visualizations that have been imported but keep the import' do viz = FactoryGirl.create(:carto_table_visualization, user_id: @user.id) data_import = FactoryGirl.create(:data_import, user_id: @user.id, visualization_id: viz.id) external_data_import = FactoryGirl.create(:external_data_import_with_external_source, data_import: data_import) visualization = external_data_import.external_source.visualization service.send(:delete_remote_visualization, visualization).should be_true Carto::Visualization.where(id: visualization.id).should be_empty Carto::ExternalSource.where(id: external_data_import.external_source.id).should be_empty Carto::ExternalDataImport.where(id: external_data_import.id).should be_empty Carto::DataImport.where(id: data_import.id).first.should_not be_nil Carto::Visualization.where(id: viz.id).first.should_not be_nil end it 'delete remote visualizations that have been synced and the sync but keep the import' do viz = FactoryGirl.create(:carto_table_visualization, user_id: @user.id) data_import = FactoryGirl.create(:data_import, user_id: @user.id, visualization_id: viz.id) sync = FactoryGirl.create(:carto_synchronization, user_id: @user.id, visualization_id: viz.id) external_data_import = FactoryGirl.create(:external_data_import_with_external_source, data_import: data_import, synchronization: sync) visualization = external_data_import.external_source.visualization service.send(:delete_remote_visualization, visualization).should be_true Carto::Visualization.where(id: visualization.id).should be_empty Carto::ExternalSource.where(id: external_data_import.external_source.id).should be_empty Carto::ExternalDataImport.where(id: external_data_import.id).should be_empty Carto::Synchronization.where(id: sync.id).should be_empty Carto::DataImport.where(id: data_import.id).first.should_not be_nil Carto::Visualization.where(id: viz.id).first.should_not be_nil end end end