<commit_before>var Backbone = require('backbone');
var ConfigModel = require('../../../../javascripts/cartodb3/data/config-model');
var AnalysisDefinitionNodesCollection = require('../../../../javascripts/cartodb3/data/analysis-definition-nodes-collection');
var LayerDefinitionsCollection = require('../../../../javascripts/cartodb3/data/layer-definitions-collection');
var layerColors = require('../../../../javascripts/cartodb3/data/layer-colors');

describe('data/layer-definitions-collection', function () {
  beforeEach(function () {
    var configModel = new ConfigModel({
      user_name: 'pepe',
      base_url: '/u/pepe'
    });

    this.analysisDefinitionNodesCollection = new AnalysisDefinitionNodesCollection(null, {
      configModel: configModel
    });

    this.collection = new LayerDefinitionsCollection(null, {
      configModel: configModel,
      analysisDefinitionNodesCollection: this.analysisDefinitionNodesCollection,
      mapId: 'm-123'
    });
  });

  describe('.add', function () {
    it('should not have created source nodes for layers that have non-sources', function () {
      this.collection.add({
        id: 'A',
        kind: 'carto',
        options: {
          table_name: 'alice',
          source: 'a1'
        }
      });
      expect(this.analysisDefinitionNodesCollection.pluck('id')).not.toContain('a0');
    });

    it('should create source if it matches expected source node id', function () {
      this.collection.add({
        id: 'A',
        kind: 'carto',
        options: {
          table_name: 'alice',
          source: 'a0'
        }
      });
      expect(this.analysisDefinitionNodesCollection.pluck('id')).toContain('a0');
    });
  });

  it('should create the layer with the next letter representation available but only for data layers', function () {
    // Adds A-D, like if the collection was created from scratch
    var layersData = [
      {kind: 'tiled', order: 0}, // a basemap
      {kind: 'carto', order: 1, options: {letter: 'b'}},
      {kind: 'carto', order: 2},
      {kind: 'carto', order: 3, options: {letter: 'a'}},
      {kind: 'torque', order: 4}
    ];
    this.collection.resetByLayersData(layersData);
    expect(this.collection.pluck('letter')).toEqual([undefined, 'b', 'c', 'a', 'd']);

    // Remove C
    this.collection.remove(this.collection.findWhere({letter: 'c'}));
    expect(this.collection.pluck('letter')).toEqual([undefined, 'b', 'a', 'd']);

    // Add new as C
    this.collection.add({kind: 'carto', order: 4});
    expect(this.collection.pluck('letter')).toEqual([undefined, 'b', 'a', 'd', 'c']);

    // Add new as E, F, G
    this.collection.add([
      {kind: 'carto', order: 5},
      {kind: 'carto', order: 6},
      {kind: 'carto', order: 7}
    ]);
    expect(this.collection.pluck('letter')).toEqual([undefined, 'b', 'a', 'd', 'c', 'e', 'f', 'g']);

    // Add a new tiled (labels-on-top) layer
    this.collection.add({kind: 'tiled', order: 8});
    expect(this.collection.pluck('letter')).toEqual([undefined, 'b', 'a', 'd', 'c', 'e', 'f', 'g', undefined]);

    // Remove all existing and add a new, should reset letters
    this.collection.reset([
      {kind: 'tiled'},
      {kind: 'carto'}
    ]);
    expect(this.collection.pluck('letter')).toEqual([undefined, 'a']);
  });

  it('should create the layer with the color that corresponds to the letter', function () {
    var layersData = [
      { kind: 'tiled', order: 0 }, // a basemap
      { kind: 'carto', order: 1 },
      { kind: 'carto', order: 2 },
      { kind: 'torque', order: 3 }
    ];

    this.collection.resetByLayersData(layersData);
    expect(this.collection.pluck('letter')).toEqual([ undefined, 'a', 'b', 'c' ]);
    expect(this.collection.pluck('color')).toEqual([ undefined, layerColors.COLORS[0], layerColors.COLORS[1], layerColors.COLORS[2] ]);

    this.collection.remove(this.collection.at(0));
    expect(this.collection.pluck('letter')).toEqual([ 'a', 'b', 'c' ]);
    expect(this.collection.pluck('color')).toEqual([ layerColors.COLORS[0], layerColors.COLORS[1], layerColors.COLORS[2] ]);

    this.collection.add({ kind: 'carto' });
    expect(this.collection.pluck('letter')).toEqual([ 'a', 'b', 'c', 'd' ]);
    expect(this.collection.pluck('color')).toEqual([ layerColors.COLORS[0], layerColors.COLORS[1], layerColors.COLORS[2], layerColors.COLORS[3] ]);

    // Remove all existing and add a couple of new layers
    this.collection.reset([
      { kind: 'carto' },
      { kind: 'carto' }
    ]);
    expect(this.collection.pluck('letter')).toEqual([ 'a', 'b' ]);
    expect(this.collection.pluck('color')).toEqual([layerColors.COLORS[0], layerColors.COLORS[1]]);
  });

  it('should create a layer with the owner of the table in the query', function () {
    var layer1 = this.collection.add({
      kind: 'carto',
      options: {
        table_name: 'table_name',
        user_name: 'paco'
      }
    });

    expect(layer1.get('sql').toLowerCase()).toBe('select * from "paco".table_name');

    layer1 = this.collection.add({
      kind: 'carto',
      options: {
        table_name: '000cd294-b124-4f82-b569-0f7fe41d2db8',
        user_name: 'paco'
      }
    });

    expect(layer1.get('sql').toLowerCase()).toBe('select * from "paco"."000cd294-b124-4f82-b569-0f7fe41d2db8"');

    var layer2 = this.collection.add({
      kind: 'carto',
      options: {
        table_name: 'table_name',
        user_name: 'pepe'
      }
    });

    expect(layer2.get('sql').toLowerCase()).toBe('select * from table_name');

    var layer3 = this.collection.add({
      kind: 'carto',
      options: {
        table_name: '"paco".table_name',
        user_name: ''
      }
    });

    expect(layer3.get('sql').toLowerCase()).toBe('select * from "paco".table_name');
  });

  describe('when there are some layers', function () {
    beforeEach(function () {
      this.collection.reset([{
        id: 'l-0',
        order: 0,
        kind: 'tiled',
        options: {
          name: 'Basemap'
        }
      }, {
        id: 'l-1',
        order: 1,
        kind: 'carto',
        options: {
          letter: 'a',
          table_name: 'foobar'
        }
      }, {
        id: 'l-2',
        order: 2,
        kind: 'carto',
        options: {
          letter: 'b',
          source: 'b0',
          table_name: 'foobar',
          query: 'SELECT * FROM foobar limit 10'
        }
      }]);<commit_msg>Check that source node has the same query than the layer when it is added to the collection<commit_after>var Backbone = require('backbone');
var ConfigModel = require('../../../../javascripts/cartodb3/data/config-model');
var AnalysisDefinitionNodesCollection = require('../../../../javascripts/cartodb3/data/analysis-definition-nodes-collection');
var LayerDefinitionsCollection = require('../../../../javascripts/cartodb3/data/layer-definitions-collection');
var layerColors = require('../../../../javascripts/cartodb3/data/layer-colors');

describe('data/layer-definitions-collection', function () {
  beforeEach(function () {
    var configModel = new ConfigModel({
      user_name: 'pepe',
      base_url: '/u/pepe'
    });

    this.analysisDefinitionNodesCollection = new AnalysisDefinitionNodesCollection(null, {
      configModel: configModel
    });

    this.collection = new LayerDefinitionsCollection(null, {
      configModel: configModel,
      analysisDefinitionNodesCollection: this.analysisDefinitionNodesCollection,
      mapId: 'm-123'
    });
  });

  describe('.add', function () {
    it('should not have created source nodes for layers that have non-sources', function () {
      this.collection.add({
        id: 'A',
        kind: 'carto',
        options: {
          table_name: 'alice',
          source: 'a1'
        }
      });
      expect(this.analysisDefinitionNodesCollection.pluck('id')).not.toContain('a0');
    });

    it('should create source if it matches expected source node id', function () {
      this.collection.add({
        id: 'A',
        kind: 'carto',
        options: {
          table_name: 'alice',
          source: 'a0'
        }
      });
      expect(this.analysisDefinitionNodesCollection.pluck('id')).toContain('a0');
    });
  });

  it('should create the layer with the next letter representation available but only for data layers', function () {
    // Adds A-D, like if the collection was created from scratch
    var layersData = [
      {kind: 'tiled', order: 0}, // a basemap
      {kind: 'carto', order: 1, options: {letter: 'b'}},
      {kind: 'carto', order: 2},
      {kind: 'carto', order: 3, options: {letter: 'a'}},
      {kind: 'torque', order: 4}
    ];
    this.collection.resetByLayersData(layersData);
    expect(this.collection.pluck('letter')).toEqual([undefined, 'b', 'c', 'a', 'd']);

    // Remove C
    this.collection.remove(this.collection.findWhere({letter: 'c'}));
    expect(this.collection.pluck('letter')).toEqual([undefined, 'b', 'a', 'd']);

    // Add new as C
    this.collection.add({kind: 'carto', order: 4});
    expect(this.collection.pluck('letter')).toEqual([undefined, 'b', 'a', 'd', 'c']);

    // Add new as E, F, G
    this.collection.add([
      {kind: 'carto', order: 5},
      {kind: 'carto', order: 6},
      {kind: 'carto', order: 7}
    ]);
    expect(this.collection.pluck('letter')).toEqual([undefined, 'b', 'a', 'd', 'c', 'e', 'f', 'g']);

    // Add a new tiled (labels-on-top) layer
    this.collection.add({kind: 'tiled', order: 8});
    expect(this.collection.pluck('letter')).toEqual([undefined, 'b', 'a', 'd', 'c', 'e', 'f', 'g', undefined]);

    // Remove all existing and add a new, should reset letters
    this.collection.reset([
      {kind: 'tiled'},
      {kind: 'carto'}
    ]);
    expect(this.collection.pluck('letter')).toEqual([undefined, 'a']);
  });

  it('should create the layer with the color that corresponds to the letter', function () {
    var layersData = [
      { kind: 'tiled', order: 0 }, // a basemap
      { kind: 'carto', order: 1 },
      { kind: 'carto', order: 2 },
      { kind: 'torque', order: 3 }
    ];

    this.collection.resetByLayersData(layersData);
    expect(this.collection.pluck('letter')).toEqual([ undefined, 'a', 'b', 'c' ]);
    expect(this.collection.pluck('color')).toEqual([ undefined, layerColors.COLORS[0], layerColors.COLORS[1], layerColors.COLORS[2] ]);

    this.collection.remove(this.collection.at(0));
    expect(this.collection.pluck('letter')).toEqual([ 'a', 'b', 'c' ]);
    expect(this.collection.pluck('color')).toEqual([ layerColors.COLORS[0], layerColors.COLORS[1], layerColors.COLORS[2] ]);

    this.collection.add({ kind: 'carto' });
    expect(this.collection.pluck('letter')).toEqual([ 'a', 'b', 'c', 'd' ]);
    expect(this.collection.pluck('color')).toEqual([ layerColors.COLORS[0], layerColors.COLORS[1], layerColors.COLORS[2], layerColors.COLORS[3] ]);

    // Remove all existing and add a couple of new layers
    this.collection.reset([
      { kind: 'carto' },
      { kind: 'carto' }
    ]);
    expect(this.collection.pluck('letter')).toEqual([ 'a', 'b' ]);
    expect(this.collection.pluck('color')).toEqual([layerColors.COLORS[0], layerColors.COLORS[1]]);
  });

  it('should create a layer with the owner of the table in the query', function () {
    var layer1 = this.collection.add({
      kind: 'carto',
      options: {
        table_name: 'table_name',
        user_name: 'paco'
      }
    });

    var sourceNode1 = this.analysisDefinitionNodesCollection.get(layer1.get('source'));
    expect(layer1.get('sql').toLowerCase()).toBe('select * from "paco".table_name');
    expect(sourceNode1.get('query').toLowerCase()).toBe('select * from "paco".table_name');

    var layer2 = this.collection.add({
      kind: 'carto',
      options: {
        table_name: '000cd294-b124-4f82-b569-0f7fe41d2db8',
        user_name: 'paco'
      }
    });

    var sourceNode2 = this.analysisDefinitionNodesCollection.get(layer2.get('source'));
    expect(layer2.get('sql').toLowerCase()).toBe('select * from "paco"."000cd294-b124-4f82-b569-0f7fe41d2db8"');
    expect(sourceNode2.get('query').toLowerCase()).toBe('select * from "paco"."000cd294-b124-4f82-b569-0f7fe41d2db8"');

    var layer3 = this.collection.add({
      kind: 'carto',
      options: {
        table_name: 'table_name',
        user_name: 'pepe'
      }
    });

    var sourceNode3 = this.analysisDefinitionNodesCollection.get(layer3.get('source'));
    expect(layer3.get('sql').toLowerCase()).toBe('select * from table_name');
    expect(sourceNode3.get('query').toLowerCase()).toBe('select * from table_name');

    var layer4 = this.collection.add({
      kind: 'carto',
      options: {
        table_name: '"paco".table_name',
        user_name: ''
      }
    });

    var sourceNode4 = this.analysisDefinitionNodesCollection.get(layer4.get('source'));
    expect(layer4.get('sql').toLowerCase()).toBe('select * from "paco".table_name');
    expect(sourceNode4.get('query').toLowerCase()).toBe('select * from "paco".table_name');
  });

  describe('when there are some layers', function () {
    beforeEach(function () {
      this.collection.reset([{
        id: 'l-0',
        order: 0,
        kind: 'tiled',
        options: {
          name: 'Basemap'
        }
      }, {
        id: 'l-1',
        order: 1,
        kind: 'carto',
        options: {
          letter: 'a',
          table_name: 'foobar'
        }
      }, {
        id: 'l-2',
        order: 2,
        kind: 'carto',
        options: {
          letter: 'b',
          source: 'b0',
          table_name: 'foobar',
          query: 'SELECT * FROM foobar limit 10'
        }
      }]);
{'fraction_non_alphanumeric': 0.18159841769833712, 'fraction_numerical': 0.016628818401582302, 'mean_word_length': 2.9207352096496266, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7152738', 'n_tokens_mistral': 4431, 'n_tokens_neox': 4376, 'n_words': 902}