Commit b5d6b210 by Clinton Blackburn

Merge pull request #9681 from edx/release

Release 2015-09-09
parents f5057b84 020e1649
......@@ -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):
......
""" 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')}">
......
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