)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":8482,"name":"Colleen Murphy","email":"colleen@gazlene.net","username":"krinkle"},"change_message_id":"fc4c62e288ae7a3c57f7cc4956557c20d2729e54","unresolved":false,"context_lines":[{"line_number":9,"context_line":"SQl refactor to allow tags search a more"},{"line_number":10,"context_line":"uniform and expected result."},{"line_number":11,"context_line":""},{"line_number":12,"context_line":"Closes-Bug: #1756190"},{"line_number":13,"context_line":"Partially Implements: bp project-tags"},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"Change-Id: I766cc7a8a7ce2ca3c68d6b910445062675f3d7ad"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":4,"id":"bf659307_b9e982e3","line":12,"updated":"2018-04-04 12:22:09.000000000","message":"We already merged https://review.openstack.org/553108 which also claims to close this bug, is this patch still needed? Or should this be changed to Related-Bug?","commit_id":"f014d8f7995b052471d62a50d9136e32e80d4d00"}],"keystone/resource/backends/sql.py":[{"author":{"_account_id":23140,"name":"Jess Egler","email":"jess.egler@gmail.com","username":"jessegler"},"change_message_id":"363e3c846a98e45ef0520c8e0504358b832191c5","unresolved":false,"context_lines":[{"line_number":202,"context_line":"        subq \u003d query.join(tag_alias,"},{"line_number":203,"context_line":"                          ProjectTag.project_id \u003d\u003d tag_alias.project_id)"},{"line_number":204,"context_line":"        if \u0027any\u0027 in filters[\u0027method\u0027]:"},{"line_number":205,"context_line":"            subq \u003d subq.filter(tag_alias.name.in_(tags))"},{"line_number":206,"context_line":"        else:"},{"line_number":207,"context_line":"            # We build a JOIN ladder expression for each tag, JOIN\u0027ing"},{"line_number":208,"context_line":"            # the first tag to the instances table, and each subsequent"}],"source_content_type":"text/x-python","patch_set":3,"id":"df7087c5_c387710f","line":205,"updated":"2018-03-19 23:47:05.000000000","message":"I don\u0027t think you need to use alias here. I think you could just use subq \u003d query.filter(ProjectTag.name.in_(any_tags))","commit_id":"20bd3f1ccd348bed0dfe83ac673af6986d757286"}],"keystone/tests/unit/test_v3_resource.py":[{"author":{"_account_id":20466,"name":"Tin Lam","email":"tin@lam.wtf","username":"tinlam"},"change_message_id":"f9bc03fd9e71532bdb08880f119cb49d86182024","unresolved":false,"context_lines":[{"line_number":737,"context_line":"            \u0027values\u0027: tag_string})"},{"line_number":738,"context_line":"        pids \u003d [p[\u0027id\u0027] for p in resp.result[\u0027projects\u0027]]"},{"line_number":739,"context_line":"        self.assertValidProjectListResponse(resp)"},{"line_number":740,"context_line":"        self.assertNotIn(project[\u0027id\u0027], pids)"},{"line_number":741,"context_line":"        self.assertNotIn(project1[\u0027id\u0027], pids)"},{"line_number":742,"context_line":""},{"line_number":743,"context_line":"    def test_list_projects_filtering_by_tags_any(self):"},{"line_number":744,"context_line":"        \"\"\"Call ``GET /projects?tags-any\u003d{tags}``.\"\"\""}],"source_content_type":"text/x-python","patch_set":1,"id":"df7087c5_f787d760","line":741,"range":{"start_line":740,"start_character":0,"end_line":741,"end_character":46},"updated":"2018-03-19 19:35:20.000000000","message":"should we not have some test with a tag_string that returns positive results as well?","commit_id":"08a6a12b4d30c16d5a774a80d14171e95a94651a"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"f269396dcd9e360f9ad0878889ced0d482e3b0fa","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"df7087c5_e32cf54b","updated":"2018-03-19 23:18:24.000000000","message":"It would be good to add another test for \"tags\u003d{values}\u0026tags-any\u003d{values}\" to show that the bug is fixed.\n\nSee: https://review.openstack.org/#/c/553108/3/keystone/tests/unit/test_v3_resource.py","commit_id":"20bd3f1ccd348bed0dfe83ac673af6986d757286"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"f269396dcd9e360f9ad0878889ced0d482e3b0fa","unresolved":false,"context_lines":[{"line_number":728,"context_line":"            if project[\u0027id\u0027] \u003d\u003d untagged_project[\u0027id\u0027]:"},{"line_number":729,"context_line":"                self.assertEqual(project[\u0027tags\u0027], [])"},{"line_number":730,"context_line":""},{"line_number":731,"context_line":"    def test_list_projects_filtering_by_tags(self):"},{"line_number":732,"context_line":"        \"\"\"Call ``GET /projects?tags\u003d{tags}``.\"\"\""},{"line_number":733,"context_line":"        project, tags \u003d self._create_project_and_tags(num_of_tags\u003d2)"},{"line_number":734,"context_line":"        project1, tags1 \u003d self._create_project_and_tags(num_of_tags\u003d2)"},{"line_number":735,"context_line":"        tag_string \u003d tags[0] + \u0027,\u0027 + tags1[0]"},{"line_number":736,"context_line":"        resp \u003d self.get(\u0027/projects?tags\u003d%(values)s\u0027 % {"},{"line_number":737,"context_line":"            \u0027values\u0027: tag_string})"},{"line_number":738,"context_line":"        pids \u003d [p[\u0027id\u0027] for p in resp.result[\u0027projects\u0027]]"},{"line_number":739,"context_line":"        self.assertValidProjectListResponse(resp)"},{"line_number":740,"context_line":"        self.assertNotIn(project[\u0027id\u0027], pids)"},{"line_number":741,"context_line":"        self.assertNotIn(project1[\u0027id\u0027], pids)"},{"line_number":742,"context_line":""},{"line_number":743,"context_line":"    def test_list_projects_filtering_by_tags_any(self):"},{"line_number":744,"context_line":"        \"\"\"Call ``GET /projects?tags-any\u003d{tags}``.\"\"\""}],"source_content_type":"text/x-python","patch_set":3,"id":"df7087c5_c35d31ea","line":741,"range":{"start_line":731,"start_character":0,"end_line":741,"end_character":46},"updated":"2018-03-19 23:18:24.000000000","message":"This still seems like it\u0027s not testing if we can actually search for a project by tags, rather than just searching if we don\u0027t find a project when we give it values that would return none, which would also happen if the functionality didn\u0027t work.","commit_id":"20bd3f1ccd348bed0dfe83ac673af6986d757286"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"f269396dcd9e360f9ad0878889ced0d482e3b0fa","unresolved":false,"context_lines":[{"line_number":743,"context_line":"    def test_list_projects_filtering_by_tags_any(self):"},{"line_number":744,"context_line":"        \"\"\"Call ``GET /projects?tags-any\u003d{tags}``.\"\"\""},{"line_number":745,"context_line":"        project, tags \u003d self._create_project_and_tags(num_of_tags\u003d2)"},{"line_number":746,"context_line":"        project1, tags1 \u003d self._create_project_and_tags(num_of_tags\u003d2)"},{"line_number":747,"context_line":"        tag_string \u003d tags[0] + \u0027,\u0027 + tags1[0]"},{"line_number":748,"context_line":"        resp \u003d self.get(\u0027/projects?tags-any\u003d%(values)s\u0027 % {"},{"line_number":749,"context_line":"            \u0027values\u0027: tag_string})"},{"line_number":750,"context_line":"        pids \u003d [p[\u0027id\u0027] for p in resp.result[\u0027projects\u0027]]"},{"line_number":751,"context_line":"        self.assertValidProjectListResponse(resp)"},{"line_number":752,"context_line":"        self.assertIn(project[\u0027id\u0027], pids)"},{"line_number":753,"context_line":"        self.assertIn(project1[\u0027id\u0027], pids)"},{"line_number":754,"context_line":""},{"line_number":755,"context_line":"    def test_list_projects_filtering_by_not_tags(self):"},{"line_number":756,"context_line":"        \"\"\"Call ``GET /projects?not-tags\u003d{tags}``.\"\"\""}],"source_content_type":"text/x-python","patch_set":3,"id":"df7087c5_6372257f","line":753,"range":{"start_line":746,"start_character":0,"end_line":753,"end_character":43},"updated":"2018-03-19 23:18:24.000000000","message":"This change is good","commit_id":"20bd3f1ccd348bed0dfe83ac673af6986d757286"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"f269396dcd9e360f9ad0878889ced0d482e3b0fa","unresolved":false,"context_lines":[{"line_number":752,"context_line":"        self.assertIn(project[\u0027id\u0027], pids)"},{"line_number":753,"context_line":"        self.assertIn(project1[\u0027id\u0027], pids)"},{"line_number":754,"context_line":""},{"line_number":755,"context_line":"    def test_list_projects_filtering_by_not_tags(self):"},{"line_number":756,"context_line":"        \"\"\"Call ``GET /projects?not-tags\u003d{tags}``.\"\"\""},{"line_number":757,"context_line":"        project, tags \u003d self._create_project_and_tags(num_of_tags\u003d2)"},{"line_number":758,"context_line":"        project1, tags1 \u003d self._create_project_and_tags(num_of_tags\u003d2)"},{"line_number":759,"context_line":"        tag_string \u003d tags[0] + \u0027,\u0027 + tags1[0]"},{"line_number":760,"context_line":"        resp \u003d self.get(\u0027/projects?not-tags\u003d%(values)s\u0027 % {"},{"line_number":761,"context_line":"            \u0027values\u0027: tag_string})"},{"line_number":762,"context_line":"        pids \u003d [p[\u0027id\u0027] for p in resp.result[\u0027projects\u0027]]"},{"line_number":763,"context_line":"        self.assertValidProjectListResponse(resp)"},{"line_number":764,"context_line":"        self.assertIn(project[\u0027id\u0027], pids)"},{"line_number":765,"context_line":"        self.assertIn(project1[\u0027id\u0027], pids)"},{"line_number":766,"context_line":""},{"line_number":767,"context_line":"    def test_list_projects_filtering_by_not_tags_any(self):"},{"line_number":768,"context_line":"        \"\"\"Call ``GET /projects?not-tags-any\u003d{tags}``.\"\"\""}],"source_content_type":"text/x-python","patch_set":3,"id":"df7087c5_0309e9db","line":765,"range":{"start_line":755,"start_character":0,"end_line":765,"end_character":43},"updated":"2018-03-19 23:18:24.000000000","message":"This is the same as the first comment, it\u0027s testing the opposite of what this filter is actually supposed to do.","commit_id":"20bd3f1ccd348bed0dfe83ac673af6986d757286"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"f269396dcd9e360f9ad0878889ced0d482e3b0fa","unresolved":false,"context_lines":[{"line_number":766,"context_line":""},{"line_number":767,"context_line":"    def test_list_projects_filtering_by_not_tags_any(self):"},{"line_number":768,"context_line":"        \"\"\"Call ``GET /projects?not-tags-any\u003d{tags}``.\"\"\""},{"line_number":769,"context_line":"        project, tags \u003d self._create_project_and_tags(num_of_tags\u003d2)"},{"line_number":770,"context_line":"        project1, tags1 \u003d self._create_project_and_tags(num_of_tags\u003d2)"},{"line_number":771,"context_line":"        tag_string \u003d tags[0] + \u0027,\u0027 + tags1[0]"},{"line_number":772,"context_line":"        resp \u003d self.get(\u0027/projects?not-tags-any\u003d%(values)s\u0027 % {"},{"line_number":773,"context_line":"            \u0027values\u0027: tag_string})"},{"line_number":774,"context_line":"        pids \u003d [p[\u0027id\u0027] for p in resp.result[\u0027projects\u0027]]"},{"line_number":775,"context_line":"        self.assertValidProjectListResponse(resp)"},{"line_number":776,"context_line":"        self.assertNotIn(project[\u0027id\u0027], pids)"},{"line_number":777,"context_line":"        self.assertNotIn(project1[\u0027id\u0027], pids)"},{"line_number":778,"context_line":""},{"line_number":779,"context_line":"    def test_list_projects_filtering_multiple_tags_filters(self):"},{"line_number":780,"context_line":"        \"\"\"Call ``GET /projects?tags\u003d{tags}\u0026tags-any\u003d{tags}``.\"\"\""}],"source_content_type":"text/x-python","patch_set":3,"id":"df7087c5_c312110a","line":777,"range":{"start_line":769,"start_character":0,"end_line":777,"end_character":46},"updated":"2018-03-19 23:18:24.000000000","message":"ditto, but I like the list comprehension change","commit_id":"20bd3f1ccd348bed0dfe83ac673af6986d757286"},{"author":{"_account_id":21420,"name":"Gage Hugo","email":"gagehugo@gmail.com","username":"ghugo"},"change_message_id":"f269396dcd9e360f9ad0878889ced0d482e3b0fa","unresolved":false,"context_lines":[{"line_number":777,"context_line":"        self.assertNotIn(project1[\u0027id\u0027], pids)"},{"line_number":778,"context_line":""},{"line_number":779,"context_line":"    def test_list_projects_filtering_multiple_tags_filters(self):"},{"line_number":780,"context_line":"        \"\"\"Call ``GET /projects?tags\u003d{tags}\u0026tags-any\u003d{tags}``.\"\"\""},{"line_number":781,"context_line":"        project, tags \u003d self._create_project_and_tags(num_of_tags\u003d2)"},{"line_number":782,"context_line":"        project1, tags1 \u003d self._create_project_and_tags(num_of_tags\u003d2)"},{"line_number":783,"context_line":"        url \u003d \u0027/projects?tags\u003d%(value1)s\u0026not-tags\u003d%(value2)s\u0027"}],"source_content_type":"text/x-python","patch_set":3,"id":"df7087c5_23018db0","line":780,"range":{"start_line":780,"start_character":44,"end_line":780,"end_character":52},"updated":"2018-03-19 23:18:24.000000000","message":"change to \u0027not-tags\u0027","commit_id":"20bd3f1ccd348bed0dfe83ac673af6986d757286"}]}
