#2372 Make the search work when searching for project with namespaces or forks
Merged 6 years ago by pingou. Opened 6 years ago by pingou.

file modified
+26 -2
@@ -287,6 +287,10 @@ 

      |               |          |               |   returned depending if  |

      |               |          |               |   they are forks or not  |

      +---------------+----------+---------------+--------------------------+

+     | ``short``     | boolean  | Optional      | | Whether to return the  |

+     |               |          |               |   entrie project JSON    |

+     |               |          |               |   or just a sub-set      |

+     +---------------+----------+---------------+--------------------------+

  

      Sample response

      ^^^^^^^^^^^^^^^
@@ -381,11 +385,16 @@ 

      namespace = flask.request.values.get('namespace', None)

      owner = flask.request.values.get('owner', None)

      pattern = flask.request.values.get('pattern', None)

+     short = flask.request.values.get('short', None)

  

      if str(fork).lower() in ['1', 'true']:

          fork = True

      elif str(fork).lower() in ['0', 'false']:

          fork = False

+     if str(short).lower() in ['1', 'true']:

+         short = True

+     else:

+         short = False

  

      private = False

      if authenticated() and username == flask.g.fas_user.username:
@@ -399,16 +408,31 @@ 

          raise pagure.exceptions.APIError(

              404, error_code=APIERROR.ENOPROJECTS)

  

+     if not short:

+         projects = [p.to_json(api=True, public=True) for p in projects]

+     else:

+         projects = [

+             {

+                 'name': p.name,

+                 'namespace': p.namespace,

+                 'fullname': p.fullname.replace('forks/', 'fork/', 1)

+                 if p.fullname.startswith('forks/') else p.fullname,

+                 'description': p.description,

+             }

+             for p in projects

+         ]

+ 

      jsonout = flask.jsonify({

          'total_projects': len(projects),

-         'projects': [p.to_json(api=True, public=True) for p in projects],

+         'projects': projects,

          'args': {

              'tags': tags,

              'username': username,

              'fork': fork,

              'pattern': pattern,

              'namespace': namespace,

-             'owner': owner

+             'owner': owner,

+             'short': short,

          }

      })

      return jsonout

@@ -9,6 +9,9 @@ 

          <option value="user"{% if select=='users' %} selected {% endif %}>Users</option>

          <option value="groups"{% if select=='groups' %} selected {% endif %}>Groups</option>

        </select>

+       {% if select == 'projects' %}

+       <input type="hidden" name="direct" readonly value="1">

+       {% endif %}

  

        <input type="text" name="term" id="term" placeholder="{%

          if select=='projects' %}Search projects{%

file modified
+37 -33
@@ -15,7 +15,7 @@ 

  {% block content %}

  <div class="repo-header p-t-1">

    <div class="container">

-     {{browse_header(select=select)}}

+     {{ browse_header(select=select) }}

    </div>

  </div>

    <div class="container">
@@ -33,18 +33,23 @@ 

  <script src="{{ url_for('static', filename='vendor/jquery.dotdotdot/jquery.dotdotdot.min.js') }}" type="text/javascript"></script>

  <script type="text/javascript">

  $(document).ready(function() {

+ 

    $('#headerSearch').on('keypress keydown keyup', function(e) {

      if (e.which == 13) {

          e.preventDefault();

          return false;

      }

- });

+   });

+ 

    $('#term').selectize({

-     valueField: 'name',

-     labelField: 'name',

+     valueField: 'fullname',

+     labelField: 'fullname',

+     searchField: 'fullname',

+     maxItems: 1,

+     create: false,

      onType: function(value){

        if (value == ""){

-       this.close();

+         this.close();

        }

      },

      onChange: function(value){
@@ -52,14 +57,12 @@ 

          $('#headerSearch').submit();

        }

      },

-     searchField: 'name',

-     maxItems: 1,

-     create: false,

      load: function(query, callback) {

        if (!query.length) return callback();

        $.getJSON(

          "{{ url_for('api_ns.api_projects') }}", {

-           pattern: "*"+query+"*"

+           pattern: "*"+query+"*",

+           short: "1",

          },

          function( data ) {

            callback( data.projects );
@@ -68,35 +71,36 @@ 

      },

      render: {

        option: function(item, escape) {

-         {% set reponame = 'item.name' %}

-         return '<div>' +

-             '<div class="projecticon-search pull-xs-left"><span class="oi" data-glyph="document"></span></div>'+

-             '<div class="title">' +

-                 '<span class="name"><strong>' + escape(item.name) + '</strong></span>' +

-             '</div>' +

-             '<div class="description"><small>' + escape(item.description) + '</small></div>' +

-         '</div>';

+         {% set reponame = 'item.fullname' %}

+         return '<div>'

+           +   '<div class="projecticon-search pull-xs-left">'

+           +     '<span class="oi" data-glyph="document"></span>'

+           +   '</div>'

+           +   '<div class="title">'

+           +     '<span class="name">'

+           +       '<strong>' + escape(item.fullname) + '</strong>'

+           +     '</span>'

+           +   '</div>'

+           +   '<div class="description">'

+           +     '<small>' + escape(item.description) + '</small>'

+           +   '</div>'

+           + '</div>';

        }

      },

    });

- });

- </script>

- {% if username %}

