diff --git a/app/assets/javascripts/app/views/header_view.js b/app/assets/javascripts/app/views/header_view.js index 985c28652c94eaeecd47c8b71a5084189ee404a1..814ef3a879b551a8babbd98e9705be05d0d23530 100644 --- a/app/assets/javascripts/app/views/header_view.js +++ b/app/assets/javascripts/app/views/header_view.js @@ -21,7 +21,7 @@ app.views.Header = app.views.Base.extend({ postRenderTemplate: function(){ new app.views.Notifications({ el: '#notification_dropdown' }); new app.views.NotificationDropdown({ el: '#notification_badge' }); - new app.views.SearchBar({ el: '#search_people_form' }); + new app.views.Search({ el: '#header-search-form' }); }, menuElement: function(){ return this.$("ul.dropdown"); }, diff --git a/app/assets/javascripts/app/views/notifications_dropdown_view.js b/app/assets/javascripts/app/views/notification_dropdown_view.js similarity index 87% rename from app/assets/javascripts/app/views/notifications_dropdown_view.js rename to app/assets/javascripts/app/views/notification_dropdown_view.js index 7273dd906e5088fecd10da9995782e47aec0a68e..a2c7525db3a859ab4d1211c9a477b8ea96515e5a 100644 --- a/app/assets/javascripts/app/views/notifications_dropdown_view.js +++ b/app/assets/javascripts/app/views/notification_dropdown_view.js @@ -13,8 +13,8 @@ app.views.NotificationDropdown = app.views.Base.extend({ this.hasMoreNotifs = true; this.badge = this.$el; this.dropdown = $('#notification_dropdown'); - this.dropdownNotifications = this.dropdown.find(".notifications"); - this.ajaxLoader = this.dropdown.find(".ajax_loader"); + this.dropdownNotifications = this.dropdown.find('.notifications'); + this.ajaxLoader = this.dropdown.find('.ajax_loader'); }, toggleDropdown: function(evt){ @@ -25,15 +25,15 @@ app.views.NotificationDropdown = app.views.Base.extend({ }, dropdownShowing: function(){ - return this.dropdown.css("display") === "block"; + return this.dropdown.css('display') === 'block'; }, showDropdown: function(){ this.resetParams(); this.ajaxLoader.show(); - this.badge.addClass("active"); - this.dropdown.css("display", "block"); - this.dropdownNotifications.addClass("loading"); + this.badge.addClass('active'); + this.dropdown.css('display', 'block'); + this.dropdownNotifications.addClass('loading'); this.getNotifications(); }, @@ -41,8 +41,8 @@ app.views.NotificationDropdown = app.views.Base.extend({ var inDropdown = $(evt.target).parents().is(this.dropdown); var inHovercard = $.contains(app.hovercard.el, evt.target); if(!inDropdown && !inHovercard && this.dropdownShowing()){ - this.badge.removeClass("active"); - this.dropdown.css("display", "none"); + this.badge.removeClass('active'); + this.dropdown.css('display', 'none'); this.dropdownNotifications.perfectScrollbar('destroy'); } }, @@ -77,7 +77,8 @@ app.views.NotificationDropdown = app.views.Base.extend({ $.getJSON(Routes.notifications_path(this.getParams()), function(notifications){ $.each(notifications, function(){ self.notifications.push(this); }); self.hasMoreNotifs = notifications.length >= self.perPage; - self.nextPage = self.nextPage++ || 3; + if(self.nextPage){ self.nextPage++; } + else { self.nextPage = 3; } self.renderNotifications(); }); }, diff --git a/app/assets/javascripts/app/views/searchbar_view.js b/app/assets/javascripts/app/views/search_view.js similarity index 80% rename from app/assets/javascripts/app/views/searchbar_view.js rename to app/assets/javascripts/app/views/search_view.js index 6c16265bfe712cdf9999db043098d8c1944a84f7..3453a969e78fd08eeb2b92f8b4ad000d4bd7e6f7 100644 --- a/app/assets/javascripts/app/views/searchbar_view.js +++ b/app/assets/javascripts/app/views/search_view.js @@ -1,11 +1,10 @@ // @license magnet:?xt=urn:btih:0b31508aeb0634b347b8270c7bee4d411b5d4109&dn=agpl-3.0.txt AGPL-v3-or-Later -app.views.SearchBar = app.views.Base.extend({ +app.views.Search = app.views.Base.extend({ initialize: function(){ - this.searchForm = this.$el; - this.searchFormAction = this.searchForm.attr('action'); - this.searchInput = this.searchForm.find('input[type="search"]'); - this.searchInputName = this.searchForm.find('input[type="search"]').attr('name'); - this.searchInputHandle = this.searchForm.find('input[type="search"]').attr('handle'); + this.searchFormAction = this.$el.attr('action'); + this.searchInput = this.$('input[type="search"]'); + this.searchInputName = this.$('input[type="search"]').attr('name'); + this.searchInputHandle = this.$('input[type="search"]').attr('handle'); this.options = { cacheLength: 15, delay: 800, @@ -39,12 +38,13 @@ app.views.SearchBar = app.views.Base.extend({ formatResult: function(row){ return Handlebars.Utils.escapeExpression(row.name); }, parse: function(data) { + var self = this.context; + var results = data.map(function(person){ - person.name = Handlebars.Utils.escapeExpression(person.name); + person.name = self.formatResult(person); return {data : person, value : person.name}; }); - var self = this.context; results.push({ data: { name: self.searchInput.val(), diff --git a/app/assets/templates/header_tpl.jst.hbs b/app/assets/templates/header_tpl.jst.hbs index 89f81b56370d35c1e0b3f19cd0d798c4316d3d1b..3922d6b5dad61530b03dbec2a3b2bc4506d54cb8 100644 --- a/app/assets/templates/header_tpl.jst.hbs +++ b/app/assets/templates/header_tpl.jst.hbs @@ -87,7 +87,7 @@ <div id="global_search"> - <form id="search_people_form" accept-charset="UTF-8" action="/search" class="search_form" method="get"> + <form id="header-search-form" accept-charset="UTF-8" action="/search" class="search_form" method="get"> <input name="utf8" type="hidden" value="✓"> <input id="q" name="q" placeholder="{{t "header.search"}}" results="5" type="search" autocomplete="off" class="ac_input"> </form> diff --git a/app/views/aspect_memberships/_aspect_membership_dropdown.html.haml b/app/views/aspect_memberships/_aspect_membership_dropdown.haml similarity index 100% rename from app/views/aspect_memberships/_aspect_membership_dropdown.html.haml rename to app/views/aspect_memberships/_aspect_membership_dropdown.haml diff --git a/spec/javascripts/app/views/notification_dropdown_view_spec.js b/spec/javascripts/app/views/notification_dropdown_view_spec.js new file mode 100644 index 0000000000000000000000000000000000000000..f6972c5be91bc87a24d6b681ada2d0ed1cc629f4 --- /dev/null +++ b/spec/javascripts/app/views/notification_dropdown_view_spec.js @@ -0,0 +1,107 @@ +describe('app.views.NotificationDropdown', function() { + beforeEach(function (){ + spec.loadFixture('notifications'); + this.header = new app.views.Header(); + $("header").prepend(this.header.el); + this.header.render(); + this.view = new app.views.NotificationDropdown({el: '#notification_badge'}); + }); + + context('showDropdown', function(){ + it('Calls resetParam()', function(){ + spyOn(this.view, 'resetParams'); + this.view.showDropdown(); + expect(this.view.resetParams).toHaveBeenCalled(); + }); + it('Changes CSS', function(){ + this.view.showDropdown(); + expect($('#notification_dropdown').css('display')).toBe('block'); + }); + it('Calls getNotifications()', function(){ + spyOn(this.view, 'getNotifications'); + this.view.showDropdown(); + expect(this.view.getNotifications).toHaveBeenCalled(); + }); + }); + + context('dropdownScroll', function(){ + it('Calls getNotifications if is at the bottom and has more notifications to load', function(){ + this.view.isBottom = function(){ return true; }; + this.view.hasMoreNotifs = true; + spyOn(this.view, 'getNotifications'); + this.view.dropdownScroll(); + expect(this.view.getNotifications).toHaveBeenCalled(); + }); + + it("Doesn't call getNotifications if is not at the bottom", function(){ + this.view.isBottom = function(){ return false; }; + this.view.hasMoreNotifs = true; + spyOn(this.view, 'getNotifications'); + this.view.dropdownScroll(); + expect(this.view.getNotifications).not.toHaveBeenCalled(); + }); + + it("Doesn't call getNotifications if is not at the bottom", function(){ + this.view.isBottom = function(){ return true; }; + this.view.hasMoreNotifs = false; + spyOn(this.view, 'getNotifications'); + this.view.dropdownScroll(); + expect(this.view.getNotifications).not.toHaveBeenCalled(); + }); + }); + + context('getNotifications', function(){ + it('Has more notifications', function(){ + var response = ['', '', '', '', '']; + spyOn($, 'getJSON').and.callFake(function(url, callback){ callback(response); }); + this.view.getNotifications(); + expect(this.view.hasMoreNotifs).toBe(true); + }); + it('Has no more notifications', function(){ + spyOn($, 'getJSON').and.callFake(function(url, callback){ callback([]); }); + this.view.getNotifications(); + expect(this.view.hasMoreNotifs).toBe(false); + }); + it('Correctly sets the next page', function(){ + spyOn($, 'getJSON').and.callFake(function(url, callback){ callback([]); }); + expect(typeof this.view.nextPage).toBe('undefined'); + this.view.getNotifications(); + expect(this.view.nextPage).toBe(3); + }); + it('Increase the page count', function(){ + var response = ['', '', '', '', '']; + spyOn($, 'getJSON').and.callFake(function(url, callback){ callback(response); }); + this.view.getNotifications(); + expect(this.view.nextPage).toBe(3); + this.view.getNotifications(); + expect(this.view.nextPage).toBe(4); + }); + it('Calls renderNotifications()', function(){ + spyOn($, 'getJSON').and.callFake(function(url, callback){ callback([]); }); + spyOn(this.view, 'renderNotifications'); + this.view.getNotifications(); + expect(this.view.renderNotifications).toHaveBeenCalled(); + }); + it('Adds the notifications to this.notifications', function(){ + var response = ['', '', '', '', '']; + this.view.notifications.length = 0; + spyOn($, 'getJSON').and.callFake(function(url, callback){ callback(response); }); + this.view.getNotifications(); + expect(this.view.notifications).toEqual(response); + }); + }); + + context('renderNotifications', function(){ + it('Removes the previous notifications', function(){ + this.view.dropdownNotifications.append('<div class="media stream_element">Notification</div>'); + expect(this.view.dropdownNotifications.find('.media.stream_element').length).toBe(1); + this.view.renderNotifications(); + expect(this.view.dropdownNotifications.find('.media.stream_element').length).toBe(0); + }); + it('Calls hideAjaxLoader()', function(){ + spyOn(this.view, 'hideAjaxLoader'); + this.view.renderNotifications(); + expect(this.view.hideAjaxLoader).toHaveBeenCalled(); + }); + }); +}); diff --git a/spec/javascripts/app/views/search_view_spec.js b/spec/javascripts/app/views/search_view_spec.js index 3ea52e03a22bc14703bb17e67e32421fa312828a..ca23e6f7cd778b713e39b66a3df0132ca87b85db 100644 --- a/spec/javascripts/app/views/search_view_spec.js +++ b/spec/javascripts/app/views/search_view_spec.js @@ -1,7 +1,7 @@ -describe("app.views.SearchBar", function() { +describe("app.views.Search", function() { beforeEach(function(){ spec.content().html('<form action="#" id="search_people_form"></form>'); - this.view = new app.views.SearchBar({ el: '#search_people_form' }); + this.view = new app.views.Search({ el: '#search_people_form' }); }); describe("parse", function() { it("escapes a persons name", function() {