Beispiel #1
0
 def test_is_query_inbox(self):
     assert parse_search_query("is:for_review") == [
         SearchFilter(key=SearchKey(name="for_review"),
                      operator="=",
                      value=SearchValue(True))
     ]
Beispiel #2
0
 def test_no_converter(self):
     search_val = SearchValue("me")
     filters = [SearchFilter(SearchKey("something"), "=", search_val)]
     filters = convert_query_values(filters, [self.project], self.user,
                                    None)
     assert filters[0].value.raw_value == search_val.raw_value
def test_search_value(raw, result):
    search_value = SearchValue(raw)
    assert search_value.value == result
    def node_visitor(token):
        if token["type"] == "spaces":
            return None

        if token["type"] == "filter":
            # Filters with an invalid reason raises to signal to the test
            # runner that we should expect this exception
            if token.get("invalid"):
                raise InvalidSearchQuery(token["invalid"]["reason"])

            # Transform the operator to match for list values
            if token["value"]["type"] in ["valueTextList", "valueNumberList"]:
                operator = "NOT IN" if token["negated"] else "IN"
            else:
                # Negate the operator if the filter is negated to match
                operator = token["operator"] or "="
                operator = f"!{operator}" if token["negated"] else operator

            key = node_visitor(token["key"])
            value = node_visitor(token["value"])

            if token["filter"] == "boolean" and token["negated"]:
                operator = "="
                value = SearchValue(raw_value=1 if value.raw_value == 0 else 0)

            return SearchFilter(key, operator, value)

        if token["type"] == "keySimple":
            return SearchKey(name=token["value"])

        if token["type"] == "keyExplicitTag":
            return SearchKey(name=f"tags[{token['key']['value']}]")

        if token["type"] == "keyAggregate":
            name = node_visitor(token["name"]).name
            # Consistent join aggregate function parameters
            args = ", ".join(arg["value"]["value"] for arg in token["args"]["args"])
            return AggregateKey(name=f"{name}({args})")

        if token["type"] == "valueText":
            # Noramlize values by removing the escaped quotes
            value = token["value"].replace('\\"', '"')
            return SearchValue(raw_value=value)

        if token["type"] == "valueNumber":
            return SearchValue(raw_value=parse_numeric_value(token["value"], token["unit"]))

        if token["type"] == "valueTextList":
            return SearchValue(raw_value=[item["value"]["value"] for item in token["items"]])

        if token["type"] == "valueNumberList":
            return SearchValue(raw_value=[item["value"]["rawValue"] for item in token["items"]])

        if token["type"] == "valueIso8601Date":
            return SearchValue(raw_value=parse_datetime_string(token["value"]))

        if token["type"] == "valueDuration":
            return SearchValue(raw_value=parse_duration(token["value"], token["unit"]))

        if token["type"] == "valueRelativeDate":
            return SearchValue(raw_value=parse_duration(token["value"], token["unit"]))

        if token["type"] == "valueBoolean":
            return SearchValue(raw_value=int(token["value"]))

        if token["type"] == "freeText":
            if token["quoted"]:
                # Normalize quotes
                value = token["value"].replace('\\"', '"')
            else:
                # Normalize spacing
                value = token["value"].strip(" ")

            if value == "":
                return None

            return SearchFilter(
                key=SearchKey(name="message"),
                operator="=",
                value=SearchValue(raw_value=value),
            )
Beispiel #5
0
    def test_raw_search_anywhere(self):
        assert parse_search_query(
            'hello what user.email:[email protected] where release:1.2.1 when'
        ) == [
            SearchFilter(
                key=SearchKey(name='message'),
                operator='=',
                value=SearchValue(raw_value='hello what'),
            ),
            SearchFilter(
                key=SearchKey(name='user.email'),
                operator="=",
                value=SearchValue(raw_value='*****@*****.**'),
            ),
            SearchFilter(
                key=SearchKey(name='message'),
                operator='=',
                value=SearchValue(raw_value='where'),
            ),
            SearchFilter(
                key=SearchKey(name='release'),
                operator="=",
                value=SearchValue(raw_value='1.2.1'),
            ),
            SearchFilter(
                key=SearchKey(name='message'),
                operator='=',
                value=SearchValue(raw_value='when'),
            ),
        ]

        assert parse_search_query('hello') == [
            SearchFilter(
                key=SearchKey(name='message'),
                operator='=',
                value=SearchValue(raw_value='hello'),
            ),
        ]

        assert parse_search_query('  hello  ') == [
            SearchFilter(
                key=SearchKey(name='message'),
                operator='=',
                value=SearchValue(raw_value='hello'),
            ),
        ]

        assert parse_search_query('  hello   there') == [
            SearchFilter(
                key=SearchKey(name='message'),
                operator='=',
                value=SearchValue(raw_value='hello   there'),
            ),
        ]

        assert parse_search_query('  hello   there:bye') == [
            SearchFilter(
                key=SearchKey(name='message'),
                operator='=',
                value=SearchValue(raw_value='hello'),
            ),
            SearchFilter(
                key=SearchKey(name='there'),
                operator='=',
                value=SearchValue(raw_value='bye'),
            ),
        ]
