text: define([
      'jquery',
      'backbone',
      'logger',
      'edx-ui-toolkit/js/utils/spec-helpers/ajax-helpers',
      'common/js/spec_helpers/page_helpers',
      'common/js/spec_helpers/template_helpers',
      'js/search/base/models/search_result',
      'js/search/base/collections/search_collection',
      'js/search/base/routers/search_router',
      'js/search/course/views/search_item_view',
      'js/search/dashboard/views/search_item_view',
      'js/search/course/views/search_form',
      'js/search/dashboard/views/search_form',
      'js/search/course/views/search_results_view',
      'js/search/dashboard/views/search_results_view',
      'js/search/course/course_search_factory',
      'js/search/dashboard/dashboard_search_factory'
  ], function(
      $,
      Backbone,
      Logger,
      AjaxHelpers,
      PageHelpers,
      TemplateHelpers,
      SearchResult,
      SearchCollection,
      SearchRouter,
      CourseSearchItemView,
      DashSearchItemView,
      CourseSearchForm,
      DashSearchForm,
      CourseSearchResultsView,
      DashSearchResultsView,
      CourseSearchFactory,
      DashboardSearchFactory
  ) {
      'use strict';
  
      describe('Search', function() {
          beforeEach(function() {
              PageHelpers.preventBackboneChangingUrl();
          });
  
          describe('SearchResult', function() {
              beforeEach(function() {
                  this.result = new SearchResult();
              });
  
              it('has properties', function() {
                  expect(this.result.get('location')).toBeDefined();
                  expect(this.result.get('content_type')).toBeDefined();
                  expect(this.result.get('excerpt')).toBeDefined();
                  expect(this.result.get('url')).toBeDefined();
              });
          });
  
  
          describe('SearchCollection', function() {
              beforeEach(function() {
                  this.collection = new SearchCollection();
  
                  this.onSearch = jasmine.createSpy('onSearch');
                  this.collection.on('search', this.onSearch);
  
                  this.onNext = jasmine.createSpy('onNext');
                  this.collection.on('next', this.onNext);
  
                  this.onError = jasmine.createSpy('onError');
                  this.collection.on('error', this.onError);
              });
  
              it('sends a request without a course ID', function() {
                  var collection = new SearchCollection([]);
                  spyOn($, 'ajax');
                  collection.performSearch('search string');
                  expect($.ajax.calls.mostRecent().args[0].url).toEqual('/search/');
              });
  
              it('sends a request with course ID', function() {
                  var collection = new SearchCollection([], {courseId: 'edx101'});
                  spyOn($, 'ajax');
                  collection.performSearch('search string');
                  expect($.ajax.calls.mostRecent().args[0].url).toEqual('/search/edx101');
              });
  
              it('sends a request and parses the json result', function() {
                  var requests = AjaxHelpers.requests(this);
                  this.collection.performSearch('search string');
                  var response = {
                      total: 2,
                      access_denied_count: 1,
                      results: [{
                          data: {
                              location: ['section', 'subsection', 'unit'],
                              url: '/some/url/to/content',
                              content_type: 'text',
                              excerpt: 'this is a short excerpt'
                          }
                      }]
                  };
                  AjaxHelpers.respondWithJson(requests, response);
  
                  expect(this.onSearch).toHaveBeenCalled();
                  expect(this.collection.totalCount).toEqual(1);
                  expect(this.collection.latestModelsCount).toEqual(1);
                  expect(this.collection.accessDeniedCount).toEqual(1);
                  expect(this.collection.page).toEqual(0);
                  expect(this.collection.first().attributes).toEqual(response.results[0].data);
              });
  
              it('handles errors', function() {
                  var requests = AjaxHelpers.requests(this);
                  this.collection.performSearch('search string');
                  AjaxHelpers.respondWithError(requests, 500);
                  expect(this.onSearch).not.toHaveBeenCalled();
                  expect(this.onError).toHaveBeenCalled();
              });
  
              it('loads next page', function() {
                  var requests = AjaxHelpers.requests(this);
                  var response = {total: 35, results: []};
                  this.collection.loadNextPage();
                  AjaxHelpers.respondWithJson(requests, response);
                  expect(this.onNext).toHaveBeenCalled();
                  expect(this.onError).not.toHaveBeenCalled();
              });
  
              it('sends correct paging parameters', function() {
                  var requests = AjaxHelpers.requests(this);
                  var searchString = 'search string';
                  var response = {total: 52, results: []};
                  this.collection.performSearch(searchString);
                  AjaxHelpers.respondWithJson(requests, response);
                  this.collection.loadNextPage();
                  AjaxHelpers.respondWithJson(requests, response);
                  spyOn($, 'ajax');
                  this.collection.loadNextPage();
                  expect($.ajax.calls.mostRecent().args[0].url).toEqual(this.collection.url);
                  expect($.ajax.calls.mostRecent().args[0].data.search_string).toEqual(searchString);
                  expect($.ajax.calls.mostRecent().args[0].data.page_size).toEqual(this.collection.pageSize);
                  expect($.ajax.calls.mostRecent().args[0].data.page_index).toEqual(2);
              });
  
              it('has next page', function() {
                  var requests = AjaxHelpers.requests(this);
                  var response = {total: 35, access_denied_count: 5, results: []};
                  this.collection.performSearch('search string');
                  AjaxHelpers.respondWithJson(requests, response);
                  expect(this.collection.hasNextPage()).toEqual(true);
                  this.collection.loadNextPage();
                  AjaxHelpers.respondWithJson(requests, response);
                  expect(this.collection.hasNextPage()).toEqual(false);
              });
  
              it('aborts any previous request', function() {
                  var requests = AjaxHelpers.requests(this);
                  var response = {total: 35, results: []};
  
                  this.collection.performSearch('old search');
                  this.collection.performSearch('new search');
                  AjaxHelpers.skipResetRequest(requests);
                  AjaxHelpers.respondWithJson(requests, response);
                  expect(this.onSearch.calls.count()).toEqual(1);
  
                  this.collection.performSearch('old search');
                  this.collection.cancelSearch();
                  AjaxHelpers.skipResetRequest(requests);
                  expect(this.onSearch.calls.count()).toEqual(1);
  
                  this.collection.loadNextPage();
                  this.collection.loadNextPage();
                  AjaxHelpers.skipResetRequest(requests);
                  AjaxHelpers.respondWithJson(requests, response);
                  expect(this.onNext.calls.count()).toEqual(1);
              });
  
              describe('reset state', function() {
                  beforeEach(function() {
                      this.collection.page = 2;
                      this.collection.totalCount = 35;
                      this.collection.latestModelsCount = 5;
                  });
  
                  it('resets state when performing new search', function() {
                      this.collection.performSearch('search string');
                      expect(this.collection.models.length).toEqual(0);
                      expect(this.collection.page).toEqual(0);
                      expect(this.collection.totalCount).toEqual(0);
                      expect(this.collection.latestModelsCount).toEqual(0);
                  });
  
                  it('resets state when canceling a search', function() {
                      this.collection.cancelSearch();
                      expect(this.collection.models.length).toEqual(0);
                      expect(this.collection.page).toEqual(0);
                      expect(this.collection.totalCount).toEqual(0);
                      expect(this.collection.latestModelsCount).toEqual(0);
                  });
              });
          });
  
  
          describe('SearchRouter', function() {
              beforeEach(function() {
                  this.router = new SearchRouter();
                  this.onSearch = jasmine.createSpy('onSearch');
                  this.router.on('search', this.onSearch);
              });
  
              it('has a search route', function() {
                  expect(this.router.routes['search/:query']).toEqual('search');
              });
  
              it('triggers a search event', function() {
                  var query = 'mercury';
                  this.router.search(query);
                  expect(this.onSearch).toHaveBeenCalledWith(query);
              });
          });
  
  
          describe('SearchItemView', function() {
              function beforeEachHelper(SearchItemView) {
                  TemplateHelpers.installTemplates([
                      'templates/search/course_search_item',
                      'templates/search/dashboard_search_item'
                  ]);
  
                  this.model = new SearchResult({
                      location: ['section', 'subsection', 'unit'],
                      content_type: 'Video',
                      course_name: 'Course Name',
                      excerpt: 'A short excerpt.',
                      url: 'path/to/content'
                  });
  
                  this.seqModel = new SearchResult({
                      location: ['section', 'subsection'],
                      content_type: 'Sequence',
                      course_name: 'Course Name',
                      excerpt: 'A short excerpt.',
                      url: 'path/to/content'
                  });
  
                  this.item = new SearchItemView({model: this.model});
                  this.item.render();
                  this.seqItem = new SearchItemView({model: this.seqModel});
                  this.seqItem.render();
              }
  
              function rendersItem() {
                  expect(this.item.$el).toHaveAttr('role', 'region');
                  expect(this.item.$el).toHaveAttr('aria-label', 'search result');
                  expect(this.item.$el).toContainElement('a[href="' + this.model.get('url') + '"]');
                  expect(this.item.$el.find('.result-type')).toContainHtml(this.model.get('content_type'));
                  expect(this.item.$el.find('.result-excerpt')).toContainHtml(this.model.get('excerpt'));
                  expect(this.item.$el.find('.result-location')).toContainHtml('section ▸ subsection ▸ unit');
              }
  
              function rendersSequentialItem() {
                  expect(this.seqItem.$el).toHaveAttr('role', 'region');
                  expect(this.seqItem.$el).toHaveAttr('aria-label', 'search result');
                  expect(this.seqItem.$el).toContainElement('a[href="' + this.seqModel.get('url') + '"]');
                  expect(this.seqItem.$el.find('.result-type')).toBeEmpty();
                  expect(this.seqItem.$el.find('.result-excerpt')).toBeEmpty();
                  expect(this.seqItem.$el.find('.result-location')).toContainHtml('section ▸ subsection');
              }
  
              function logsSearchItemViewEvent() {
                  this.model.collection = new SearchCollection([this.model], {course_id: 'edx101'});
                  this.item.render();
                  // Mock the redirect call
                  spyOn(this.item, 'redirect').and.callFake(function() {});
                  spyOn(Logger, 'log').and.returnValue($.Deferred().resolve());
                  this.item.$el.find('a').trigger('click');
                  expect(this.item.redirect).toHaveBeenCalled();
                  this.item.$el.trigger('click');
                  expect(this.item.redirect).toHaveBeenCalled();
              }
  
              describe('CourseSearchItemView', function() {
                  beforeEach(function() {
                      beforeEachHelper.call(this, CourseSearchItemView);
                  });
                  it('renders items correctly', rendersItem);
                  it('renders Sequence items correctly', rendersSequentialItem);
                  it('logs view event', logsSearchItemViewEvent);
              });
  
              describe('DashSearchItemView', function() {
                  beforeEach(function() {
                      beforeEachHelper.call(this, DashSearchItemView);
                  });
                  it('renders items correctly', rendersItem);
                  it('renders Sequence items correctly', rendersSequentialItem);
                  it('displays course name in breadcrumbs', function() {
                      expect(this.seqItem.$el.find('.result-course-name')).toContainHtml(this.model.get('course_name'));
                  });
                  it('logs view event', logsSearchItemViewEvent);
              });
          });
  
  
          describe('SearchForm', function() {
              function trimsInputString() {
                  var term = '    search string  ';
                  $('.search-field').val(term);
                  $('form').trigger('submit');
                  expect(this.onSearch).toHaveBeenCalledWith($.trim(term));
              }
  
              function doesSearch() {
                  var term = '  search string  ';
                  $('.search-field').val(term);
                  this.form.doSearch(term);
                  expect(this.onSearch).toHaveBeenCalledWith($.trim(term));
                  expect($('.search-field').val()).toEqual(term);
                  expect($('.search-field')).toHaveClass('is-active');
                  expect($('.search-button')).toBeHidden();
                  expect($('.cancel-button')).toBeVisible();
              }
  
              function triggersSearchEvent() {
                  var term = 'search string';
                  $('.search-field').val(term);
                  $('form').trigger('submit');
                  expect(this.onSearch).toHaveBeenCalledWith(term);
                  expect($('.search-field')).toHaveClass('is-active');
                  expect($('.search-button')).toBeHidden();
                  expect($('.cancel-button')).toBeVisible();
              }
  
              function clearsSearchOnCancel() {
                  $('.search-field').val('search string');
                  $('.search-button').trigger('click');
                  $('.cancel-button').trigger('click');
                  expect($('.search-field')).not.toHaveClass('is-active');
                  expect($('.search-button')).toBeVisible();
                  expect($('.cancel-button')).toBeHidden();
                  expect($('.search-field')).toHaveValue('');
              }
  
              function clearsSearchOnEmpty() {
                  $('.search-field').val('');
                  $('form').trigger('submit');
                  expect(this.onClear).toHaveBeenCalled();
                  expect($('.search-field')).not.toHaveClass('is-active');
                  expect($('.cancel-button')).toBeHidden();
                  expect($('.search-button')).toBeVisible();
              }
  
              describe('CourseSearchForm', function() {
                  beforeEach(function() {
                      loadFixtures('js/fixtures/search/course_search_form.html');
                      this.form = new CourseSearchForm();
                      this.onClear = jasmine.createSpy('onClear');
                      this.onSearch = jasmine.createSpy('onSearch');
                      this.form.on('clear', this.onClear);
                      this.form.on('search', this.onSearch);
                  });
                  it('trims input string', trimsInputString);
                  it('handles calls to doSearch', doesSearch);
                  it('triggers a search event and changes to active state', triggersSearchEvent);
                  it('clears search when clicking on cancel button', clearsSearchOnCancel);
                  it('clears search when search box is empty', clearsSearchOnEmpty);
              });
  
              describe('DashSearchForm', function() {
                  beforeEach(function() {
                      loadFixtures('js/fixtures/search/dashboard_search_form.html');
                      this.form = new DashSearchForm();
                      this.onClear = jasmine.createSpy('onClear');
                      this.onSearch = jasmine.createSpy('onSearch');
                      this.form.on('clear', this.onClear);
                      this.form.on('search', this.onSearch);
                  });
                  it('trims input string', trimsInputString);
                  it('handles calls to doSearch', doesSearch);
                  it('triggers a search event and changes to active state', triggersSearchEvent);
                  it('clears search when clicking on cancel button', clearsSearchOnCancel);
                  it('clears search when search box is empty', clearsSearchOnEmpty);
              });
          });
  
  
          describe('SearchResultsView', function() {
              function showsLoadingMessage() {
                  this.resultsView.showLoadingMessage();
                  expect(this.resultsView.$contentElement).toBeHidden();
                  expect(this.resultsView.$el).toBeVisible();
                  expect(this.resultsView.$el).not.toBeEmpty();
              }
  
              function showsErrorMessage() {
                  this.resultsView.showErrorMessage();
                  expect(this.resultsView.$contentElement).toBeHidden();
                  expect(this.resultsView.$el).toBeVisible();
                  expect(this.resultsView.$el).not.toBeEmpty();
              }
  
              function returnsToContent() {
                  this.resultsView.clear();
                  expect(this.resultsView.$contentElement).toHaveCss({'display': this.contentElementDisplayValue});
                  expect(this.resultsView.$el).toBeHidden();
                  expect(this.resultsView.$el).toBeEmpty();
              }
  
              function showsNoResultsMessage() {
                  this.collection.reset();
                  this.resultsView.render();
                  expect(this.resultsView.$el).toContainHtml('no results');
                  expect(this.resultsView.$el.find('ol')).not.toExist();
              }
  
              function rendersSearchResults() {
                  var searchResults = [{
                      location: ['section', 'subsection', 'unit'],
                      url: '/some/url/to/content',
                      content_type: 'text',
                      course_name: '',
                      excerpt: 'this is a short excerpt'
                  }];
                  this.collection.set(searchResults);
                  this.collection.latestModelsCount = 1;
                  this.collection.totalCount = 1;
  
                  this.resultsView.render();
                  expect(this.resultsView.$el.find('ol')[0]).toExist();
                  expect(this.resultsView.$el.find('li').length).toEqual(1);
                  expect(this.resultsView.$el).toContainHtml('Search Results');
                  expect(this.resultsView.$el).toContainHtml('this is a short excerpt');
  
                  this.collection.set(searchResults);
                  this.collection.totalCount = 2;
                  this.resultsView.renderNext();
                  expect(this.resultsView.$el.find('.search-count')).toContainHtml('2');
                  expect(this.resultsView.$el.find('li').length).toEqual(2);
              }
  
              function showsMoreResultsLink() {
                  this.collection.totalCount = 123;
                  this.collection.hasNextPage = function() { return true; };
                  this.resultsView.render();
                  expect(this.resultsView.$el.find('a.search-load-next')[0]).toExist();
  
                  this.collection.totalCount = 123;
                  this.collection.hasNextPage = function() { return false; };
                  this.resultsView.render();
                  expect(this.resultsView.$el.find('a.search-load-next')[0]).not.toExist();
              }
  
              function triggersNextPageEvent() {
                  var onNext = jasmine.createSpy('onNext');
                  this.resultsView.on('next', onNext);
                  this.collection.totalCount = 123;
                  this.collection.hasNextPage = function() { return true; };
                  this.resultsView.render();
                  this.resultsView.$el.find('a.search-load-next').click();
                  expect(onNext).toHaveBeenCalled();
              }
  
              function showsLoadMoreSpinner() {
                  this.collection.totalCount = 123;
                  this.collection.hasNextPage = function() { return true; };
                  this.resultsView.render();
                  expect(this.resultsView.$el.find('a.search-load-next .icon')).toBeHidden();
                  this.resultsView.loadNext();
                  // toBeVisible does not work with inline
                  expect(this.resultsView.$el.find('a.search-load-next .icon')).toHaveCss({'display': 'inline'});
                  this.resultsView.renderNext();
                  expect(this.resultsView.$el.find('a.search-load-next .icon')).toBeHidden();
              }
  
              function beforeEachHelper(SearchResultsView) {
                  appendSetFixtures(
                      '<div class="courseware-results"></div>' +
                      '<section id="course-content"></section>' +
                      '<section id="dashboard-search-results"></section>' +
                      '<section id="my-courses" tabindex="-1"></section>'
                  );
  
                  TemplateHelpers.installTemplates([
                      'templates/search/course_search_item',
                      'templates/search/dashboard_search_item',
                      'templates/search/course_search_results',
                      'templates/search/dashboard_search_results',
                      'templates/search/search_loading',
                      'templates/search/search_error'
                  ]);
  
                  var MockCollection = Backbone.Collection.extend({
                      hasNextPage: function() {},
                      latestModelsCount: 0,
                      pageSize: 20,
                      latestModels: function() {
                          return SearchCollection.prototype.latestModels.apply(this, arguments);
                      }
                  });
                  this.collection = new MockCollection();
                  this.resultsView = new SearchResultsView({collection: this.collection});
              }
  
              describe('CourseSearchResultsView', function() {
                  beforeEach(function() {
                      beforeEachHelper.call(this, CourseSearchResultsView);
                      this.contentElementDisplayValue = 'table-cell';
                  });
                  it('shows loading message', showsLoadingMessage);
                  it('shows error message', showsErrorMessage);
                  it('returns to content', returnsToContent);
                  it('shows a message when there are no results', showsNoResultsMessage);
                  it('renders search results', rendersSearchResults);
                  it('shows a link to load more results', showsMoreResultsLink);
                  it('triggers an event for next page', triggersNextPageEvent);
                  it('shows a spinner when loading more results', showsLoadMoreSpinner);
              });
  
              describe('DashSearchResultsView', function() {
                  beforeEach(function() {
                      beforeEachHelper.call(this, DashSearchResultsView);
                      this.contentElementDisplayValue = 'block';
                  });
                  it('shows loading message', showsLoadingMessage);
                  it('shows error message', showsErrorMessage);
                  it('returns to content', returnsToContent);
                  it('shows a message when there are no results', showsNoResultsMessage);
                  it('renders search results', rendersSearchResults);
                  it('shows a link to load more results', showsMoreResultsLink);
                  it('triggers an event for next page', triggersNextPageEvent);
                  it('shows a spinner when loading more results', showsLoadMoreSpinner);
                  it('returns back to courses', function() {
                      var onReset = jasmine.createSpy('onReset');
                      this.resultsView.on('reset', onReset);
                      this.resultsView.render();
                      expect(this.resultsView.$el.find('a.search-back-to-courses')).toExist();
                      this.resultsView.$el.find('.search-back-to-courses').click();
                      expect(onReset).toHaveBeenCalled();
                      expect(this.resultsView.$contentElement).toBeVisible();
                      expect(this.resultsView.$el).toBeHidden();
                  });
              });
          });
  
  
          describe('SearchApp', function() {
              function showsLoadingMessage() {
                  $('.search-field').val('search string');
                  $('.search-button').trigger('click');
                  expect(this.$contentElement).toBeHidden();
                  expect(this.$searchResults).toBeVisible();
                  expect(this.$searchResults).not.toBeEmpty();
              }
  
              function performsSearch() {
                  var requests = AjaxHelpers.requests(this);
                  $('.search-field').val('search string');
                  $('.search-button').trigger('click');
                  AjaxHelpers.respondWithJson(requests, {
                      total: 1337,
                      access_denied_count: 12,
                      results: [{
                          data: {
                              location: ['section', 'subsection', 'unit'],
                              url: '/some/url/to/content',
                              content_type: 'text',
                              excerpt: 'this is a short excerpt',
                              course_name: ''
                          }
                      }]
                  });
                  expect($('.search-info')).toExist();
                  expect($('.search-result-list')).toBeVisible();
                  expect(this.$searchResults.find('li').length).toEqual(1);
              }
  
              function showsErrorMessage() {
                  var requests = AjaxHelpers.requests(this);
                  $('.search-field').val('search string');
                  $('.search-button').trigger('click');
                  AjaxHelpers.respondWithError(requests, 500, {});
                  expect(this.$searchResults).toContainHtml('There was an error');
              }
  
              function updatesNavigationHistory() {
                  $('.search-field').val('edx');
                  $('.search-button').trigger('click');
                  expect(Backbone.history.navigate.calls.mostRecent().args[0]).toContain('search/edx');
                  $('.cancel-button').trigger('click');
                  expect(Backbone.history.navigate.calls.argsFor(1)[0]).toBe('');
              }
  
              function cancelsSearchRequest() {
                  var requests = AjaxHelpers.requests(this);
                  // send search request to server
                  $('.search-field').val('search string');
                  $('.search-button').trigger('click');
                  // cancel the search and then skip the request that was marked as reset
                  $('.cancel-button').trigger('click');
                  AjaxHelpers.skipResetRequest(requests);
                  // there should be no results
                  expect(this.$contentElement).toHaveCss({'display': this.contentElementDisplayValue});
                  expect(this.$searchResults).toBeHidden();
              }
  
              function clearsResults() {
                  $('.cancel-button').trigger('click');
                  expect(this.$contentElement).toHaveCss({'display': this.contentElementDisplayValue});
                  expect(this.$searchResults).toBeHidden();
              }
  
              function loadsNextPage() {
                  var requests = AjaxHelpers.requests(this);
                  var response = {
                      total: 1337,
                      access_denied_count: 12,
                      results: [{
                          data: {
                              location: ['section', 'subsection', 'unit'],
                              url: '/some/url/to/content',
                              content_type: 'text',
                              excerpt: 'this is a short excerpt',
                              course_name: ''
                          }
                      }]
                  };
                  $('.search-field').val('query');
                  $('.search-button').trigger('click');
                  AjaxHelpers.respondWithJson(requests, response);
                  expect(this.$searchResults.find('li').length).toEqual(1);
                  expect($('.search-load-next')).toBeVisible();
                  $('.search-load-next').trigger('click');
                  var body = requests[1].requestBody;
                  expect(body).toContain('search_string=query');
                  expect(body).toContain('page_index=1');
                  AjaxHelpers.respondWithJson(requests, response);
                  expect(this.$searchResults.find('li').length).toEqual(2);
              }
  
              function navigatesToSearch() {
                  var requests = AjaxHelpers.requests(this);
                  Backbone.history.start();
                  Backbone.history.loadUrl('search/query');
                  expect(requests[0].requestBody).toContain('search_string=query');
              }
  
              function loadTemplates() {
                  TemplateHelpers.installTemplates([
                      'templates/search/course_search_item',
                      'templates/search/dashboard_search_item',
                      'templates/search/search_loading',
                      'templates/search/search_error',
                      'templates/search/course_search_results',
                      'templates/search/dashboard_search_results'
                  ]);
              }
  
              describe('CourseSearchApp', function() {
                  beforeEach(function() {
                      loadFixtures('js/fixtures/search/course_search_form.html');
                      appendSetFixtures(
                          '<div class="courseware-results"></div>' +
                          '<section id="course-content"></section>'
                      );
                      loadTemplates.call(this);
  
                      var courseId = 'a/b/c';
                      CourseSearchFactory(courseId);
                      spyOn(Backbone.history, 'navigate');
                      this.$contentElement = $('#course-content');
                      this.contentElementDisplayValue = 'table-cell';
                      this.$searchResults = $('.courseware-results');
                  });
  
                  afterEach(function() {
                      Backbone.history.stop();
                  });
  
                  it('shows loading message on search', showsLoadingMessage);
                  it('performs search', performsSearch);
                  it('shows an error message', showsErrorMessage);
                  it('updates navigation history', updatesNavigationHistory);
                  it('cancels search request', cancelsSearchRequest);
                  it('clears results', clearsResults);
                  it('loads next page', loadsNextPage);
                  it('navigates to search', navigatesToSearch);
              });
  
              describe('DashSearchApp', function() {
                  beforeEach(function() {
                      loadFixtures('js/fixtures/search/dashboard_search_form.html');
                      appendSetFixtures(
                          '<section id="dashboard-search-results"></section>' +
                          '<section id="my-courses" tabindex="-1"></section>'
                      );
                      loadTemplates.call(this);
                      DashboardSearchFactory();
  
                      spyOn(Backbone.history, 'navigate');
                      this.$contentElement = $('#my-courses');
                      this.contentElementDisplayValue = 'block';
                      this.$searchResults = $('#dashboard-search-results');
                  });
  
                  afterEach(function() {
                      Backbone.history.stop();
                  });
  
                  it('shows loading message on search', showsLoadingMessage);
                  it('performs search', performsSearch);
                  it('shows an error message', showsErrorMessage);
                  it('updates navigation history', updatesNavigationHistory);
                  it('cancels search request', cancelsSearchRequest);
                  it('clears results', clearsResults);
                  it('loads next page', loadsNextPage);
                  it('navigates to search', navigatesToSearch);
                  it('returns to course list', function() {
                      var requests = AjaxHelpers.requests(this);
                      $('.search-field').val('search string');
                      $('.search-button').trigger('click');
                      AjaxHelpers.respondWithJson(requests, {
                          total: 1337,
                          access_denied_count: 12,
                          results: [{
                              data: {
                                  location: ['section', 'subsection', 'unit'],
                                  url: '/some/url/to/content',
                                  content_type: 'text',
                                  excerpt: 'this is a short excerpt',
                                  course_name: ''
                              }
                          }]
                      });
                      expect($('.search-back-to-courses')).toExist();
                      $('.search-back-to-courses').trigger('click');
                      expect(this.$contentElement).toBeVisible();
                      expect(this.$searchResults).toBeHidden();
                      expect(this.$searchResults).toBeEmpty();
                  });
              });
          });
      });
  });
  