Commit 4234ff59 by Bill DeRusha

Merge pull request #9707 from edx/bderusha/edx-search-config

Add edx-search configuration to lms
parents 60e4a9f3 eec2bed0
...@@ -170,9 +170,6 @@ FEATURES = { ...@@ -170,9 +170,6 @@ FEATURES = {
# Teams feature # Teams feature
'ENABLE_TEAMS': True, 'ENABLE_TEAMS': True,
# Teams search feature
'ENABLE_TEAMS_SEARCH': False,
# Show video bumper in Studio # Show video bumper in Studio
'ENABLE_VIDEO_BUMPER': False, 'ENABLE_VIDEO_BUMPER': False,
......
...@@ -281,8 +281,5 @@ SEARCH_ENGINE = "search.tests.mock_search_engine.MockSearchEngine" ...@@ -281,8 +281,5 @@ SEARCH_ENGINE = "search.tests.mock_search_engine.MockSearchEngine"
# teams feature # teams feature
FEATURES['ENABLE_TEAMS'] = True FEATURES['ENABLE_TEAMS'] = True
# teams search
FEATURES['ENABLE_TEAMS_SEARCH'] = True
# Dummy secret key for dev/test # Dummy secret key for dev/test
SECRET_KEY = '85920908f28904ed733fe576320db18cabd7b6cd' SECRET_KEY = '85920908f28904ed733fe576320db18cabd7b6cd'
...@@ -783,7 +783,7 @@ class BrowseTeamsWithinTopicTest(TeamsTabBase): ...@@ -783,7 +783,7 @@ class BrowseTeamsWithinTopicTest(TeamsTabBase):
self.browse_teams_page.click_browse_all_teams_link() self.browse_teams_page.click_browse_all_teams_link()
self.assertTrue(self.topics_page.is_browser_on_page()) self.assertTrue(self.topics_page.is_browser_on_page())
@skip('Disabled until search connectivity issues are resolved, see TNL-3206') @skip("Skip until TNL-3198 (searching teams makes two AJAX requests) is resolved")
def test_search(self): def test_search(self):
""" """
Scenario: User should be able to search for a team Scenario: User should be able to search for a team
......
...@@ -16,11 +16,6 @@ class AlreadyOnTeamInCourse(TeamAPIRequestError): ...@@ -16,11 +16,6 @@ class AlreadyOnTeamInCourse(TeamAPIRequestError):
pass pass
class ElasticSearchConnectionError(TeamAPIRequestError):
"""System was unable to connect to the configured elasticsearch instance"""
pass
class ImmutableMembershipFieldException(Exception): class ImmutableMembershipFieldException(Exception):
"""An attempt was made to change an immutable field on a CourseTeamMembership model""" """An attempt was made to change an immutable field on a CourseTeamMembership model"""
pass pass
...@@ -53,8 +53,8 @@ class Command(BaseCommand): ...@@ -53,8 +53,8 @@ class Command(BaseCommand):
if len(args) == 0 and not options.get('all', False): if len(args) == 0 and not options.get('all', False):
raise CommandError(u"reindex_course_team requires one or more arguments: <course_team_id>") raise CommandError(u"reindex_course_team requires one or more arguments: <course_team_id>")
elif not settings.FEATURES.get('ENABLE_TEAMS_SEARCH', False): elif not settings.FEATURES.get('ENABLE_TEAMS', False):
raise CommandError(u"ENABLE_TEAMS_SEARCH must be enabled to use course team indexing") raise CommandError(u"ENABLE_TEAMS must be enabled to use course team indexing")
if options.get('all', False): if options.get('all', False):
course_teams = CourseTeam.objects.all() course_teams = CourseTeam.objects.all()
......
...@@ -39,9 +39,9 @@ class ReindexCourseTeamTest(SharedModuleStoreTestCase): ...@@ -39,9 +39,9 @@ class ReindexCourseTeamTest(SharedModuleStoreTestCase):
def test_teams_search_flag_disabled_raises_command_error(self): def test_teams_search_flag_disabled_raises_command_error(self):
""" Test that raises CommandError for disabled feature flag. """ """ Test that raises CommandError for disabled feature flag. """
with mock.patch('django.conf.settings.FEATURES') as features: with mock.patch('django.conf.settings.FEATURES') as features:
features.return_value = {"ENABLE_TEAMS_SEARCH": False} features.return_value = {"ENABLE_TEAMS": False}
with self.assertRaises(SystemExit), nostderr(): with self.assertRaises(SystemExit), nostderr():
with self.assertRaisesRegexp(CommandError, ".* ENABLE_TEAMS_SEARCH must be enabled .*"): with self.assertRaisesRegexp(CommandError, ".* ENABLE_TEAMS must be enabled .*"):
call_command('reindex_course_team') call_command('reindex_course_team')
def test_given_invalid_team_id_raises_command_error(self): def test_given_invalid_team_id_raises_command_error(self):
......
""" Search index used to load data into elasticsearch""" """ Search index used to load data into elasticsearch"""
import logging
from requests import ConnectionError
from django.conf import settings from django.conf import settings
from django.db.models.signals import post_delete, post_save from django.db.models.signals import post_delete, post_save
from django.dispatch import receiver from django.dispatch import receiver
...@@ -11,7 +8,6 @@ from functools import wraps ...@@ -11,7 +8,6 @@ from functools import wraps
from search.search_engine_base import SearchEngine from search.search_engine_base import SearchEngine
from .errors import ElasticSearchConnectionError
from .serializers import CourseTeamSerializer, CourseTeam from .serializers import CourseTeamSerializer, CourseTeam
...@@ -34,7 +30,7 @@ class CourseTeamIndexer(object): ...@@ -34,7 +30,7 @@ class CourseTeamIndexer(object):
""" """
INDEX_NAME = "course_team_index" INDEX_NAME = "course_team_index"
DOCUMENT_TYPE_NAME = "course_team" DOCUMENT_TYPE_NAME = "course_team"
ENABLE_SEARCH_KEY = "ENABLE_TEAMS_SEARCH" ENABLE_SEARCH_KEY = "ENABLE_TEAMS"
def __init__(self, course_team): def __init__(self, course_team):
self.course_team = course_team self.course_team = course_team
...@@ -108,11 +104,7 @@ class CourseTeamIndexer(object): ...@@ -108,11 +104,7 @@ class CourseTeamIndexer(object):
Return course team search engine (if feature is enabled). Return course team search engine (if feature is enabled).
""" """
if cls.search_is_enabled(): if cls.search_is_enabled():
try: return SearchEngine.get_search_engine(index=cls.INDEX_NAME)
return SearchEngine.get_search_engine(index=cls.INDEX_NAME)
except ConnectionError as err:
logging.error("Error connecting to elasticsearch: %s", err)
raise ElasticSearchConnectionError
@classmethod @classmethod
def search_is_enabled(cls): def search_is_enabled(cls):
...@@ -127,10 +119,7 @@ def course_team_post_save_callback(**kwargs): ...@@ -127,10 +119,7 @@ def course_team_post_save_callback(**kwargs):
""" """
Reindex object after save. Reindex object after save.
""" """
try: CourseTeamIndexer.index(kwargs['instance'])
CourseTeamIndexer.index(kwargs['instance'])
except ElasticSearchConnectionError:
pass
@receiver(post_delete, sender=CourseTeam, dispatch_uid='teams.signals.course_team_post_delete_callback') @receiver(post_delete, sender=CourseTeam, dispatch_uid='teams.signals.course_team_post_delete_callback')
......
...@@ -9,7 +9,7 @@ define([ ...@@ -9,7 +9,7 @@ define([
], function ($, Backbone, Logger, AjaxHelpers, SpecHelpers, TeamsTabView, TeamSpecHelpers) { ], function ($, Backbone, Logger, AjaxHelpers, SpecHelpers, TeamsTabView, TeamSpecHelpers) {
'use strict'; 'use strict';
describe('TeamsTab', function () { describe('TeamsTab', function() {
var expectError = function (teamsTabView, text) { var expectError = function (teamsTabView, text) {
expect(teamsTabView.$('.warning').text()).toContain(text); expect(teamsTabView.$('.warning').text()).toContain(text);
}; };
...@@ -19,19 +19,12 @@ define([ ...@@ -19,19 +19,12 @@ define([
}; };
var createTeamsTabView = function(options) { var createTeamsTabView = function(options) {
var defaultTopics = { var teamsTabView = new TeamsTabView(
count: 5, {
num_pages: 1, el: $('.teams-content'),
current_page: 1, context: TeamSpecHelpers.createMockContext(options)
start: 0, }
results: TeamSpecHelpers.createMockTopicData(1, 5) );
},
teamsTabView = new TeamsTabView(
{
el: $('.teams-content'),
context: TeamSpecHelpers.createMockContext(options)
}
);
teamsTabView.start(); teamsTabView.start();
return teamsTabView; return teamsTabView;
}; };
...@@ -175,7 +168,7 @@ define([ ...@@ -175,7 +168,7 @@ define([
}, function (url, expectedEvent) { }, function (url, expectedEvent) {
var requests = AjaxHelpers.requests(this), var requests = AjaxHelpers.requests(this),
teamsTabView = createTeamsTabView({ teamsTabView = createTeamsTabView({
userInfo: TeamSpecHelpers.createMockUserInfo({ staff: true }) userInfo: TeamSpecHelpers.createMockUserInfo({staff: true})
}); });
teamsTabView.router.navigate(url, {trigger: true}); teamsTabView.router.navigate(url, {trigger: true});
if (requests.length) { if (requests.length) {
...@@ -188,7 +181,7 @@ define([ ...@@ -188,7 +181,7 @@ define([
describe('Discussion privileges', function () { describe('Discussion privileges', function () {
it('allows privileged access to any team', function () { it('allows privileged access to any team', function () {
var teamsTabView = createTeamsTabView({ var teamsTabView = createTeamsTabView({
userInfo: TeamSpecHelpers.createMockUserInfo({ privileged: true }) userInfo: TeamSpecHelpers.createMockUserInfo({privileged: true})
}); });
// Note: using `undefined` here to ensure that we // Note: using `undefined` here to ensure that we
// don't even look at the team when the user is // don't even look at the team when the user is
...@@ -216,10 +209,10 @@ define([ ...@@ -216,10 +209,10 @@ define([
it('does not allow access if the user is neither privileged nor a team member', function () { it('does not allow access if the user is neither privileged nor a team member', function () {
var teamsTabView = createTeamsTabView({ var teamsTabView = createTeamsTabView({
userInfo: TeamSpecHelpers.createMockUserInfo({ privileged: false, staff: true }) userInfo: TeamSpecHelpers.createMockUserInfo({privileged: false, staff: true})
}); });
expect(teamsTabView.readOnlyDiscussion({ expect(teamsTabView.readOnlyDiscussion({
attributes: { membership: [] } attributes: {membership: []}
})).toBe(true); })).toBe(true);
}); });
}); });
...@@ -241,7 +234,7 @@ define([ ...@@ -241,7 +234,7 @@ define([
)); ));
}; };
xit('can search teams', function () { it('can search teams', function () {
var requests = AjaxHelpers.requests(this), var requests = AjaxHelpers.requests(this),
teamsTabView = createTeamsTabView(); teamsTabView = createTeamsTabView();
teamsTabView.browseTopic(TeamSpecHelpers.testTopicID); teamsTabView.browseTopic(TeamSpecHelpers.testTopicID);
...@@ -261,7 +254,7 @@ define([ ...@@ -261,7 +254,7 @@ define([
expect(teamsTabView.$('.page-description').text()).toBe('Showing results for "foo"'); expect(teamsTabView.$('.page-description').text()).toBe('Showing results for "foo"');
}); });
xit('can clear a search', function () { it('can clear a search', function () {
var requests = AjaxHelpers.requests(this), var requests = AjaxHelpers.requests(this),
teamsTabView = createTeamsTabView(); teamsTabView = createTeamsTabView();
teamsTabView.browseTopic(TeamSpecHelpers.testTopicID); teamsTabView.browseTopic(TeamSpecHelpers.testTopicID);
...@@ -290,29 +283,7 @@ define([ ...@@ -290,29 +283,7 @@ define([
expect(teamsTabView.$('.page-description').text()).toBe('Test description 1'); expect(teamsTabView.$('.page-description').text()).toBe('Test description 1');
}); });
xit('clears the search when navigating away and then back', function () { it('does not switch to showing results when the search returns an error', function () {
var requests = AjaxHelpers.requests(this),
teamsTabView = createTeamsTabView();
teamsTabView.browseTopic(TeamSpecHelpers.testTopicID);
AjaxHelpers.respondWithJson(requests, {});
// Perform a search
teamsTabView.$('.search-field').val('foo');
teamsTabView.$('.action-search').click();
AjaxHelpers.respondWithJson(requests, {});
// Navigate back to the teams list
teamsTabView.$('.breadcrumbs a').last().click();
verifyTeamsRequest(removeTeamEvents(requests), {
order_by: 'last_activity_at',
text_search: ''
});
AjaxHelpers.respondWithJson(requests, {});
expect(teamsTabView.$('.page-title').text()).toBe('Test Topic 1');
expect(teamsTabView.$('.page-description').text()).toBe('Test description 1');
});
xit('does not switch to showing results when the search returns an error', function () {
var requests = AjaxHelpers.requests(this), var requests = AjaxHelpers.requests(this),
teamsTabView = createTeamsTabView(); teamsTabView = createTeamsTabView();
teamsTabView.browseTopic(TeamSpecHelpers.testTopicID); teamsTabView.browseTopic(TeamSpecHelpers.testTopicID);
......
...@@ -66,7 +66,7 @@ define([ ...@@ -66,7 +66,7 @@ define([
expect(Backbone.history.navigate.calls[0].args).toContain('browse'); expect(Backbone.history.navigate.calls[0].args).toContain('browse');
}); });
xit('gives the search field focus when clicking on the search teams link', function () { it('gives the search field focus when clicking on the search teams link', function () {
var emptyMembership = TeamSpecHelpers.createMockTeamMemberships([]), var emptyMembership = TeamSpecHelpers.createMockTeamMemberships([]),
teamsView = createTopicTeamsView({ teamMemberships: emptyMembership }); teamsView = createTopicTeamsView({ teamMemberships: emptyMembership });
spyOn($.fn, 'focus').andCallThrough(); spyOn($.fn, 'focus').andCallThrough();
......
...@@ -365,7 +365,7 @@ ...@@ -365,7 +365,7 @@
viewWithHeader = this.createViewWithHeader({ viewWithHeader = this.createViewWithHeader({
subject: topic, subject: topic,
mainView: teamsView, mainView: teamsView,
headerActionsView: null, // TODO: add back SearchFieldView when search is enabled headerActionsView: searchFieldView,
title: options.title, title: options.title,
description: options.description, description: options.description,
breadcrumbs: this.createBreadcrumbs() breadcrumbs: this.createBreadcrumbs()
......
...@@ -57,16 +57,13 @@ ...@@ -57,16 +57,13 @@
}, },
searchTeams: function (event) { searchTeams: function (event) {
//var searchField = $('.page-header-search .search-field'); var searchField = $('.page-header-search .search-field');
event.preventDefault(); event.preventDefault();
//searchField.focus(); searchField.focus();
//searchField.select(); searchField.select();
//$('html, body').animate({ $('html, body').animate({
// scrollTop: 0 scrollTop: 0
//}, 500); }, 500);
// TODO! Will navigate to correct place once required functionality is available
Backbone.history.navigate('browse', {trigger: true});
}, },
showCreateTeamForm: function (event) { showCreateTeamForm: function (event) {
......
...@@ -58,7 +58,7 @@ from .serializers import ( ...@@ -58,7 +58,7 @@ from .serializers import (
add_team_count add_team_count
) )
from .search_indexes import CourseTeamIndexer from .search_indexes import CourseTeamIndexer
from .errors import AlreadyOnTeamInCourse, NotEnrolledInCourseForTeam, ElasticSearchConnectionError from .errors import AlreadyOnTeamInCourse, NotEnrolledInCourseForTeam
TEAM_MEMBERSHIPS_PER_PAGE = 2 TEAM_MEMBERSHIPS_PER_PAGE = 2
TOPICS_PER_PAGE = 12 TOPICS_PER_PAGE = 12
...@@ -366,13 +366,7 @@ class TeamsListView(ExpandableFieldViewMixin, GenericAPIView): ...@@ -366,13 +366,7 @@ class TeamsListView(ExpandableFieldViewMixin, GenericAPIView):
return Response(error, status=status.HTTP_400_BAD_REQUEST) return Response(error, status=status.HTTP_400_BAD_REQUEST)
result_filter.update({'topic_id': topic_id}) result_filter.update({'topic_id': topic_id})
if text_search and CourseTeamIndexer.search_is_enabled(): if text_search and CourseTeamIndexer.search_is_enabled():
try: search_engine = CourseTeamIndexer.engine()
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}) result_filter.update({'course_id': course_id_string})
search_results = search_engine.search( search_results = search_engine.search(
......
...@@ -633,10 +633,12 @@ PDF_RECEIPT_COBRAND_LOGO_HEIGHT_MM = ENV_TOKENS.get( ...@@ -633,10 +633,12 @@ PDF_RECEIPT_COBRAND_LOGO_HEIGHT_MM = ENV_TOKENS.get(
if FEATURES.get('ENABLE_COURSEWARE_SEARCH') or \ if FEATURES.get('ENABLE_COURSEWARE_SEARCH') or \
FEATURES.get('ENABLE_DASHBOARD_SEARCH') or \ FEATURES.get('ENABLE_DASHBOARD_SEARCH') or \
FEATURES.get('ENABLE_COURSE_DISCOVERY') or \ FEATURES.get('ENABLE_COURSE_DISCOVERY') or \
FEATURES.get('ENABLE_TEAMS_SEARCH'): FEATURES.get('ENABLE_TEAMS'):
# Use ElasticSearch as the search engine herein # Use ElasticSearch as the search engine herein
SEARCH_ENGINE = "search.elastic.ElasticSearchEngine" SEARCH_ENGINE = "search.elastic.ElasticSearchEngine"
ELASTIC_SEARCH_CONFIG = ENV_TOKENS.get('ELASTIC_SEARCH_CONFIG', [{}])
# Facebook app # Facebook app
FACEBOOK_API_VERSION = AUTH_TOKENS.get("FACEBOOK_API_VERSION") FACEBOOK_API_VERSION = AUTH_TOKENS.get("FACEBOOK_API_VERSION")
FACEBOOK_APP_SECRET = AUTH_TOKENS.get("FACEBOOK_APP_SECRET") FACEBOOK_APP_SECRET = AUTH_TOKENS.get("FACEBOOK_APP_SECRET")
......
...@@ -486,9 +486,6 @@ FEATURES['ENABLE_EDXNOTES'] = True ...@@ -486,9 +486,6 @@ FEATURES['ENABLE_EDXNOTES'] = True
# Enable teams feature for tests. # Enable teams feature for tests.
FEATURES['ENABLE_TEAMS'] = True FEATURES['ENABLE_TEAMS'] = True
# Enable teams search for tests.
FEATURES['ENABLE_TEAMS_SEARCH'] = True
# Add milestones to Installed apps for testing # Add milestones to Installed apps for testing
INSTALLED_APPS += ('milestones', 'openedx.core.djangoapps.call_stack_manager') INSTALLED_APPS += ('milestones', 'openedx.core.djangoapps.call_stack_manager')
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment