Files
cartodb/lib/assets/test/spec/dashboard/views/public-dataset/carto-table-metadata.spec.js
T
2020-06-15 10:58:47 +08:00

821 lines
28 KiB
JavaScript

const _ = require('underscore');
const CartoTableMetadata = require('dashboard/views/public-dataset/carto-table-metadata');
const ImportModel = require('dashboard/data/import-model');
const RowModel = require('dashboard/data/table/row-model');
const SQLViewDataModel = require('dashboard/data/table/sqlviewdata-model');
const CartoTableMetadataFixture = require('fixtures/dashboard/carto-table-metadata.fixture');
const configModel = require('fixtures/dashboard/config-model.fixture');
const InfowindowModel = require('builder/data/infowindow-definition-model');
const SQL = require('internal-carto.js').SQL;
describe('dashboard/views/public-dataset/carto-table-metadata', function () {
let table;
beforeEach(function () {
table = new CartoTableMetadata({
id: 'testTable',
name: 'testTable',
schema: [
['test', 'string'],
['test2', 'number']
]
}, { configModel });
});
it('should return columntypes', function () {
expect(table.columnTypes()).toEqual({
test: 'string',
test2: 'number'
});
});
it('should return unqualified name', function () {
const ntable = new CartoTableMetadata({
id: '"kease".testTable',
name: '"kease".testTable'
}, { configModel });
expect(ntable.getUnqualifiedName()).toEqual('testTable');
expect(table.getUnqualifiedName()).toEqual('testTable');
});
it('should add geometrytypes when adding a row', function () {
table = new CartoTableMetadata({
name: 'testTable',
schema: [
['test', 'string'],
['test2', 'number']
],
geometry_types: []
}, { configModel });
table.data().add({ cartodb_id: 2 });
var r = table.data().get(2);
r.set('the_geom', '{"type": "point", "coordinates": [1,2]}');
expect(table.get('geometry_types')).toEqual(['st_point']);
});
it('geometryTypeChanged', function () {
var changed = null;
table.bind('change', function () {
changed = table.geometryTypeChanged();
});
table.set('geometry_types', ['ST_Point']);
expect(changed).toEqual(true);
changed = null;
table.set('geometry_types', ['ST_Point']);
expect(changed).toEqual(null);
changed = null;
table.set('geometry_types', ['ST_MultiPoint']);
expect(changed).toEqual(false);
changed = null;
table.set('geometry_types', ['ST_Polygon']);
expect(changed).toEqual(true);
changed = null;
table.unset('geometry_types');
expect(changed).toEqual(true);
});
it("should be read only if it's synced", function () {
expect(table.isReadOnly()).toEqual(false);
table.synchronization.set('id', 'test');
expect(table.isReadOnly()).toEqual(true);
});
it('should emit sync changes', function () {
var spy = jasmine.createSpy();
table.on('change:isSync', spy);
table.synchronization.set('id', 'test');
expect(spy).toHaveBeenCalledWith(table, true);
table.synchronization.unset('id');
expect(spy).toHaveBeenCalledWith(table, false);
});
it('should create column types', function () {
expect(table._getColumn('test').get('type')).toEqual('string');
expect(table._getColumn('test2').get('type')).toEqual('number');
table.set({
schema: [
['test', 'number'],
['test2', 'number']
]
});
expect(table._getColumn('test').get('type')).toEqual('number');
});
it('should sort schema', function () {
table = new CartoTableMetadata({
name: 'testTable',
schema: [
['otra_foobar', 'string'],
['test2', 'number'],
['_desc', 'string'],
['other', 'string'],
['the_geom', 'geometry'],
['created_at', 'date'],
['updated_at', 'date'],
['cartodb_id', 'number']
]
}, { configModel });
var changeSchemaSpy = jasmine.createSpy();
table.bind('change:schema', changeSchemaSpy);
table.sortSchema();
expect(table.get('schema')).toEqual([
['cartodb_id', 'number'],
['the_geom', 'geometry'],
['_desc', 'string'],
['other', 'string'],
['otra_foobar', 'string'],
['test2', 'number'],
['created_at', 'date'],
['updated_at', 'date']
]
);
expect(changeSchemaSpy).toHaveBeenCalled();
});
it('should copy the types of the original schema', function () {
var sqlView = new SQLViewDataModel(null, { sql: 'select * from a', configModel });
table.useSQLView(sqlView);
sqlView.query_schema = {
'test': 'string',
'test3': 'number'
};
sqlView.reset([
{ test: 1, b: 2 }
]);
expect(table.getColumnType('test')).toEqual('string');
expect(table.getColumnType('test2')).toEqual(undefined);
expect(table.getColumnType('test3')).toEqual('number');
table.useSQLView(null);
expect(table.getColumnType('test')).toEqual('string');
expect(table.getColumnType('test3')).toEqual(undefined);
expect(table.getColumnType('b')).toEqual(undefined);
});
it('should have a original_schema', function () {
var s = _.clone(table.get('schema'));
expect(table.get('original_schema')).toEqual(s);
var sqlView = new SQLViewDataModel(null, { sql: 'select * from a', configModel });
table.useSQLView(sqlView);
sqlView.reset([
{ a: 1, b: 2 }
]);
expect(table.get('original_schema')).toEqual(s);
expect(table.get('schema')).not.toEqual(s);
});
it('should return geom column types', function () {
table.set({geometry_types: ['ST_MultiPolygon']});
expect(table.geomColumnTypes()).toEqual(['polygon']);
table.set({geometry_types: ['ST_MultiPolygon', 'ST_LineString']});
expect(table.geomColumnTypes()).toEqual(['polygon', 'line']);
table.set({geometry_types: ['ST_MultiPoint', 'ST_LineString']});
expect(table.geomColumnTypes()).toEqual(['point', 'line']);
table.set({geometry_types: []});
expect(table.geomColumnTypes()).toEqual([]);
table.set({geometry_types: ['st_MultiPoint', 'ST_LINESTRING']});
expect(table.geomColumnTypes()).toEqual(['point', 'line']);
expect(table.geomColumnTypes('test')).toEqual([]);
table.set({geometry_types: ''});
expect(table.geomColumnTypes()).toEqual([]);
});
it('should return stats geom column types', function () {
table.set({ stats_geometry_types: ['ST_MultiPolygon'] });
expect(table.statsGeomColumnTypes()).toEqual(['polygon']);
});
it('hasgeomtype', function () {
var r = new RowModel({
cartodb_id: 100,
the_geom: JSON.stringify({ type: 'point', coordinates: [2, 1] })
}, { configModel });
expect(r.hasGeometry()).toEqual(true);
r.set('the_geom', null);
expect(r.hasGeometry()).toEqual(false);
r.set('the_geom', undefined);
expect(r.hasGeometry()).toEqual(false);
});
it('should know if the_geom contains a geoJSON', function () {
var a = {
cartodb_id: 100,
the_geom: JSON.stringify({ type: 'point', coordinates: [2, 1] })
};
var r = new RowModel(a, { configModel });
expect(r.isGeometryGeoJSON()).toBeTruthy();
a.the_geom = 'asdasdsad';
r = new RowModel(a, { configModel });
expect(r.isGeometryGeoJSON()).toBeFalsy();
});
it('tojson should not include the_geom if is not in geojson format', function () {
var a = {
cartodb_id: 100,
the_geom: JSON.stringify({ type: 'point', coordinates: [2, 1] })
};
var r = new RowModel(a, { configModel });
expect(r.toJSON().the_geom).toEqual(a.the_geom);
a.the_geom = 'asdasdsad';
r = new RowModel(a, { configModel });
expect(r.toJSON().the_geom).toEqual(undefined);
});
it('tojson should not include the_geom_webmercator, created_at or updated_at', function () {
var a = {
cartodb_id: 100,
updated_at: 1,
created_at: 1,
the_geom_webmercator: 1
};
var r = new RowModel(a, { configModel });
expect(r.toJSON().the_geom).toEqual(undefined);
expect(r.toJSON().created_at).toEqual(undefined);
expect(r.toJSON().updated_at).toEqual(undefined);
});
it('altertable', function () {
var t = CartoTableMetadata;
expect(t.alterTable('select * from blba')).toEqual(false);
expect(t.alterTable('select create from table')).toEqual(false);
expect(t.alterTable('select * from test wherw id=\'vacuum\'')).toEqual(false);
expect(t.alterTable('insert into blaba values (1,2,3,4)')).toEqual(false);
expect(t.alterTable('delete from bkna')).toEqual(false);
expect(t.alterTable('update aaa set a = 1')).toEqual(false);
expect(t.alterTable('vacuum full')).toEqual(true);
expect(t.alterTable('exPlain Analyze select * from test')).toEqual(true);
expect(t.alterTable('grant update on foo to jerry')).toEqual(true);
expect(t.alterTable('comment on foo \'this is crazy\'')).toEqual(true);
expect(t.alterTable('revoke update on foo from jerry')).toEqual(true);
expect(t.alterTable('reindex public.foo')).toEqual(true);
expect(t.alterTable('cluster public.foo using foo_gidx')).toEqual(true);
expect(t.alterTable('alter table add column blbla')).toEqual(true);
expect(t.alterTable('alter schema.table add column blbla')).toEqual(true);
expect(t.alterTable('create function')).toEqual(true);
expect(t.alterTable('create or replace function')).toEqual(true);
expect(t.alterTable('create index foo_idx on foo using gist(the_geom)')).toEqual(true);
expect(t.alterTable('create index foo_idx on public.foo (cartodb_id)')).toEqual(true);
});
it('altertabledata', function () {
var t = CartoTableMetadata;
expect(t.alterTableData('select * from blba')).toEqual(false);
expect(t.alterTableData('alter table add column blbla')).toEqual(true);
expect(t.alterTableData('vacuum full')).toEqual(true);
expect(t.alterTableData('refresh materialized view bar')).toEqual(true);
expect(t.alterTableData('truncate table')).toEqual(true);
expect(t.alterTableData('truncate schema.table')).toEqual(true);
expect(t.alterTableData('update aaa set a = 1')).toEqual(true);
expect(t.alterTableData('update table as whatvever set a = null')).toEqual(true);
expect(t.alterTableData('update __rabos123123 set a = 1')).toEqual(true);
expect(t.alterTableData('insert into blaba values (1,2,3,4)')).toEqual(true);
expect(t.alterTableData('insert into blaba values (1,2,3,4)')).toEqual(true);
expect(t.alterTableData('delete from bkna')).toEqual(true);
expect(t.alterTableData('update schema.table set a = 1')).toEqual(true);
expect(t.alterTableData('update "schema".table set a = 1')).toEqual(true);
expect(t.alterTableData('update "schema"."table" set a = 1')).toEqual(true);
expect(t.alterTableData('update "schema-dash".table set a = 1')).toEqual(true);
expect(t.alterTableData('update "schema-dash"."table" set a = 1')).toEqual(true);
});
it("isGeoreferenced should be false when there's geom and no data", function () {
// var r = new RowModel({
// cartodb_id: 100,
// the_geom: JSON.stringify({ type: 'point', coordinates: [2, 1] })
// });
table = CartoTableMetadataFixture({
name: 'test',
schema: [['the_geom', 'geometry']],
geometry_types: []
}, configModel);
expect(table.isGeoreferenced()).toEqual(false);
});
it('row fetch should request geometry', function () {
// Hack: Inject username in window to avoid requiring
// the userModel in RowModel
window.user_name = 'testusername';
table = CartoTableMetadataFixture({
name: 'test',
schema: [['the_geom', 'geometry'], ['testa', 'number']]
}, configModel);
var r = new RowModel({ cartodb_id: 100 }, { configModel });
r.table = table;
var sqlArg;
spyOn(SQL.prototype, 'execute').and.callFake(sql => {
sqlArg = sql;
return { done: function () {} };
});
r.fetch();
expect(sqlArg).toEqual('SELECT testa ,ST_AsGeoJSON(the_geom, 8) as the_geom from (select * from test) _table_sql WHERE cartodb_id = 100');
window.user_name = undefined;
});
it('row should not fetch the geom when no_geom is passed', function () {
// Hack: Inject username in window to avoid requiring
// the userModel in RowModel
window.user_name = 'testusername';
table = CartoTableMetadataFixture({
name: 'test',
schema: [['testa', 'number'], ['the_geom', 'geometry']]
}, configModel);
var r = new RowModel({ cartodb_id: 100 }, { configModel });
r.table = table;
var sqlArg;
spyOn(SQL.prototype, 'execute').and.callFake(sql => {
sqlArg = sql;
return { done: function () {} };
});
r.fetch({ no_geom: true });
expect(sqlArg).toEqual('SELECT testa from (select * from test) _table_sql WHERE cartodb_id = 100');
window.user_name = undefined;
});
it('row should not fetch the geom when no_geom is passed but quote the sql if needed', function () {
// Hack: Inject username in window to avoid requiring
// the userModel in RowModel
window.user_name = 'testusername';
table = CartoTableMetadataFixture({
name: '000cd294-b124-4f82-b569-0f7fe41d2db8',
schema: [['testa', 'number'], ['the_geom', 'geometry']]
}, configModel);
var r = new RowModel({ cartodb_id: 100 }, { configModel });
r.table = table;
var sqlArg;
spyOn(SQL.prototype, 'execute').and.callFake(sql => {
sqlArg = sql;
return { done: function () {} };
});
r.fetch({ no_geom: true });
expect(sqlArg).toEqual('SELECT testa from (select * from "000cd294-b124-4f82-b569-0f7fe41d2db8") _table_sql WHERE cartodb_id = 100');
window.user_name = undefined;
});
it("isGeoreferenced should be false when there isn't any geometry column", function () {
expect(table.isGeoreferenced()).toEqual(false);
});
it("isGeoreferenced should be true when there's geom and data", function () {
var r = new RowModel({
cartodb_id: 100,
the_geom: JSON.stringify({ type: 'point', coordinates: [2, 1] })
}, { configModel });
table = CartoTableMetadataFixture({
name: 'test',
schema: [['the_geom', 'geometry']]
}, configModel);
table.data().add(r);
expect(table.isGeoreferenced()).toEqual(true);
});
it("isGeoreferenced should be true when there's geom and geometry data, but it's not loaded yet", function () {
var r = new RowModel({
cartodb_id: 100,
the_geom: 'GeoJSON'
}, { configModel });
table = CartoTableMetadataFixture({
name: 'test',
schema: [['the_geom', 'geometry']]
}, configModel);
table.data().add(r);
expect(table.isGeoreferenced()).toEqual(true);
});
it("isGeoreferenced should be false when there's geom and no georef data", function () {
var r = new RowModel({
cartodb_id: 100,
the_geom: null
}, { configModel });
table = CartoTableMetadataFixture({
name: 'test',
schema: [['the_geom', 'geometry']],
geometry_types: []
}, configModel);
table.data().add(r);
expect(table.isGeoreferenced()).toEqual(false);
});
it('should change schema when a sqlview is reset', function () {
var sqlView = new SQLViewDataModel(null, { sql: 'select * from a', configModel });
table.useSQLView(sqlView);
sqlView.reset([
{ a: 1, b: 2 }
]);
spyOn(table._data, 'fetch');
expect(sqlView.table).toEqual(table);
table.useSQLView(null);
expect(table._data.fetch).toHaveBeenCalled();
expect(sqlView.table).toEqual(null);
});
it('should remove sqlview when sqlview executes a write query', function () {
var sqlView = new SQLViewDataModel(null, { sql: 'insert bbblba', configModel });
table.useSQLView(sqlView);
spyOn(table, 'fetch');
sqlView.modify_rows = true;
sqlView.reset([
{ a: 1, b: 2 }
]);
expect(table.isInSQLView()).toEqual(false);
});
it('it should return a row', function () {
var r = table.data().getRow(1234);
// This was set before to id attribute, but looks
// like the code changed ¯\_(ツ)_/¯
expect(r.get('cartodb_id')).toEqual(1234);
});
it('newRow should fetch the table if table is emtpy', function () {
table.data().reset([]);
var r = table.data().newRow();
spyOn(table.data(), 'fetch');
r.trigger('saved');
expect(table.data().fetch).toHaveBeenCalled();
});
it('should be able to link to infowindow', function () {
const info = new InfowindowModel({}, { configModel });
info.addField('test').addField('test2');
table.linkToInfowindow(info);
table.trigger('columnRename', 'tt', 'test');
expect(info.containsField('test')).toEqual(false);
expect(info.containsField('tt')).toEqual(true);
table.trigger('columnRename', 'java', 'tt');
expect(info.containsField('tt')).toEqual(false);
});
it('should not clear infowindow on write queries', function () {
const info = new InfowindowModel({}, { configModel });
info.addField('test');
table.linkToInfowindow(info);
var sqlView = new SQLViewDataModel(null, { sql: 'select * from a', configModel });
sqlView.url = 'test';
table.useSQLView(sqlView);
sqlView.modify_rows = true;
sqlView.reset([]);
expect(info.containsField('test')).toEqual(true);
});
it('should return default sql', function () {
expect(table.data().getSQL()).toEqual('select * from testTable');
});
it('should retrieve a column type', function () {
var type = table.getColumnType('test');
expect(type).toEqual('string');
});
it('should add a column', function () {
jasmine.Ajax.install();
var succeded = false;
var signalCalled = false;
table.bind('columnAdd', function () {
signalCalled = true;
});
table.addColumn('irrelevant1', 'string', {
success: function () {
succeded = true;
}
});
jasmine.Ajax.requests.mostRecent().respondWith({
status: 200,
contentType: 'application/json',
responseText: '{"name":"irrelevant1","type":"text","cartodb_type":"string"}'
});
expect(succeded).toBeTruthy();
expect(signalCalled).toEqual(true);
jasmine.Ajax.uninstall();
});
it('should remove a column', function () {
jasmine.Ajax.install();
var succeded = false;
table.bind('columnDelete', function () {
succeded = true;
});
spyOn(table._data, 'fetch');
table.deleteColumn('test');
jasmine.Ajax.requests.mostRecent().respondWith({
status: 200,
contentType: 'application/json',
responseText: '{"name":"irrelevant1","type":"text","cartodb_type":"string"}'
});
expect(succeded).toBeTruthy();
expect(table._data.fetch).toHaveBeenCalled();
jasmine.Ajax.uninstall();
});
it("should not remove a column if it's invalid", function () {
var succeded = false;
table.bind('columnDelete', function () {
succeded = true;
});
table.deleteColumn('');
expect(succeded).not.toBeTruthy();
});
it('should rename a column', function () {
jasmine.Ajax.install();
var succeded = false;
table.bind('columnRename', function (newName, oldName) {
if (oldName === 'test' && newName === 'irrelevant') {
succeded = true;
}
});
spyOn(table._data, 'fetch');
table.renameColumn('test', 'irrelevant');
jasmine.Ajax.requests.mostRecent().respondWith({
status: 200,
contentType: 'application/json',
responseText: '{"name":"irrelevant1","type":"text","cartodb_type":"string"}'
});
expect(succeded).toBeTruthy();
expect(table._data.fetch).toHaveBeenCalled();
jasmine.Ajax.uninstall();
});
it('should be able to say if a type change is possible', function () {
expect(table.isTypeChangeAllowed('test2', 'string')).toBeTruthy();
expect(table.isTypeChangeAllowed('test2', 'date')).toBeFalsy();
expect(table.isTypeChangeAllowed('test', 'date')).toBeTruthy();
});
it('should be able to say if a type change is destructive', function () {
expect(table.isTypeChangeDestructive('test2', 'string')).toBeFalsy();
expect(table.isTypeChangeDestructive('test', 'number')).toBeTruthy();
});
it('should change the type of a column', function () {
jasmine.Ajax.install();
var succeded = false;
table.bind('typeChanged', function (newType) {
if (newType === 'string') {
succeded = true;
}
});
spyOn(table._data, 'fetch');
table.changeColumnType('test2', 'string');
jasmine.Ajax.requests.mostRecent().respondWith({
status: 200,
contentType: 'application/json',
responseText: '{"name":"irrelevant1","type":"text","cartodb_type":"string"}'
});
expect(succeded).toBeTruthy();
expect(table._data.fetch).toHaveBeenCalled();
jasmine.Ajax.uninstall();
});
it("should trigger an error when there's any error saving the type change", function () {
jasmine.Ajax.install();
var succeded = false;
table.bind('typeChangeFailed', function (newType) {
if (newType === 'string') {
succeded = true;
}
});
table.changeColumnType('test2', 'string');
jasmine.Ajax.requests.mostRecent().respondWith({
status: 500,
responseText: '{ "errors": ["Fake Error"]}'
});
expect(succeded).toBeTruthy();
jasmine.Ajax.uninstall();
});
it('should do nothing when you try to change a column to its own type', function () {
spyOn(table, 'saveNewColumnType');
table.changeColumnType('test', 'string');
expect(table.saveNewColumnType).not.toHaveBeenCalled();
});
it('shoudl not fetch data when geometry_types change', function () {
table.trigger('change');
spyOn(table._data, 'fetch');
table.set('geometry_types', ['st_polygon', 'st_multilinestring']);
expect(table._data.fetch).not.toHaveBeenCalled();
});
it('should raise when read only is set', function () {
var called = 0;
table.bind('change:readOnly', function () {
++called;
});
table.setReadOnly(true);
expect(called).toEqual(1);
table.setReadOnly(true);
expect(called).toEqual(1);
table.setReadOnly(false);
expect(called).toEqual(2);
});
describe('.duplicate', function () {
beforeEach(function () {
spyOn(ImportModel.prototype, 'save');
});
describe('when table is in SQL view', function () {
beforeEach(function () {
spyOn(table, 'isInSQLView').and.returnValue(true);
table.duplicate('foobar', {});
});
it('should the new table name', function () {
expect(ImportModel.prototype.save).toHaveBeenCalled();
expect(ImportModel.prototype.save.calls.argsFor(0)[0]).toEqual(jasmine.objectContaining({ table_name: 'foobar' }));
});
it('should return an object with SQL', function () {
expect(ImportModel.prototype.save.calls.argsFor(0)[0]).toEqual(jasmine.objectContaining({ sql: 'select * from testTable' }));
});
});
describe('when table is not in SQL view', function () {
beforeEach(function () {
spyOn(table, 'isInSQLView').and.returnValue(false);
table.duplicate('foobar', {});
});
it('should the new table name', function () {
expect(ImportModel.prototype.save).toHaveBeenCalled();
expect(ImportModel.prototype.save.calls.argsFor(0)[0]).toEqual(jasmine.objectContaining({ table_name: 'foobar' }));
});
it('should return an object with SQL', function () {
expect(ImportModel.prototype.save.calls.argsFor(0)[0]).toEqual(jasmine.objectContaining({ table_copy: 'testTable' }));
});
});
describe('when import creation fails', function () {
beforeEach(function () {
this.errorCallback = jasmine.createSpy('error');
table.duplicate('foobar', {
error: this.errorCallback
});
ImportModel.prototype.save.calls.argsFor(0)[1].error();
});
it('should call the error callback', function () {
expect(this.errorCallback).toHaveBeenCalled();
});
});
describe('when import creation succeeds', function () {
let importModelError, importModelCompleted;
beforeEach(function () {
const originalBind = ImportModel.prototype.bind;
spyOn(ImportModel.prototype, 'pollCheck');
spyOn(ImportModel.prototype, 'bind').and.callFake(function (event, callback) {
if (event === 'importError') {
importModelError = this;
}
if (event === 'importComplete') {
importModelCompleted = this;
}
originalBind.apply(this, arguments);
});
this.errorCallback = jasmine.createSpy('error');
this.successCallback = jasmine.createSpy('success');
table.duplicate('foobar', {
error: this.errorCallback,
success: this.successCallback
});
ImportModel.prototype.save.calls.argsFor(0)[1].success(this.fakeImport, { item_queue_id: 'abc-123' });
});
afterEach(function () {
importModelError.unbind();
importModelCompleted.unbind();
importModelError = undefined;
importModelCompleted = undefined;
});
xit('should create a new import model from the old one', function () {
// Untestable
expect(ImportModel.calls.count()).toEqual(2);
expect(ImportModel.calls.argsFor(1)[0]).toEqual(jasmine.objectContaining({ item_queue_id: 'abc-123' }));
});
it('should start checking for import status', function () {
expect(ImportModel.prototype.pollCheck).toHaveBeenCalled();
});
describe('when import fails', function () {
beforeEach(function () {
importModelError.trigger('importError', 1, 2, 3);
});
it('should called error callback with args', function () {
expect(this.errorCallback).toHaveBeenCalled();
expect(this.errorCallback).toHaveBeenCalledWith(1, 2, 3);
});
});
describe('when import succeeds', function () {
let createdTable;
beforeEach(function () {
spyOn(CartoTableMetadata.prototype, 'fetch').and.callFake(function (options) {
options.success && options.success();
});
this.fakeTable = new CartoTableMetadata(null, { configModel });
importModelCompleted.set('table_id', 'abc-123');
this.successCallback.and.callFake(function (newTable) {
createdTable = newTable;
});
importModelCompleted.trigger('importComplete');
});
it('should create new table from imported table id', function () {
expect(createdTable).toEqual(jasmine.objectContaining({ id: 'abc-123' }));
});
it('should fetch all table data for it to be ready', function () {
expect(createdTable.fetch).toHaveBeenCalled();
});
describe('when table fetch fails', function () {
beforeEach(function () {
createdTable.fetch.calls.argsFor(0)[0].error(1, 2, 3);
});
it('should call error callback with args', function () {
expect(this.errorCallback).toHaveBeenCalled();
expect(this.errorCallback).toHaveBeenCalledWith(1, 2, 3);
});
});
describe('when table fetch succeeds', function () {
beforeEach(function () {
createdTable.fetch.calls.argsFor(0)[0].success();
});
it('should call the sucess callback with new table', function () {
expect(this.successCallback).toHaveBeenCalled();
expect(this.successCallback).toHaveBeenCalledWith(createdTable);
});
});
});
});
});
describe('.dependentVisualizations', function () {
it('should return a list', function () {
expect(table.dependentVisualizations()).toEqual([]);
});
describe('when there are at least some dependent/non-dependent visualizations', function () {
beforeEach(function () {
table.set({
dependent_visualizations: [{id: 'dv1'}, {id: 'dv2'}],
non_dependent_visualizations: [{id: 'ndv1'}]
});
});
it('should return them as a list', function () {
var results = table.dependentVisualizations();
expect(results.length).toEqual(3);
expect(_.pluck(results, 'id')).toEqual(['dv1', 'dv2', 'ndv1']);
});
});
});
});