@@ -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,
|
||||
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1375,9 +1375,34 @@ class ShoppingCartViewsTests(SharedModuleStoreTestCase, XssTestMixin):
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
self.assertIn('<a class="shopping-cart"', resp.content)
|
||||
|
||||
def test_shopping_cart_navigation_link_in_microsite(self):
|
||||
def test_shopping_cart_navigation_link_not_in_microsite_and_not_on_courseware(self):
|
||||
"""
|
||||
Tests shopping cart link is not available in navigation header if request is from a microsite.
|
||||
Tests shopping cart link is available in navigation header if request is not from a microsite
|
||||
and requested page is not courseware too.
|
||||
"""
|
||||
CourseEnrollment.enroll(self.user, self.course_key)
|
||||
self.add_course_to_user_cart(self.testing_course.id)
|
||||
resp = self.client.get(reverse('dashboard'))
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
self.assertIn('<a class="shopping-cart"', resp.content)
|
||||
|
||||
def test_shopping_cart_navigation_link_in_microsite_not_on_courseware(self):
|
||||
"""
|
||||
Tests shopping cart link is available in navigation header if request is from a microsite but requested
|
||||
page is not from courseware.
|
||||
"""
|
||||
CourseEnrollment.enroll(self.user, self.course_key)
|
||||
self.add_course_to_user_cart(self.testing_course.id)
|
||||
with patch('microsite_configuration.microsite.is_request_in_microsite',
|
||||
Mock(return_value=True)):
|
||||
resp = self.client.get(reverse('dashboard'))
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
self.assertIn('<a class="shopping-cart"', resp.content)
|
||||
|
||||
def test_shopping_cart_navigation_link_in_microsite_courseware_page(self):
|
||||
"""
|
||||
Tests shopping cart link is not available in navigation header if request is from a microsite
|
||||
and requested page is from courseware.
|
||||
"""
|
||||
CourseEnrollment.enroll(self.user, self.course_key)
|
||||
self.add_course_to_user_cart(self.testing_course.id)
|
||||
|
||||
@@ -16,6 +16,11 @@ class AlreadyOnTeamInCourse(TeamAPIRequestError):
|
||||
pass
|
||||
|
||||
|
||||
class ElasticSearchConnectionError(TeamAPIRequestError):
|
||||
"""System was unable to connect to the configured elasticsearch instance"""
|
||||
pass
|
||||
|
||||
|
||||
class ImmutableMembershipFieldException(Exception):
|
||||
"""An attempt was made to change an immutable field on a CourseTeamMembership model"""
|
||||
pass
|
||||
|
||||
@@ -53,8 +53,8 @@ class Command(BaseCommand):
|
||||
|
||||
if len(args) == 0 and not options.get('all', False):
|
||||
raise CommandError(u"reindex_course_team requires one or more arguments: <course_team_id>")
|
||||
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()
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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')
|
||||
|
||||
|
||||
@@ -97,7 +97,7 @@ site_status_msg = get_site_status_msg(course_id)
|
||||
</ul>
|
||||
</li>
|
||||
</ol>
|
||||
% 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
|
||||
<ol class="user">
|
||||
<li class="primary">
|
||||
<a class="shopping-cart" href="${reverse('shoppingcart.views.show_cart')}">
|
||||
|
||||
Reference in New Issue
Block a user