- <script type="text/javascript">

-   $(function(){

-       $('.show_parts input[type="checkbox"]').change(function(){

-           $('#' + $(this).attr('name')).toggle();

-       });

-   });

- </script>

- {% endif %}

  

- <script type="text/javascript">

-   $(document).ready(function() {

-       $(".repo_desc").dotdotdot({

-           watch:"window"

-       });

+   $(".repo_desc").dotdotdot({

+     watch:"window"

    });

+ 

+   {% if username %}

+     $(function(){

+         $('.show_parts input[type="checkbox"]').change(function(){

+             $('#' + $(this).attr('name')).toggle();

+         });

+     });

+   {% endif %}

+ });

  </script>

  

  {% endblock %}

file modified
+11
@@ -158,6 +158,12 @@ 

      stype = flask.request.args.get('type', 'projects')

      term = flask.request.args.get('term')

      page = flask.request.args.get('page', 1)

+     direct = flask.request.values.get('direct', None)

+     if str(direct).lower() in ['1', 'true']:

+         direct = True

+     else:

+         direct = False

+ 

      try:

          page = int(page)

          if page < 1:
@@ -165,6 +171,11 @@ 

      except ValueError:

          page = 1

  

+     if direct:

+         return flask.redirect(

+             flask.url_for('view_repo', repo='') + term

+         )

+ 

      if stype == 'projects':

          return flask.redirect(flask.url_for('view_projects', pattern=term))

      elif stype == 'projects_forks':

@@ -235,6 +235,107 @@ 

          data = json.loads(output.data)

          self.assertDictEqual(data, expected_rv)

  

+     def test_api_projects_pattern(self):

+         """ Test the api_projects method of the flask api. """

+         tests.create_projects(self.session)

+ 

+         output = self.app.get('/api/0/projects?pattern=test')

+         self.assertEqual(output.status_code, 200)

+         data = json.loads(output.data)

+         data['projects'][0]['date_created'] = "1436527638"

+         expected_data = {

+           "args": {

+             "fork": None,

+             "namespace": None,

+             "owner": None,

+             "pattern": "test",

+             "short": False,

+             "tags": [],

+             "username": None

+           },

+           "projects": [

+             {

+               "access_groups": {

+                 "admin": [],

+                 "commit": [],

+                 "ticket": []

+               },

+               "access_users": {

+                 "admin": [],

+                 "commit": [],

+                 "owner": [

+                   "pingou"

+                 ],

+                 "ticket": []

+               },

+               "close_status": [

+                 "Invalid",

+                 "Insufficient data",

+                 "Fixed",

+                 "Duplicate"

+               ],

+               "custom_keys": [],

+               "date_created": "1436527638",

+               "description": "test project #1",

+               "fullname": "test",

+               "id": 1,

+               "milestones": {},

+               "name": "test",

+               "namespace": None,

+               "parent": None,

+               "priorities": {},

+               "tags": [],

+               "user": {

+                 "fullname": "PY C",

+                 "name": "pingou"

+               }

+             }

+           ],

+           "total_projects": 1

+         }

+         self.assertDictEqual(data, expected_data)

+ 

+     def test_api_projects_pattern_short(self):

+         """ Test the api_projects method of the flask api. """

+         tests.create_projects(self.session)

+ 

+         output = self.app.get('/api/0/projects?pattern=te*&short=1')

+         self.assertEqual(output.status_code, 200)

+         data = json.loads(output.data)

+         expected_data = {

+           "args": {

+             "fork": None,

+             "namespace": None,

+             "owner": None,

+             "pattern": "te*",

+             "short": True,

+             "tags": [],

+             "username": None

+           },

+           "projects": [

+             {

+               "description": "test project #1",

+               "fullname": "test",

+               "name": "test",

+               "namespace": None

+             },

+             {

+               "description": "test project #2",

+               "fullname": "test2",

+               "name": "test2",

+               "namespace": None

+             },

+             {

+               "description": "namespaced test project",

+               "fullname": "somenamespace/test3",

+               "name": "test3",

+               "namespace": "somenamespace"

+             }

+           ],

+           "total_projects": 3

+         }

+         self.assertDictEqual(data, expected_data)

+ 

      def test_api_projects(self):

          """ Test the api_projects method of the flask api. """

          tests.create_projects(self.session)
@@ -272,6 +373,7 @@ 

                  "namespace": None,

                  "owner": None,

                  "pattern": None,

+                 "short": False,

                  "tags": ["infra"],

                  "username": None

              },
@@ -323,6 +425,7 @@ 

                  "namespace": None,

                  "owner": "pingou",

                  "pattern": None,

+                 "short": False,

                  "tags": [],

                  "username": None

              },
@@ -446,6 +549,7 @@ 

                  "namespace": None,

                  "owner": None,

                  "pattern": None,

+                 "short": False,

                  "tags": [],

                  "username": "pingou"

              },
@@ -564,6 +668,7 @@ 

                  "namespace": None,

                  "owner": None,

                  "pattern": None,

+                 "short": False,

                  "tags": ["infra"],

                  "username": "pingou",

              },
@@ -613,6 +718,7 @@ 

                  "owner": None,

                  "namespace": "somenamespace",

                  "pattern": None,

+                 "short": False,

                  "tags": [],

                  "username": None

              },