Beispiel #6
0
    def test_multiple_statements(self):
        assert parse_search_query(
            'user.email:[email protected] OR user.email:[email protected] OR user.email:[email protected]'
        ) == [
            SearchBoolean(left_term=self.term1,
                          operator='OR',
                          right_term=SearchBoolean(left_term=self.term2,
                                                   operator='OR',
                                                   right_term=self.term3))
        ]

        assert parse_search_query(
            'user.email:[email protected] AND user.email:[email protected] AND user.email:[email protected]'
        ) == [
            SearchBoolean(left_term=self.term1,
                          operator='AND',
                          right_term=SearchBoolean(left_term=self.term2,
                                                   operator='AND',
                                                   right_term=self.term3))
        ]

        term4 = SearchFilter(
            key=SearchKey(name='user.email'),
            operator="=",
            value=SearchValue(raw_value='*****@*****.**'),
        )

        # longer even number of terms
        assert parse_search_query(
            'user.email:[email protected] AND user.email:[email protected] OR user.email:[email protected] AND user.email:[email protected]'
        ) == [
            SearchBoolean(left_term=SearchBoolean(left_term=self.term1,
                                                  operator='AND',
                                                  right_term=self.term2),
                          operator='OR',
                          right_term=SearchBoolean(left_term=self.term3,
                                                   operator='AND',
                                                   right_term=term4))
        ]

        term5 = SearchFilter(
            key=SearchKey(name='user.email'),
            operator="=",
            value=SearchValue(raw_value='*****@*****.**'),
        )

        # longer odd number of terms
        assert parse_search_query(
            'user.email:[email protected] AND user.email:[email protected] OR user.email:[email protected] AND user.email:[email protected] AND user.email:[email protected]'
        ) == [
            SearchBoolean(left_term=SearchBoolean(left_term=self.term1,
                                                  operator='AND',
                                                  right_term=self.term2),
                          operator='OR',
                          right_term=SearchBoolean(left_term=self.term3,
                                                   operator='AND',
                                                   right_term=SearchBoolean(
                                                       left_term=term4,
                                                       operator='AND',
                                                       right_term=term5)))
        ]

        # absurdly long
        assert parse_search_query(
            'user.email:[email protected] AND user.email:[email protected] OR user.email:[email protected] AND user.email:[email protected] AND user.email:[email protected] OR user.email:[email protected] AND user.email:[email protected] OR user.email:[email protected] AND user.email:[email protected] AND user.email:[email protected]'
        ) == [
            SearchBoolean(
                left_term=SearchBoolean(left_term=self.term1,
                                        operator='AND',
                                        right_term=self.term2),
                operator='OR',
                right_term=SearchBoolean(
                    left_term=SearchBoolean(left_term=self.term3,
                                            operator='AND',
                                            right_term=SearchBoolean(
                                                left_term=term4,
                                                operator='AND',
                                                right_term=term5)),
                    operator='OR',
                    right_term=SearchBoolean(
                        left_term=SearchBoolean(left_term=self.term1,
                                                operator='AND',
                                                right_term=self.term2),
                        operator='OR',
                        right_term=SearchBoolean(left_term=self.term3,
                                                 operator='AND',
                                                 right_term=SearchBoolean(
                                                     left_term=term4,
                                                     operator='AND',
                                                     right_term=term5)))))
        ]
