diff --git a/cms/envs/common.py b/cms/envs/common.py index f1d34953a1..eb7980eabe 100644 --- a/cms/envs/common.py +++ b/cms/envs/common.py @@ -170,6 +170,9 @@ FEATURES = { # Teams feature 'ENABLE_TEAMS': True, + # Teams search feature + 'ENABLE_TEAMS_SEARCH': False, + # Show video bumper in Studio 'ENABLE_VIDEO_BUMPER': False, diff --git a/cms/envs/test.py b/cms/envs/test.py index 16133ac8ef..1539c28fb7 100644 --- a/cms/envs/test.py +++ b/cms/envs/test.py @@ -281,5 +281,8 @@ SEARCH_ENGINE = "search.tests.mock_search_engine.MockSearchEngine" # teams feature FEATURES['ENABLE_TEAMS'] = True +# teams search +FEATURES['ENABLE_TEAMS_SEARCH'] = True + # Dummy secret key for dev/test SECRET_KEY = '85920908f28904ed733fe576320db18cabd7b6cd' diff --git a/common/test/acceptance/tests/lms/test_teams.py b/common/test/acceptance/tests/lms/test_teams.py index 6ba2bf279a..c071613fbd 100644 --- a/common/test/acceptance/tests/lms/test_teams.py +++ b/common/test/acceptance/tests/lms/test_teams.py @@ -10,6 +10,7 @@ import ddt from flaky import flaky from nose.plugins.attrib import attr from uuid import uuid4 +from unittest import skip from ..helpers import EventsTestMixin, UniqueCourseTest from ...fixtures import LMS_BASE_URL @@ -705,6 +706,7 @@ class BrowseTeamsWithinTopicTest(TeamsTabBase): self.browse_teams_page.click_browse_all_teams_link() self.assertTrue(self.topics_page.is_browser_on_page()) + @skip('Disabled until search connectivity issues are resolved, see TNL-3206') def test_search(self): """ Scenario: User should be able to search for a team diff --git a/lms/djangoapps/shoppingcart/tests/test_views.py b/lms/djangoapps/shoppingcart/tests/test_views.py index 75793197fd..76b0b04e7b 100644 --- a/lms/djangoapps/shoppingcart/tests/test_views.py +++ b/lms/djangoapps/shoppingcart/tests/test_views.py @@ -1375,9 +1375,34 @@ class ShoppingCartViewsTests(SharedModuleStoreTestCase, XssTestMixin): self.assertEqual(resp.status_code, 200) self.assertIn('") - elif not settings.FEATURES.get('ENABLE_TEAMS', False): - raise CommandError(u"ENABLE_TEAMS must be enabled to use course team indexing") + elif not settings.FEATURES.get('ENABLE_TEAMS_SEARCH', False): + raise CommandError(u"ENABLE_TEAMS_SEARCH must be enabled to use course team indexing") if options.get('all', False): course_teams = CourseTeam.objects.all() diff --git a/lms/djangoapps/teams/management/commands/tests/test_reindex_course_team.py b/lms/djangoapps/teams/management/commands/tests/test_reindex_course_team.py index 63b7593bcd..885bf48188 100644 --- a/lms/djangoapps/teams/management/commands/tests/test_reindex_course_team.py +++ b/lms/djangoapps/teams/management/commands/tests/test_reindex_course_team.py @@ -39,9 +39,9 @@ class ReindexCourseTeamTest(SharedModuleStoreTestCase): def test_teams_search_flag_disabled_raises_command_error(self): """ Test that raises CommandError for disabled feature flag. """ with mock.patch('django.conf.settings.FEATURES') as features: - features.return_value = {"ENABLE_TEAMS": False} + features.return_value = {"ENABLE_TEAMS_SEARCH": False} with self.assertRaises(SystemExit), nostderr(): - with self.assertRaisesRegexp(CommandError, ".* ENABLE_TEAMS must be enabled .*"): + with self.assertRaisesRegexp(CommandError, ".* ENABLE_TEAMS_SEARCH must be enabled .*"): call_command('reindex_course_team') def test_given_invalid_team_id_raises_command_error(self): diff --git a/lms/djangoapps/teams/search_indexes.py b/lms/djangoapps/teams/search_indexes.py index 7532b48ac6..090f3856ce 100644 --- a/lms/djangoapps/teams/search_indexes.py +++ b/lms/djangoapps/teams/search_indexes.py @@ -1,11 +1,15 @@ """ Search index used to load data into elasticsearch""" +import logging +from requests import ConnectionError + from django.conf import settings from django.db.models.signals import post_save from django.dispatch import receiver from search.search_engine_base import SearchEngine +from .errors import ElasticSearchConnectionError from .serializers import CourseTeamSerializer, CourseTeam @@ -15,7 +19,7 @@ class CourseTeamIndexer(object): """ INDEX_NAME = "course_team_index" DOCUMENT_TYPE_NAME = "course_team" - ENABLE_SEARCH_KEY = "ENABLE_TEAMS" + ENABLE_SEARCH_KEY = "ENABLE_TEAMS_SEARCH" def __init__(self, course_team): self.course_team = course_team @@ -78,7 +82,11 @@ class CourseTeamIndexer(object): Return course team search engine (if feature is enabled). """ if cls.search_is_enabled(): - return SearchEngine.get_search_engine(index=cls.INDEX_NAME) + try: + return SearchEngine.get_search_engine(index=cls.INDEX_NAME) + except ConnectionError as err: + logging.error("Error connecting to elasticsearch: %s", err) + raise ElasticSearchConnectionError @classmethod def search_is_enabled(cls): @@ -93,4 +101,7 @@ def course_team_post_save_callback(**kwargs): """ Reindex object after save. """ - CourseTeamIndexer.index(kwargs['instance']) + try: + CourseTeamIndexer.index(kwargs['instance']) + except ElasticSearchConnectionError: + pass diff --git a/lms/djangoapps/teams/static/teams/js/spec/views/teams_tab_spec.js b/lms/djangoapps/teams/static/teams/js/spec/views/teams_tab_spec.js index 9d7f402335..786cb08b63 100644 --- a/lms/djangoapps/teams/static/teams/js/spec/views/teams_tab_spec.js +++ b/lms/djangoapps/teams/static/teams/js/spec/views/teams_tab_spec.js @@ -134,7 +134,7 @@ define([ )); }; - it('can search teams', function () { + xit('can search teams', function () { var requests = AjaxHelpers.requests(this), teamsTabView = createTeamsTabView(); teamsTabView.browseTopic(TeamSpecHelpers.testTopicID); @@ -154,7 +154,7 @@ define([ expect(teamsTabView.$('.page-description').text()).toBe('Showing results for "foo"'); }); - it('can clear a search', function () { + xit('can clear a search', function () { var requests = AjaxHelpers.requests(this), teamsTabView = createTeamsTabView(); teamsTabView.browseTopic(TeamSpecHelpers.testTopicID); @@ -177,7 +177,7 @@ define([ expect(teamsTabView.$('.page-description').text()).toBe('Test description 1'); }); - it('clears the search when navigating away and then back', function () { + xit('clears the search when navigating away and then back', function () { var requests = AjaxHelpers.requests(this), teamsTabView = createTeamsTabView(); teamsTabView.browseTopic(TeamSpecHelpers.testTopicID); @@ -199,7 +199,7 @@ define([ expect(teamsTabView.$('.page-description').text()).toBe('Test description 1'); }); - it('does not switch to showing results when the search returns an error', function () { + xit('does not switch to showing results when the search returns an error', function () { var requests = AjaxHelpers.requests(this), teamsTabView = createTeamsTabView(); teamsTabView.browseTopic(TeamSpecHelpers.testTopicID); diff --git a/lms/djangoapps/teams/static/teams/js/spec/views/topic_teams_spec.js b/lms/djangoapps/teams/static/teams/js/spec/views/topic_teams_spec.js index a67a5298dc..902fb01208 100644 --- a/lms/djangoapps/teams/static/teams/js/spec/views/topic_teams_spec.js +++ b/lms/djangoapps/teams/static/teams/js/spec/views/topic_teams_spec.js @@ -66,7 +66,7 @@ define([ expect(Backbone.history.navigate.calls[0].args).toContain('browse'); }); - it('gives the search field focus when clicking on the search teams link', function () { + xit('gives the search field focus when clicking on the search teams link', function () { var emptyMembership = TeamSpecHelpers.createMockTeamMemberships([]), teamsView = createTopicTeamsView({ teamMemberships: emptyMembership }); spyOn($.fn, 'focus').andCallThrough(); diff --git a/lms/djangoapps/teams/static/teams/js/views/teams_tab.js b/lms/djangoapps/teams/static/teams/js/views/teams_tab.js index bc7b44155d..ae36b4fd09 100644 --- a/lms/djangoapps/teams/static/teams/js/views/teams_tab.js +++ b/lms/djangoapps/teams/static/teams/js/views/teams_tab.js @@ -303,7 +303,7 @@ viewWithHeader = this.createViewWithHeader({ subject: topic, mainView: teamsView, - headerActionsView: searchFieldView, + headerActionsView: null, // TODO: add back SearchFieldView when search is enabled title: options.title, description: options.description, breadcrumbs: options.breadcrumbs diff --git a/lms/djangoapps/teams/static/teams/js/views/topic_teams.js b/lms/djangoapps/teams/static/teams/js/views/topic_teams.js index b545483d5d..2d23304bd4 100644 --- a/lms/djangoapps/teams/static/teams/js/views/topic_teams.js +++ b/lms/djangoapps/teams/static/teams/js/views/topic_teams.js @@ -57,13 +57,16 @@ }, searchTeams: function (event) { - var searchField = $('.page-header-search .search-field'); + //var searchField = $('.page-header-search .search-field'); event.preventDefault(); - searchField.focus(); - searchField.select(); - $('html, body').animate({ - scrollTop: 0 - }, 500); + //searchField.focus(); + //searchField.select(); + //$('html, body').animate({ + // scrollTop: 0 + //}, 500); + + // TODO! Will navigate to correct place once required functionality is available + Backbone.history.navigate('browse', {trigger: true}); }, showCreateTeamForm: function (event) { diff --git a/lms/djangoapps/teams/views.py b/lms/djangoapps/teams/views.py index 53432643cc..5f5200a5d7 100644 --- a/lms/djangoapps/teams/views.py +++ b/lms/djangoapps/teams/views.py @@ -55,7 +55,7 @@ from .serializers import ( add_team_count ) from .search_indexes import CourseTeamIndexer -from .errors import AlreadyOnTeamInCourse, NotEnrolledInCourseForTeam +from .errors import AlreadyOnTeamInCourse, NotEnrolledInCourseForTeam, ElasticSearchConnectionError TEAM_MEMBERSHIPS_PER_PAGE = 2 TOPICS_PER_PAGE = 12 @@ -351,7 +351,13 @@ class TeamsListView(ExpandableFieldViewMixin, GenericAPIView): return Response(error, status=status.HTTP_400_BAD_REQUEST) result_filter.update({'topic_id': topic_id}) if text_search and CourseTeamIndexer.search_is_enabled(): - search_engine = CourseTeamIndexer.engine() + try: + search_engine = CourseTeamIndexer.engine() + except ElasticSearchConnectionError: + return Response( + build_api_error(ugettext_noop('Error connecting to elasticsearch')), + status=status.HTTP_400_BAD_REQUEST + ) result_filter.update({'course_id': course_id_string}) search_results = search_engine.search( diff --git a/lms/envs/aws.py b/lms/envs/aws.py index d9cf8c9854..aae22b3f82 100644 --- a/lms/envs/aws.py +++ b/lms/envs/aws.py @@ -633,7 +633,7 @@ PDF_RECEIPT_COBRAND_LOGO_HEIGHT_MM = ENV_TOKENS.get( if FEATURES.get('ENABLE_COURSEWARE_SEARCH') or \ FEATURES.get('ENABLE_DASHBOARD_SEARCH') or \ FEATURES.get('ENABLE_COURSE_DISCOVERY') or \ - FEATURES.get('ENABLE_TEAMS'): + FEATURES.get('ENABLE_TEAMS_SEARCH'): # Use ElasticSearch as the search engine herein SEARCH_ENGINE = "search.elastic.ElasticSearchEngine" diff --git a/lms/envs/test.py b/lms/envs/test.py index 1e52d4297c..b26c03b4de 100644 --- a/lms/envs/test.py +++ b/lms/envs/test.py @@ -486,6 +486,9 @@ FEATURES['ENABLE_EDXNOTES'] = True # Enable teams feature for tests. FEATURES['ENABLE_TEAMS'] = True +# Enable teams search for tests. +FEATURES['ENABLE_TEAMS_SEARCH'] = True + # Add milestones to Installed apps for testing INSTALLED_APPS += ('milestones', 'openedx.core.djangoapps.call_stack_manager') diff --git a/lms/templates/navigation.html b/lms/templates/navigation.html index 16ba583f66..48154a5956 100644 --- a/lms/templates/navigation.html +++ b/lms/templates/navigation.html @@ -97,7 +97,7 @@ site_status_msg = get_site_status_msg(course_id) - % if should_display_shopping_cart_func() and not microsite.is_request_in_microsite(): # see shoppingcart.context_processor.user_has_cart_context_processor + % if should_display_shopping_cart_func() and not (course and microsite.is_request_in_microsite()): # see shoppingcart.context_processor.user_has_cart_context_processor