From 13a79eb48df3260d04dd61528c329705a7514b1b Mon Sep 17 00:00:00 2001
From: Tira + Joao <aodhner+jpereira@pivotal.io>
Date: Tue, 14 Mar 2017 17:34:11 -0400
Subject: [PATCH 2/5] Refactor copyData; Add feature test

---
 .../copy_selected_columns_feature_test.py          | 103 +++++++++++++++++++++
 web/pgadmin/static/js/selection/copy_data.js       |  45 +++++++++
 .../static/js/selection/tests/SpecRunner.html      |  15 +++
 .../static/js/selection/tests/copy_data_spec.js    |  35 +++++++
 .../sqleditor/templates/sqleditor/js/sqleditor.js  |  44 +--------
 web/regression/feature_utils/pgadmin_page.py       |   1 +
 6 files changed, 202 insertions(+), 41 deletions(-)
 create mode 100644 web/pgadmin/feature_tests/copy_selected_columns_feature_test.py
 create mode 100644 web/pgadmin/static/js/selection/copy_data.js
 create mode 100644 web/pgadmin/static/js/selection/tests/SpecRunner.html
 create mode 100644 web/pgadmin/static/js/selection/tests/copy_data_spec.js

diff --git a/web/pgadmin/feature_tests/copy_selected_columns_feature_test.py b/web/pgadmin/feature_tests/copy_selected_columns_feature_test.py
new file mode 100644
index 0000000..ab74819
--- /dev/null
+++ b/web/pgadmin/feature_tests/copy_selected_columns_feature_test.py
@@ -0,0 +1,103 @@
+import pyperclip
+import time
+
+from selenium.webdriver import ActionChains
+
+from regression import test_utils
+from regression.feature_utils.base_feature_test import BaseFeatureTest
+
+
+class CopySelectedColumnsFeatureTest(BaseFeatureTest):
+    def setUp(self):
+        # DO NOT CHECK THIS IN
+        self.server = {
+            "db": "postgres",
+            "host": "localhost",
+            "username": "pivotal",
+            "db_password": "",
+            "port": 5432,
+            "name": "like, whatever"
+        }
+        # IT IS NOT REAL.
+
+        connection = test_utils.get_db_connection(self.server['db'],
+                                                  self.server['username'],
+                                                  self.server['db_password'],
+                                                  self.server['host'],
+                                                  self.server['port'])
+        test_utils.drop_database(connection, "acceptance_test_db")
+
+        test_utils.create_database(self.server, "acceptance_test_db")
+
+        test_utils.create_table(self.server, "acceptance_test_db", "test_table")
+
+
+        super(CopySelectedColumnsFeatureTest, self).setUp()
+
+        self.page.add_server(self.server)
+
+
+    def runTest(self):
+        self.page.toggle_open_tree_item(self.server['name'])
+        self.page.toggle_open_tree_item('Databases')
+        self.page.toggle_open_tree_item('acceptance_test_db')
+        time.sleep(5)
+        self.page.find_by_partial_link_text("Tools").click()
+        self.page.find_by_partial_link_text("Query Tool").click()
+        self.page.click_tab('Query-1')
+        time.sleep(5)
+        ActionChains(self.page.driver).send_keys("SELECT * FROM test_table").perform()
+        self.page.driver.switch_to_frame(self.page.driver.find_element_by_tag_name("iframe"))
+        self.page.find_by_id("btn-flash").click()
+
+        self._copies_rows()
+        # self._copies_columns()
+
+    def _copies_rows(self):
+        pyperclip.copy("old clipboard contents")
+        time.sleep(5)
+        self.page.find_by_xpath("//*[contains(@class, 'sc l0 r0 sc-cb')]/input").click()
+        time.sleep(5)
+        self.page.find_by_xpath("//*[@id='btn-copy-row']").click()
+
+        self.assertEqual(
+"""'Some-Name','6'
+""",
+            pyperclip.paste())
+
+    def _copies_columns(self):
+        pyperclip.copy("old clipboard contents")
+        self.page.toggle_open_tree_item(self.server['name'])
+        self.page.toggle_open_tree_item('Databases')
+        self.page.toggle_open_tree_item('acceptance_test_db')
+        time.sleep(5)
+        self.page.find_by_partial_link_text("Tools").click()
+        self.page.find_by_partial_link_text("Query Tool").click()
+        self.page.click_tab('Query-1')
+        time.sleep(5)
+        ActionChains(self.page.driver).send_keys("SELECT * FROM test_table").perform()
+        self.page.driver.switch_to_frame(self.page.driver.find_element_by_tag_name("iframe"))
+
+        self.page.find_by_id("btn-flash").click()
+
+        time.sleep(5)
+
+        self.page.find_by_xpath("//*[@data-test='output-column-header' and .='name']/input").click()
+        self.page.find_by_xpath("//*[@id='btn-copy-row]").click()
+
+        self.assertEqual(
+"""
+name
+Some-Name
+""",
+            pyperclip.paste())
+
+    def tearDown(self):
+        self.page.remove_server(self.server)
+        self.app_starter.stop_app()
+        connection = test_utils.get_db_connection(self.server['db'],
+                                                  self.server['username'],
+                                                  self.server['db_password'],
+                                                  self.server['host'],
+                                                  self.server['port'])
+        test_utils.drop_database(connection, "acceptance_test_db")
\ No newline at end of file
diff --git a/web/pgadmin/static/js/selection/copy_data.js b/web/pgadmin/static/js/selection/copy_data.js
new file mode 100644
index 0000000..264defe
--- /dev/null
+++ b/web/pgadmin/static/js/selection/copy_data.js
@@ -0,0 +1,45 @@
+define(['jquery', 'js/selection/clipboard'], function ($, clipboard) {
+  var copyData = function () {
+    var self = this, grid, data, rows, selection, copied_text = '', copied_data = '';
+    self.copied_rows = [];
+
+    // Disable copy button
+    $("#btn-copy-row").prop('disabled', true);
+    // Enable paste button
+    if (self.can_edit) {
+      $("#btn-paste-row").prop('disabled', false);
+    }
+
+    grid = self.slickgrid;
+    selection = grid.getSelectionModel().getSelectedRanges();
+    data = grid.getData();
+    rows = grid.getSelectedRows();
+    // Iterate over all the selected rows & fetch data
+    for (var i = 0; i < rows.length; i += 1) {
+      var idx = rows[i],
+        _rowData = data[idx],
+        _values = [];
+      self.copied_rows.push(_rowData);
+      // Convert it as CSV for clipboard
+      for (var j = 0; j < self.columns.length; j += 1) {
+
+        var val = _rowData[self.columns[j].pos];
+        if(val && _.isObject(val))
+          val = "'" + JSON.stringify(val) + "'";
+        else if(val && typeof val != "number" && typeof true != "boolean")
+          val = "'" + val.toString() + "'";
+        else if (_.isNull(val) || _.isUndefined(val))
+          val = '';
+        _values.push(val);
+      }
+      // Append to main text string
+      if (_values.length > 0)
+        copied_text += _values.toString() + "\n";
+    }
+
+    // If there is something to set into clipboard
+    if (copied_text)
+      clipboard.copyTextToClipboard(copied_text);
+  };
+  return copyData
+});
\ No newline at end of file
diff --git a/web/pgadmin/static/js/selection/tests/SpecRunner.html b/web/pgadmin/static/js/selection/tests/SpecRunner.html
new file mode 100644
index 0000000..c3bc24b
--- /dev/null
+++ b/web/pgadmin/static/js/selection/tests/SpecRunner.html
@@ -0,0 +1,15 @@
+<!doctype html>
+<html>
+  <head>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    <title>Jasmine Spec Runner v2.0.0</title>
+
+    <link rel="shortcut icon" type="image/png" href="../../../vendor/jasmine-core/images/jasmine_favicon.png">
+    <link rel="stylesheet" type="text/css" href="../../../vendor/jasmine-core/lib/jasmine-core/jasmine.css">
+
+    <!-- specRunner.js runs all of the tests -->
+    <script data-main="test_main" src="../../../vendor/require/require.js"></script>
+  </head>
+  <body>
+  </body>
+</html>
\ No newline at end of file
diff --git a/web/pgadmin/static/js/selection/tests/copy_data_spec.js b/web/pgadmin/static/js/selection/tests/copy_data_spec.js
new file mode 100644
index 0000000..03b4cfe
--- /dev/null
+++ b/web/pgadmin/static/js/selection/tests/copy_data_spec.js
@@ -0,0 +1,35 @@
+define(
+  ["jquery",
+    "slickgrid/slick.grid",
+    "slickgrid/slick.rowselectionmodel",
+    "js/selection/copy_data",
+    "js/selection/clipboard"
+  ],
+  function ($, SlickGrid, RowSelectionModel, copyData, clipboard) {
+    describe('copyData', function () {
+      it('copies selected rows', function () {
+        var data = [{"brand":"nike","id":"1","size":"12"},
+          {"brand":"adidas","id":"2","size":"13"},
+          {"brand":"puma","id":"3","size":"9"}];
+        var columns = [{"name":"id","label":"id<br> numeric","cell":"number","can_edit":false,"type":"numeric"},
+          {"name":"brand","label":"brand<br> character varying","cell":"string","can_edit":false,"type":"character varying"},
+          {"name":"size","label":"size<br> numeric","cell":"number","can_edit":false,"type":"numeric"}];
+        var gridContainer = $("<div id='grid'></div>");
+        $("body").append(gridContainer);
+        var grid = new Slick.Grid("#grid", data, columns, {});
+        grid.setSelectionModel(new Slick.RowSelectionModel({selectActiveRow: false}));
+
+
+        var sqlEditor = {slickgrid: grid, columns: columns};
+        spyOn(clipboard, 'copyTextToClipboard');
+        spyOn(grid, 'getSelectedRows').and.returnValue([0, 2]);
+
+        copyData.apply(sqlEditor);
+
+        expect(sqlEditor.copied_rows.length).toBe(2);
+        expect(clipboard.copyTextToClipboard).toHaveBeenCalled();
+
+      })
+    })
+  }
+);
\ No newline at end of file
diff --git a/web/pgadmin/tools/sqleditor/templates/sqleditor/js/sqleditor.js b/web/pgadmin/tools/sqleditor/templates/sqleditor/js/sqleditor.js
index c109768..3279204 100644
--- a/web/pgadmin/tools/sqleditor/templates/sqleditor/js/sqleditor.js
+++ b/web/pgadmin/tools/sqleditor/templates/sqleditor/js/sqleditor.js
@@ -3,6 +3,7 @@ define(
     'jquery', 'underscore', 'underscore.string', 'alertify', 'pgadmin',
     'backbone', 'backgrid', 'codemirror', 'pgadmin.misc.explain',
     'sources/selection/column_selector', 'sources/selection/clipboard',
+    'sources/selection/copy_data',
 
     'slickgrid', 'bootstrap', 'pgadmin.browser', 'wcdocker',
     'codemirror/mode/sql/sql', 'codemirror/addon/selection/mark-selection',
@@ -27,7 +28,7 @@ define(
     'slickgrid/slick.grid'
   ],
   function(
-    $, _, S, alertify, pgAdmin, Backbone, Backgrid, CodeMirror, pgExplain, ColumnSelector, clipboard
+    $, _, S, alertify, pgAdmin, Backbone, Backgrid, CodeMirror, pgExplain, ColumnSelector, clipboard, copyData
   ) {
     /* Return back, this has been called more than once */
     if (pgAdmin.SqlEditor)
@@ -2936,46 +2937,7 @@ define(
         },
 
         // This function will copy the selected row.
-        _copy_row: function() {
-          var self = this, grid, data, rows, copied_text = '';
-
-          self.copied_rows = [];
-
-          // Disable copy button
-          $("#btn-copy-row").prop('disabled', true);
-          // Enable paste button
-          if(self.can_edit) {
-            $("#btn-paste-row").prop('disabled', false);
-          }
-
-          grid = self.slickgrid;
-          data = grid.getData();
-          rows = grid.getSelectedRows();
-          // Iterate over all the selected rows & fetch data
-          for (var i = 0; i < rows.length; i += 1) {
-            var idx = rows[i],
-              _rowData = data[idx],
-              _values = [];
-            self.copied_rows.push(_rowData);
-            // Convert it as CSV for clipboard
-            for (var j = 0; j < self.columns.length; j += 1) {
-               var val = _rowData[self.columns[j].pos];
-               if(val && _.isObject(val))
-                 val = "'" + JSON.stringify(val) + "'";
-               else if(val && typeof val != "number" && typeof true != "boolean")
-                 val = "'" + val.toString() + "'";
-               else if (_.isNull(val) || _.isUndefined(val))
-                 val = '';
-                _values.push(val);
-            }
-            // Append to main text string
-            if(_values.length > 0)
-              copied_text += _values.toString() + "\n";
-          }
-          // If there is something to set into clipboard
-          if(copied_text)
-            clipboard.copyTextToClipboard(copied_text);
-        },
+        _copy_row: copyData,
 
         // This function will paste the selected row.
         _paste_row: function() {
diff --git a/web/regression/feature_utils/pgadmin_page.py b/web/regression/feature_utils/pgadmin_page.py
index 96c2821..cba4824 100644
--- a/web/regression/feature_utils/pgadmin_page.py
+++ b/web/regression/feature_utils/pgadmin_page.py
@@ -47,6 +47,7 @@ class PgadminPage:
         self.find_by_xpath("//*[@id='tree']//*[.='" + server_config['name'] + "']")
 
     def remove_server(self, server_config):
+        self.driver.switch_to.default_content()
         self.find_by_xpath("//*[@id='tree']//*[.='" + server_config['name'] + "' and @class='aciTreeItem']").click()
         self.find_by_partial_link_text("Object").click()
         self.find_by_partial_link_text("Delete/Drop").click()
-- 
2.10.1 (Apple Git-78)

