GUI -- Added isMobile() predicate to FnService.
- Mocked out $window in fn-spec.js and table-spec.js

Change-Id: Ibe59c742b3955809ea9a64dabc9a7e3779dd6199
diff --git a/web/gui/src/main/webapp/app/fw/util/fn.js b/web/gui/src/main/webapp/app/fw/util/fn.js
index e504a8c..3c810a5 100644
--- a/web/gui/src/main/webapp/app/fw/util/fn.js
+++ b/web/gui/src/main/webapp/app/fw/util/fn.js
@@ -102,6 +102,13 @@
         };
     }
 
+    // Returns true if current browser determined to be a mobile device
+    function isMobile() {
+        var ua = $window.navigator.userAgent,
+            patt = /iPhone|iPod|iPad|Silk|Android|BlackBerry|Opera Mini|IEMobile/;
+        return patt.test(ua);
+    }
+
     // search through an array of objects, looking for the one with the
     // tagged property matching the given key. tag defaults to 'id'.
     // returns the index of the matching object, or -1 for no match.
@@ -171,6 +178,7 @@
                 areFunctions: areFunctions,
                 areFunctionsNonStrict: areFunctionsNonStrict,
                 windowSize: windowSize,
+                isMobile: isMobile,
                 find: find,
                 inArray: inArray,
                 removeFromArray: removeFromArray,
diff --git a/web/gui/src/main/webapp/tests/app/fw/util/fn-spec.js b/web/gui/src/main/webapp/tests/app/fw/util/fn-spec.js
index a7e8b47..8838998 100644
--- a/web/gui/src/main/webapp/tests/app/fw/util/fn-spec.js
+++ b/web/gui/src/main/webapp/tests/app/fw/util/fn-spec.js
@@ -30,12 +30,23 @@
 
     beforeEach(module('onosUtil'));
 
+    var mockWindow = {
+        innerWidth: 400,
+        innerHeight: 200,
+        navigator: {
+            userAgent: 'defaultUA'
+        }
+    };
+
+    beforeEach(function () {
+        module(function ($provide) {
+            $provide.value('$window', mockWindow);
+        });
+    });
+
     beforeEach(inject(function (_$window_, FnService) {
         $window = _$window_;
         fs = FnService;
-
-        $window.innerWidth = 400;
-        $window.innerHeight = 200;
     }));
 
     // === Tests for isF()
@@ -201,8 +212,8 @@
     it('should define api functions', function () {
         expect(fs.areFunctions(fs, [
             'isF', 'isA', 'isS', 'isO', 'contains',
-            'areFunctions', 'areFunctionsNonStrict', 'windowSize', 'find',
-            'inArray', 'removeFromArray', 'isEmptyObject', 'cap'
+            'areFunctions', 'areFunctionsNonStrict', 'windowSize', 'isMobile',
+            'find', 'inArray', 'removeFromArray', 'isEmptyObject', 'cap'
         ])).toBeTruthy();
     });
 
@@ -232,6 +243,39 @@
         expect(dim.height).toEqual(99);
     });
 
+    // === Tests for isMobile()
+    var uaMap = {
+        chrome: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_2) " +
+                "AppleWebKit/537.36 (KHTML, like Gecko) " +
+                "Chrome/41.0.2272.89 Safari/537.36",
+
+        iPad: "Mozilla/5.0 (iPad; CPU OS 7_0 like Mac OS X) " +
+                "AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 " +
+                "Mobile/11A465 Safari/9537.53",
+
+        iPhone: "Mozilla/5.0 (iPhone; CPU iPhone OS 7_0 like Mac OS X) " +
+                "AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 " +
+                "Mobile/11A465 Safari/9537.53"
+    };
+
+    function setUa(key) {
+        var str = uaMap[key];
+        expect(str).toBeTruthy();
+        mockWindow.navigator.userAgent = str;
+    }
+
+    it('isMobile(): should be false for Chrome on Mac OS X', function () {
+        setUa('chrome');
+        expect(fs.isMobile()).toBe(false);
+    });
+    it('isMobile(): should be true for Safari on iPad', function () {
+        setUa('iPad');
+        expect(fs.isMobile()).toBe(true);
+    });
+    it('isMobile(): should be true for Safari on iPhone', function () {
+        setUa('iPhone');
+        expect(fs.isMobile()).toBe(true);
+    });
 
     // === Tests for find()
     var dataset = [
diff --git a/web/gui/src/main/webapp/tests/app/fw/widget/table-spec.js b/web/gui/src/main/webapp/tests/app/fw/widget/table-spec.js
index 1b35376..107d27d 100644
--- a/web/gui/src/main/webapp/tests/app/fw/widget/table-spec.js
+++ b/web/gui/src/main/webapp/tests/app/fw/widget/table-spec.js
@@ -75,6 +75,22 @@
 
     beforeEach(module('onosWidget', 'onosUtil', 'onosSvg'));
 
+    var mockWindow = {
+        innerWidth: 400,
+        innerHeight: 200,
+        navigator: {
+            userAgent: 'defaultUA'
+        },
+        on: function () {},
+        addEventListener: function () {}
+    };
+
+    beforeEach(function () {
+        module(function ($provide) {
+            $provide.value('$window', mockWindow);
+        });
+    });
+
     beforeEach(inject(function (_$log_, _$compile_, _$rootScope_,
                                 FnService, IconService) {
         $log = _$log_;