Beispiel #7
0
    def test_quotes_filtered_on_raw(self):
        # Enclose the full raw query? Strip it.
        assert parse_search_query('thinger:unknown "what is this?"') == [
            SearchFilter(
                key=SearchKey(name='thinger'),
                operator='=',
                value=SearchValue(raw_value='unknown'),
            ),
            SearchFilter(
                key=SearchKey(name='message'),
                operator='=',
                value=SearchValue(raw_value='what is this?'),
            ),
        ]

        # Enclose the full query? Strip it and the whole query is raw.
        assert parse_search_query('"thinger:unknown what is this?"') == [
            SearchFilter(
                key=SearchKey(name='message'),
                operator='=',
                value=SearchValue(raw_value='thinger:unknown what is this?'),
            ),
        ]

        # Allow a single quotation at end
        assert parse_search_query('end"') == [
            SearchFilter(
                key=SearchKey(name='message'),
                operator='=',
                value=SearchValue(raw_value='end"'),
            ),
        ]

        # Allow a single quotation at beginning
        assert parse_search_query('"beginning') == [
            SearchFilter(
                key=SearchKey(name='message'),
                operator='=',
                value=SearchValue(raw_value='"beginning'),
            ),
        ]

        # Allow a single quotation
        assert parse_search_query('"') == [
            SearchFilter(
                key=SearchKey(name='message'),
                operator='=',
                value=SearchValue(raw_value='"'),
            ),
        ]

        # Empty quotations become a dropped term
        assert parse_search_query('""') == []

        # Allow a search for space
        assert parse_search_query('" "') == [
            SearchFilter(
                key=SearchKey(name='message'),
                operator='=',
                value=SearchValue(raw_value=' '),
            ),
        ]

        # Strip in a balanced manner
        assert parse_search_query('""woof"') == [
            SearchFilter(
                key=SearchKey(name='message'),
                operator='=',
                value=SearchValue(raw_value='woof"'),
            ),
        ]

        # Don't try this at home kids
        assert parse_search_query('"""""""""') == [
            SearchFilter(
                key=SearchKey(name='message'),
                operator='=',
                value=SearchValue(raw_value='"'),
            ),
        ]
Beispiel #8
0
 def _build_search_filter(self, key_name, operator, value):
     return SearchFilter(
         key=SearchKey(name=key_name),
         operator=operator,
         value=SearchValue(raw_value=value),
     )
Beispiel #9
0
 def test_tab_within_quote(self):
     assert parse_search_query('release:"a\trelease"') == [
         SearchFilter(key=SearchKey(name='release'),
                      operator='=',
                      value=SearchValue(raw_value='a\trelease')),
     ]
Beispiel #10
0
 def test_negated_duration_on_non_duration_field(self):
     assert parse_search_query("!user.id:500s") == [
         SearchFilter(key=SearchKey(name="user.id"),
                      operator="!=",
                      value=SearchValue(raw_value="500s"))
     ]
Beispiel #11
0
    def test_simple_in(self):
        assert parse_search_query(
            "user.email:[[email protected]] test:[hello]") == [
                SearchFilter(
                    key=SearchKey(name="user.email"),
                    operator="IN",
                    value=SearchValue(raw_value=["*****@*****.**"]),
                ),
                SearchFilter(
                    key=SearchKey(name="test"),
                    operator="IN",
                    value=SearchValue(raw_value=["hello"]),
                ),
            ]
        assert parse_search_query(
            "user.email:[[email protected],[email protected],[email protected]] test:[hello]"
        ) == [
            SearchFilter(
                key=SearchKey(name="user.email"),
                operator="IN",
                value=SearchValue(raw_value=[
                    "*****@*****.**", "*****@*****.**", "*****@*****.**"
                ]),
            ),
            SearchFilter(
                key=SearchKey(name="test"),
                operator="IN",
                value=SearchValue(raw_value=["hello"]),
            ),
        ]
        assert parse_search_query(
            "!user.email:[[email protected], [email protected],     [email protected]] test:[hello]"
        ) == [
            SearchFilter(
                key=SearchKey(name="user.email"),
                operator="NOT IN",
                value=SearchValue(raw_value=[
                    "*****@*****.**", "*****@*****.**", "*****@*****.**"
                ]),
            ),
            SearchFilter(
                key=SearchKey(name="test"),
                operator="IN",
                value=SearchValue(raw_value=["hello"]),
            ),
        ]
        # Make sure brackets still work in normal values
        assert parse_search_query("test:h[e]llo]") == [
            SearchFilter(
                key=SearchKey(name="test"),
                operator="=",
                value=SearchValue(raw_value="h[e]llo]"),
            ),
        ]
        assert parse_search_query("test:[h[e]llo") == [
            SearchFilter(
                key=SearchKey(name="test"),
                operator="=",
                value=SearchValue(raw_value="[h[e]llo"),
            ),
        ]
        assert parse_search_query('test:"[h]"') == [
            SearchFilter(
                key=SearchKey(name="test"),
                operator="=",
                value=SearchValue(raw_value="[h]"),
            ),
        ]
        assert parse_search_query("test:[h]*") == [
            SearchFilter(
                key=SearchKey(name="test"),
                operator="=",
                value=SearchValue(raw_value="[h]*"),
            ),
        ]
        assert parse_search_query("test:[h e]") == [
            SearchFilter(
                key=SearchKey(name="test"),
                operator="=",
                value=SearchValue(raw_value="[h"),
            ),
            SearchFilter(
                key=SearchKey(name="message"),
                operator="=",
                value=SearchValue(raw_value="e]"),
            ),
        ]
        assert parse_search_query("test:[]") == [
            SearchFilter(
                key=SearchKey(name="test"),
                operator="=",
                value=SearchValue(raw_value="[]"),
            ),
        ]
        assert parse_search_query('user.email:[[email protected], "hi", 1]') == [
            SearchFilter(
                key=SearchKey(name="user.email"),
                operator="IN",
                value=SearchValue(raw_value=["*****@*****.**", "hi", "1"]),
            )
        ]
        assert parse_search_query('user.email:[[email protected], "hi", 1.0]') == [
            SearchFilter(
                key=SearchKey(name="user.email"),
                operator="IN",
                value=SearchValue(raw_value=["*****@*****.**", "hi", "1.0"]),
            )
        ]
        assert parse_search_query("test:[[h]]") == [
            SearchFilter(
                key=SearchKey(name="test"),
                operator="IN",
                value=SearchValue(raw_value=["[h]"]),
            ),
        ]
        assert parse_search_query("test:[a, [h]]") == [
            SearchFilter(
                key=SearchKey(name="test"),
                operator="IN",
                value=SearchValue(raw_value=["a", "[h]"]),
            ),
        ]

        assert parse_search_query(
            "user.email:[[email protected]]user.email:[email protected]") == [
                SearchFilter(
                    key=SearchKey(name="user.email"),
                    operator="=",
                    value=SearchValue(
                        raw_value="[[email protected]]user.email:[email protected]"),
                ),
            ]
Beispiel #12
0
    def test_parse_search_query_weird_values(self):
        # quotes within quotes
        assert parse_search_query('release:"a"thing""') == [
            SearchFilter(
                key=SearchKey(name='release'),
                operator='=',
                value=SearchValue(raw_value='a"thing"'),
            ),
        ]

        # newline within quote
        assert parse_search_query('release:"a\nrelease"') == [
            SearchFilter(
                key=SearchKey(name='release'),
                operator='=',
                value=SearchValue(raw_value='a\nrelease')
            ),
        ]
        # newline outside quote
        with self.assertRaises(IncompleteParseError):
            parse_search_query('release:a\nrelease')

        # tab within quote
        assert parse_search_query('release:"a\trelease"') == [
            SearchFilter(
                key=SearchKey(name='release'),
                operator='=',
                value=SearchValue(raw_value='a\trelease')
            ),
        ]
        # tab outside quote
        assert parse_search_query('release:a\trelease') == [
            SearchFilter(
                key=SearchKey(name='release'),
                operator='=',
                value=SearchValue(raw_value='a'),
            ),
            SearchFilter(
                key=SearchKey(name='message'),
                operator='=',
                value=SearchValue(raw_value='\trelease')
            ),
        ]

        # escaped quotes
        assert parse_search_query('release:"a\"thing\""') == [
            SearchFilter(
                key=SearchKey(name='release'),
                operator='=',
                value=SearchValue(raw_value='a"thing"')
            ),
        ]
        assert parse_search_query('release:"a\"\"release"') == [
            SearchFilter(
                key=SearchKey(name='release'),
                operator='=',
                value=SearchValue(raw_value='a""release')
            ),
        ]

        # poorly escaped quotes
        assert parse_search_query('release:"a release\"') == [
            SearchFilter(
                key=SearchKey(name='release'),
                operator='=',
                value=SearchValue(raw_value='a release')
            ),
        ]
        assert parse_search_query('release:\"a release "') == [
            SearchFilter(
                key=SearchKey(name='release'),
                operator='=',
                value=SearchValue(raw_value='a release ')
            ),
        ]
Beispiel #13
0
 def convert_search_filter(search_filter):
     if search_filter.key.name in value_converters:
         converter = value_converters[search_filter.key.name]
         new_value = converter(search_filter.value.raw_value, projects, user)
         search_filter = search_filter._replace(value=SearchValue(new_value))
     return search_filter