From e144d3aa49a1e4a3bb487ada9d83a2b4c81e6630 Mon Sep 17 00:00:00 2001
From: Vincent Petry <pvince81@owncloud.com>
Date: Mon, 23 Feb 2015 15:29:25 +0100
Subject: [PATCH] Added unit test for app filter

---
 core/css/apps.css             |   3 +
 settings/js/apps.js           | 122 ++++++++++++++++++----------------
 settings/tests/js/appsSpec.js | 101 ++++++++++++++++++++++++++++
 tests/karma.config.js         |   6 +-
 4 files changed, 175 insertions(+), 57 deletions(-)
 create mode 100644 settings/tests/js/appsSpec.js

diff --git a/core/css/apps.css b/core/css/apps.css
index 08877402a4b..fa30c9bbc83 100644
--- a/core/css/apps.css
+++ b/core/css/apps.css
@@ -484,6 +484,9 @@ button.loading {
 	color: #555;
 	border-top: 1px solid #ddd;
 }
+.section.hidden {
+	display: none !important;
+}
 /* no top border for first settings item */
 #app-content > .section:first-child {
 	border-top: none;
diff --git a/settings/js/apps.js b/settings/js/apps.js
index 6e78ce2a6e8..c15d6a0f74d 100644
--- a/settings/js/apps.js
+++ b/settings/js/apps.js
@@ -334,7 +334,7 @@ OC.Settings.Apps = OC.Settings.Apps || {
 
 	filter: function(query) {
 		query = query.toLowerCase();
-		$('#apps-list').find('.section').hide();
+		$('#apps-list').find('.section').addClass('hidden');
 
 		var apps = _.filter(OC.Settings.Apps.State.apps, function (app) {
 			return app.name.toLowerCase().indexOf(query) !== -1;
@@ -347,77 +347,87 @@ OC.Settings.Apps = OC.Settings.Apps || {
 		apps = _.uniq(apps, function(app){return app.id;});
 
 		_.each(apps, function (app) {
-			$('#app-' + app.id).show();
+			$('#app-' + app.id).removeClass('hidden');
 		});
 
 		$('#searchresults').hide();
-	}
-};
+	},
 
-OC.Settings.Apps.Search = {
-	attach: function (search) {
-		search.setFilter('settings', OC.Settings.Apps.filter);
-	}
-};
+	/**
+	 * Initializes the apps list
+	 */
+	initialize: function($el) {
+		OC.Plugins.register('OCA.Search', OC.Settings.Apps.Search);
+		OC.Settings.Apps.loadCategories();
 
-$(document).ready(function () {
-	OC.Plugins.register('OCA.Search', OC.Settings.Apps.Search);
-	OC.Settings.Apps.loadCategories();
+		$(document).on('click', 'ul#apps-categories li', function () {
+			var categoryId = $(this).data('categoryId');
+			OC.Settings.Apps.loadCategory(categoryId);
+		});
 
-	$(document).on('click', 'ul#apps-categories li', function () {
-		var categoryId = $(this).data('categoryId');
-		OC.Settings.Apps.loadCategory(categoryId);
-	});
+		$(document).on('click', '#apps-list input.enable', function () {
+			var appId = $(this).data('appid');
+			var element = $(this);
+			var active = $(this).data('active');
 
-	$(document).on('click', '#apps-list input.enable', function () {
-		var appId = $(this).data('appid');
-		var element = $(this);
-		var active = $(this).data('active');
+			OC.Settings.Apps.enableApp(appId, active, element);
+		});
 
-		OC.Settings.Apps.enableApp(appId, active, element);
-	});
+		$(document).on('click', '#apps-list input.uninstall', function () {
+			var appId = $(this).data('appid');
+			var element = $(this);
 
-	$(document).on('click', '#apps-list input.uninstall', function () {
-		var appId = $(this).data('appid');
-		var element = $(this);
+			OC.Settings.Apps.uninstallApp(appId, element);
+		});
 
-		OC.Settings.Apps.uninstallApp(appId, element);
-	});
+		$(document).on('click', '#apps-list input.update', function () {
+			var appId = $(this).data('appid');
+			var element = $(this);
 
-	$(document).on('click', '#apps-list input.update', function () {
-		var appId = $(this).data('appid');
-		var element = $(this);
+			OC.Settings.Apps.updateApp(appId, element);
+		});
 
-		OC.Settings.Apps.updateApp(appId, element);
-	});
+		$(document).on('change', '#group_select', function() {
+			var element = $(this).parent().find('input.enable');
+			var groups = $(this).val();
+			if (groups && groups !== '') {
+				groups = groups.split(',');
+			} else {
+				groups = [];
+			}
 
-	$(document).on('change', '#group_select', function() {
-		var element = $(this).parent().find('input.enable');
-		var groups = $(this).val();
-		if (groups && groups !== '') {
-			groups = groups.split(',');
-		} else {
-			groups = [];
-		}
+			var appId = element.data('appid');
+			if (appId) {
+				OC.Settings.Apps.enableApp(appId, false, element, groups);
+				OC.Settings.Apps.State.apps[appId].groups = groups;
+			}
+		});
 
-		var appId = element.data('appid');
-		if (appId) {
-			OC.Settings.Apps.enableApp(appId, false, element, groups);
-			OC.Settings.Apps.State.apps[appId].groups = groups;
-		}
-	});
+		$(document).on('change', ".groups-enable", function() {
+			var $select = $(this).parent().find('#group_select');
+			$select.val('');
 
-	$(document).on('change', ".groups-enable", function() {
-		var $select = $(this).parent().find('#group_select');
-		$select.val('');
+			if (this.checked) {
+				OC.Settings.Apps.setupGroupsSelect($select);
+			} else {
+				$select.select2('destroy');
+			}
 
-		if (this.checked) {
-			OC.Settings.Apps.setupGroupsSelect($select);
-		} else {
-			$select.select2('destroy');
-		}
+			$select.change();
+		});
 
-		$select.change();
-	});
+	}
+};
 
+OC.Settings.Apps.Search = {
+	attach: function (search) {
+		search.setFilter('settings', OC.Settings.Apps.filter);
+	}
+};
+
+$(document).ready(function () {
+	// HACK: FIXME: use plugin approach
+	if (!window.TESTING) {
+		OC.Settings.Apps.initialize($('#apps-list'));
+	}
 });
diff --git a/settings/tests/js/appsSpec.js b/settings/tests/js/appsSpec.js
new file mode 100644
index 00000000000..39329c19246
--- /dev/null
+++ b/settings/tests/js/appsSpec.js
@@ -0,0 +1,101 @@
+/**
+* ownCloud
+*
+* @author Vincent Petry
+* @copyright 2015 Vincent Petry <pvince81@owncloud.com>
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+* License as published by the Free Software Foundation; either
+* version 3 of the License, or any later version.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
+*
+* You should have received a copy of the GNU Affero General Public
+* License along with this library.  If not, see <http://www.gnu.org/licenses/>.
+*
+*/
+
+describe('OC.Settings.Apps tests', function() {
+	var Apps;
+
+	beforeEach(function() {
+		var $el = $('<div id="apps-list"></div>' +
+			'<div id="app-template">' +
+			// dummy template for testing
+			'<div id="app-{{id}}" data-id="{{id}}" class="section">{{name}}</div>' +
+			'</div>'
+		);
+		$('#testArea').append($el);
+
+		Apps = OC.Settings.Apps;
+	});
+	afterEach(function() {
+		Apps.State.apps = null;
+		Apps.State.currentCategory = null;
+	});
+
+	describe('Filtering apps', function() {
+		var oldApps;
+
+		function loadApps(appList) {
+			Apps.State.apps = appList;
+
+			_.each(appList, function(appSpec) {
+				Apps.renderApp(appSpec);
+			});
+		}
+
+		function getResultsFromDom() {
+			var results = [];
+			$('#apps-list .section:not(.hidden)').each(function() {
+				results.push($(this).attr('data-id'));
+			});
+			return results;
+		}
+
+		beforeEach(function() {
+			loadApps([
+				{id: 'appone', name: 'App One', description: 'The first app'},
+				{id: 'apptwo', name: 'App Two', description: 'The second app'},
+				{id: 'appthree', name: 'App Three', description: 'Third app'},
+				{id: 'somestuff', name: 'Some Stuff', description: 'whatever'}
+			]);
+		});
+
+		it('does not filter when no query passed', function() {
+			Apps.filter('');
+			expect(getResultsFromDom().length).toEqual(4);
+		});
+		it('returns no results when query does not match anything', function() {
+			Apps.filter('absurdity');
+			expect(getResultsFromDom().length).toEqual(0);
+		});
+		it('returns relevant results when query matches name', function() {
+			var results;
+			Apps.filter('app');
+			results = getResultsFromDom();
+			expect(results.length).toEqual(3);
+			expect(results[0]).toEqual('appone');
+			expect(results[1]).toEqual('apptwo');
+			expect(results[2]).toEqual('appthree');
+		});
+		it('returns relevant result when query matches name', function() {
+			var results;
+			Apps.filter('TWO');
+			results = getResultsFromDom();
+			expect(results.length).toEqual(1);
+			expect(results[0]).toEqual('apptwo');
+		});
+		it('returns relevant result when query matches description', function() {
+			var results;
+			Apps.filter('ever');
+			results = getResultsFromDom();
+			expect(results.length).toEqual(1);
+			expect(results[0]).toEqual('somestuff');
+		});
+	});
+});
diff --git a/tests/karma.config.js b/tests/karma.config.js
index e4f8b3ea68f..e5febb15aaa 100644
--- a/tests/karma.config.js
+++ b/tests/karma.config.js
@@ -71,9 +71,13 @@ module.exports = function(config) {
 			{
 				name: 'settings',
 				srcFiles: [
+					'settings/js/apps.js',
 					'settings/js/users/deleteHandler.js'
 				],
-				testFiles: ['settings/tests/js/users/deleteHandlerSpec.js']
+				testFiles: [
+					'settings/tests/js/appsSpec.js',
+					'settings/tests/js/users/deleteHandlerSpec.js'
+				]
 			}
 		];
 	}
-- 
GitLab