aboutsummaryrefslogtreecommitdiffstats
path: root/docs/component-spec/bootstrap/bootstrapSpec.js
blob: 2c8d89fa9578be10d72754b81e6f3221f02ad02e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
'use strict';

describe('bootstrap', function() {
  var $compile, $rootScope, element;

  function clickTab(element, index) {
    browserTrigger(element.children().eq(0).children().eq(index));
  }

  beforeEach(module('bootstrap'));
  beforeEach(inject(function(_$compile_, _$rootScope_) {
    $compile = _$compile_;
    $rootScope = _$rootScope_;
  }));
  beforeEach(function(){
    function findTab(element, index) {
      return _jQuery(element[0]).find('> .nav-tabs > li').eq(index);
    }
    function findTabPane(element, index) {
      return _jQuery(element[0]).find('> .tab-content > .tab-pane').eq(index);
    }

    this.addMatchers({
      toHaveTab: function(index, title) {
        var tab = findTab(element, index);

        this.message = function() {
          if (tab.length) {
            return 'Expect tab index ' + index + ' to be ' + toJson(title) + ' but was ' + toJson(tab.text());
          } else {
            return 'Expect tab index ' + index + ' to be ' + toJson(title) + ' but there are only ' +
              element.children().length + ' tabs.';
          }
        };

        return tab.length && tab.text() == title;
      },

      toHaveTabPane: function(index, title) {
        var tabPane = findTabPane(element, index);

        this.message = function() {
          if (tabPane.length) {
            return 'Expect tab pane index ' + index + ' to be ' + toJson(title) + ' but was ' + toJson(tabPane.text());
          } else {
            return 'Expect tab pane index ' + index + ' to be ' + toJson(title) + ' but there are only ' +
              element.children().length + 'tab panes.';
          }
        };

        return tabPane.length && tabPane.text() == title;
      },

      toHaveSelected: function(index) {
        var tab = findTab(element, index);
        var tabPane = findTabPane(element, index);

        this.message = function() {
          return 'Expect tab  index ' + index + ' to be selected\n' +
            '     TAB: ' + angular.mock.dump(tab) + '\n' +
            'TAB-PANE: ' + angular.mock.dump(tabPane);
        };

        return tabPane.hasClass('active') && tab.hasClass('active');
      }
    });
  });

  afterEach(function() {
    dealoc(element);
  });

  describe('tabbable', function() {

    it('should create the right structure', function() {
      element = $compile(
        '<div class="tabbable">' +
          '<div class="tab-pane" title="first">tab1</div>' +
          '<div class="tab-pane" title="second">tab2</div>' +
        '</div>')($rootScope);

      $rootScope.$apply();

      expect(element).toHaveTab(0, 'first');
      expect(element).toHaveTab(1, 'second');

      expect(element).toHaveTabPane(0, 'tab1');
      expect(element).toHaveTabPane(1, 'tab2');

      expect(element).toHaveSelected(0);
    });


    it('should respond to tab click', function(){
      element = $compile(
        '<div class="tabbable">' +
          '<div class="tab-pane" title="first">tab1</div>' +
          '<div class="tab-pane" title="second">tab2</div>' +
          '</div>')($rootScope);

      expect(element).toHaveSelected(0);
      clickTab(element, 1);
      expect(element).toHaveSelected(1);
    });


    it('should select the first tab in repeater', function() {
      element = $compile(
        '<div class="tabbable">' +
          '<div class="tab-pane" ng-repeat="id in [1,2,3]" title="Tab {{id}}" value="tab-{{id}}">' +
          'Tab content {{id}}!' +
          '</div>' +
        '</div>')($rootScope);
      $rootScope.$apply();

      expect(element).toHaveSelected(0);
    });


    describe('ngModel', function() {
      it('should bind to model', function() {
        $rootScope.tab = 'B';

        element = $compile(
          '<div class="tabbable" ng-model="tab">' +
            '<div class="tab-pane" title="first" value="A">tab1</div>' +
            '<div class="tab-pane" title="second" value="B">tab2</div>' +
          '</div>')($rootScope);

        $rootScope.$apply();
        expect(element).toHaveSelected(1);

        $rootScope.tab = 'A';
        $rootScope.$apply();
        expect(element).toHaveSelected(0);

        clickTab(element, 1);
        expect($rootScope.tab).toEqual('B');
        expect(element).toHaveSelected(1);
      });


      it('should not overwrite the model', function() {
        $rootScope.tab = 'tab-2';
        element = $compile(
        '<div class="tabbable" ng-model="tab">' +
            '<div class="tab-pane" ng-repeat="id in [1,2,3]" title="Tab {{id}}" value="tab-{{id}}">' +
            'Tab content {{id}}!' +
            '</div>' +
            '</div>')($rootScope);
        $rootScope.$apply();

        expect(element).toHaveSelected(1);
      });
    });
  });
});
9;_stream'): self._load_stream() return self._stream @property def QUERY_PARAMS(self): """ More semantically correct name for request.GET. """ return self._request.GET @property def DATA(self): """ Parses the request body and returns the data. Similar to usual behaviour of `request.POST`, except that it handles arbitrary parsers, and also works on methods other than POST (eg PUT). """ if not _hasattr(self, '_data'): self._load_data_and_files() return self._data @property def FILES(self): """ Parses the request body and returns any files uploaded in the request. Similar to usual behaviour of `request.FILES`, except that it handles arbitrary parsers, and also works on methods other than POST (eg PUT). """ if not _hasattr(self, '_files'): self._load_data_and_files() return self._files @property def user(self): """ Returns the user associated with the current request, as authenticated by the authentication classes provided to the request. """ if not hasattr(self, '_user'): self._authenticator, self._user, self._auth = self._authenticate() return self._user @user.setter def user(self, value): """ Sets the user on the current request. This is necessary to maintain compatilbility with django.contrib.auth where the user proprety is set in the login and logout functions. """ self._user = value @property def auth(self): """ Returns any non-user authentication information associated with the request, such as an authentication token. """ if not hasattr(self, '_auth'): self._authenticator, self._user, self._auth = self._authenticate() return self._auth @auth.setter def auth(self, value): """ Sets any non-user authentication information associated with the request, such as an authentication token. """ self._auth = value @property def successful_authenticator(self): """ Return the instance of the authentication instance class that was used to authenticate the request, or `None`. """ if not hasattr(self, '_authenticator'): self._authenticator, self._user, self._auth = self._authenticate() return self._authenticator def _load_data_and_files(self): """ Parses the request content into self.DATA and self.FILES. """ if not _hasattr(self, '_content_type'): self._load_method_and_content_type() if not _hasattr(self, '_data'): self._data, self._files = self._parse() def _load_method_and_content_type(self): """ Sets the method and content_type, and then check if they've been overridden. """ self._content_type = self.META.get('HTTP_CONTENT_TYPE', self.META.get('CONTENT_TYPE', '')) self._perform_form_overloading() if not _hasattr(self, '_method'): # Method wasn't overloaded by hidden form element, so look for # method override in header. If not present default to raw HTTP method self._method = self.META.get('HTTP_X_HTTP_METHOD_OVERRIDE', self._request.method) def _load_stream(self): """ Return the content body of the request, as a stream. """ try: content_length = int(self.META.get('CONTENT_LENGTH', self.META.get('HTTP_CONTENT_LENGTH'))) except (ValueError, TypeError): content_length = 0 if content_length == 0: self._stream = None elif hasattr(self._request, 'read'): self._stream = self._request else: self._stream = BytesIO(self.raw_post_data) def _perform_form_overloading(self): """ If this is a form POST request, then we need to check if the method and content/content_type have been overridden by setting them in hidden form fields or not. """ USE_FORM_OVERLOADING = ( self._METHOD_PARAM or (self._CONTENT_PARAM and self._CONTENTTYPE_PARAM) ) # We only need to use form overloading on form POST requests. if (not USE_FORM_OVERLOADING or self._request.method != 'POST' or not is_form_media_type(self._content_type)): return # At this point we're committed to parsing the request as form data. self._data = self._request.POST self._files = self._request.FILES # Method overloading - change the method and remove the param from the content. if (self._METHOD_PARAM and self._METHOD_PARAM in self._data): self._method = self._data[self._METHOD_PARAM].upper() # Content overloading - modify the content type, and force re-parse. if (self._CONTENT_PARAM and self._CONTENTTYPE_PARAM and self._CONTENT_PARAM in self._data and self._CONTENTTYPE_PARAM in self._data): self._content_type = self._data[self._CONTENTTYPE_PARAM] self._stream = BytesIO(self._data[self._CONTENT_PARAM].encode(HTTP_HEADER_ENCODING)) self._data, self._files = (Empty, Empty) def _parse(self): """ Parse the request content, returning a two-tuple of (data, files) May raise an `UnsupportedMediaType`, or `ParseError` exception. """ stream = self.stream media_type = self.content_type if stream is None or media_type is None: empty_data = QueryDict('', self._request._encoding) empty_files = MultiValueDict() return (empty_data, empty_files) parser = self.negotiator.select_parser(self, self.parsers) if not parser: raise exceptions.UnsupportedMediaType(media_type) parsed = parser.parse(stream, media_type, self.parser_context) # Parser classes may return the raw data, or a # DataAndFiles object. Unpack the result as required. try: return (parsed.data, parsed.files) except AttributeError: empty_files = MultiValueDict() return (parsed, empty_files) def _authenticate(self): """ Attempt to authenticate the request using each authentication instance in turn. Returns a three-tuple of (authenticator, user, authtoken). """ for authenticator in self.authenticators: user_auth_tuple = authenticator.authenticate(self) if not user_auth_tuple is None: user, auth = user_auth_tuple return (authenticator, user, auth) return self._not_authenticated() def _not_authenticated(self): """ Return a three-tuple of (authenticator, user, authtoken), representing an unauthenticated request. By default this will be (None, AnonymousUser, None). """ if api_settings.UNAUTHENTICATED_USER: user = api_settings.UNAUTHENTICATED_USER() else: user = None if api_settings.UNAUTHENTICATED_TOKEN: auth = api_settings.UNAUTHENTICATED_TOKEN() else: auth = None return (None, user, auth) def __getattr__(self, attr): """ Proxy other attributes to the underlying HttpRequest object. """ return getattr(self._request, attr)