175 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
		
		
			
		
	
	
			175 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
|  | from __future__ import unicode_literals | ||
|  | 
 | ||
|  | import pytest | ||
|  | 
 | ||
|  | from moto.rds2.utils import ( | ||
|  |     FilterDef, | ||
|  |     apply_filter, | ||
|  |     merge_filters, | ||
|  |     filters_from_querystring, | ||
|  |     validate_filters, | ||
|  | ) | ||
|  | 
 | ||
|  | 
 | ||
|  | class TestFilterValidation(object): | ||
|  |     @classmethod | ||
|  |     def setup_class(cls): | ||
|  |         cls.filter_defs = { | ||
|  |             "not-implemented": FilterDef(None, ""), | ||
|  |             "identifier": FilterDef(["identifier"], "Object Identifiers"), | ||
|  |         } | ||
|  | 
 | ||
|  |     def test_unrecognized_filter_raises_exception(self): | ||
|  |         filters = {"invalid-filter-name": ["test-value"]} | ||
|  |         with pytest.raises(KeyError) as ex: | ||
|  |             validate_filters(filters, self.filter_defs) | ||
|  |         assert "Unrecognized filter name: invalid-filter-name" in str(ex) | ||
|  | 
 | ||
|  |     def test_empty_filter_values_raises_exception(self): | ||
|  |         filters = {"identifier": []} | ||
|  |         with pytest.raises(ValueError) as ex: | ||
|  |             validate_filters(filters, self.filter_defs) | ||
|  |         assert "Object Identifiers must not be empty" in str(ex) | ||
|  | 
 | ||
|  |     def test_unimplemented_filter_raises_exception(self): | ||
|  |         filters = {"not-implemented": ["test-value"]} | ||
|  |         with pytest.raises(NotImplementedError): | ||
|  |             validate_filters(filters, self.filter_defs) | ||
|  | 
 | ||
|  | 
 | ||
|  | class Resource(object): | ||
|  |     def __init__(self, identifier, **kwargs): | ||
|  |         self.identifier = identifier | ||
|  |         self.__dict__.update(kwargs) | ||
|  | 
 | ||
|  | 
 | ||
|  | class TestResourceFiltering(object): | ||
|  |     @classmethod | ||
|  |     def setup_class(cls): | ||
|  |         cls.filter_defs = { | ||
|  |             "identifier": FilterDef(["identifier"], "Object Identifiers"), | ||
|  |             "nested-resource": FilterDef(["nested.identifier"], "Nested Identifiers"), | ||
|  |             "common-attr": FilterDef(["common_attr"], ""), | ||
|  |             "multiple-attrs": FilterDef(["common_attr", "uncommon_attr"], ""), | ||
|  |         } | ||
|  |         cls.resources = { | ||
|  |             "identifier-0": Resource("identifier-0"), | ||
|  |             "identifier-1": Resource("identifier-1", common_attr="common"), | ||
|  |             "identifier-2": Resource("identifier-2"), | ||
|  |             "identifier-3": Resource("identifier-3", nested=Resource("nested-id-1")), | ||
|  |             "identifier-4": Resource("identifier-4", common_attr="common"), | ||
|  |             "identifier-5": Resource("identifier-5", uncommon_attr="common"), | ||
|  |         } | ||
|  | 
 | ||
|  |     def test_filtering_on_nested_attribute(self): | ||
|  |         filters = {"nested-resource": ["nested-id-1"]} | ||
|  |         filtered_resources = apply_filter(self.resources, filters, self.filter_defs) | ||
|  |         filtered_resources.should.have.length_of(1) | ||
|  |         filtered_resources.should.have.key("identifier-3") | ||
|  | 
 | ||
|  |     def test_filtering_on_common_attribute(self): | ||
|  |         filters = {"common-attr": ["common"]} | ||
|  |         filtered_resources = apply_filter(self.resources, filters, self.filter_defs) | ||
|  |         filtered_resources.should.have.length_of(2) | ||
|  |         filtered_resources.should.have.key("identifier-1") | ||
|  |         filtered_resources.should.have.key("identifier-4") | ||
|  | 
 | ||
|  |     def test_filtering_on_multiple_attributes(self): | ||
|  |         filters = {"multiple-attrs": ["common"]} | ||
|  |         filtered_resources = apply_filter(self.resources, filters, self.filter_defs) | ||
|  |         filtered_resources.should.have.length_of(3) | ||
|  |         filtered_resources.should.have.key("identifier-1") | ||
|  |         filtered_resources.should.have.key("identifier-4") | ||
|  |         filtered_resources.should.have.key("identifier-5") | ||
|  | 
 | ||
|  |     def test_filters_with_multiple_values(self): | ||
|  |         filters = {"identifier": ["identifier-0", "identifier-3", "identifier-5"]} | ||
|  |         filtered_resources = apply_filter(self.resources, filters, self.filter_defs) | ||
|  |         filtered_resources.should.have.length_of(3) | ||
|  |         filtered_resources.should.have.key("identifier-0") | ||
|  |         filtered_resources.should.have.key("identifier-3") | ||
|  |         filtered_resources.should.have.key("identifier-5") | ||
|  | 
 | ||
|  |     def test_multiple_filters(self): | ||
|  |         filters = { | ||
|  |             "identifier": ["identifier-1", "identifier-3", "identifier-5"], | ||
|  |             "common-attr": ["common"], | ||
|  |             "multiple-attrs": ["common"], | ||
|  |         } | ||
|  |         filtered_resources = apply_filter(self.resources, filters, self.filter_defs) | ||
|  |         filtered_resources.should.have.length_of(1) | ||
|  |         filtered_resources.should.have.key("identifier-1") | ||
|  | 
 | ||
|  | 
 | ||
|  | class TestMergingFilters(object): | ||
|  |     def test_when_filters_to_update_is_none(self): | ||
|  |         filters_to_update = {"filter-name": ["value1"]} | ||
|  |         merged = merge_filters(filters_to_update, None) | ||
|  |         assert merged == filters_to_update | ||
|  | 
 | ||
|  |     def test_when_filters_to_merge_is_none(self): | ||
|  |         filters_to_merge = {"filter-name": ["value1"]} | ||
|  |         merged = merge_filters(None, filters_to_merge) | ||
|  |         assert merged == filters_to_merge | ||
|  | 
 | ||
|  |     def test_when_both_filters_are_none(self): | ||
|  |         merged = merge_filters(None, None) | ||
|  |         assert merged == {} | ||
|  | 
 | ||
|  |     def test_values_are_merged(self): | ||
|  |         filters_to_update = {"filter-name": ["value1"]} | ||
|  |         filters_to_merge = {"filter-name": ["value2"]} | ||
|  |         merged = merge_filters(filters_to_update, filters_to_merge) | ||
|  |         assert merged == {"filter-name": ["value1", "value2"]} | ||
|  | 
 | ||
|  |     def test_complex_merge(self): | ||
|  |         filters_to_update = { | ||
|  |             "filter-name-1": ["value1"], | ||
|  |             "filter-name-2": ["value1", "value2"], | ||
|  |             "filter-name-3": ["value1"], | ||
|  |         } | ||
|  |         filters_to_merge = { | ||
|  |             "filter-name-1": ["value2"], | ||
|  |             "filter-name-3": ["value2"], | ||
|  |             "filter-name-4": ["value1", "value2"], | ||
|  |         } | ||
|  |         merged = merge_filters(filters_to_update, filters_to_merge) | ||
|  |         assert len(merged.keys()) == 4 | ||
|  |         for key in merged.keys(): | ||
|  |             assert merged[key] == ["value1", "value2"] | ||
|  | 
 | ||
|  | 
 | ||
|  | class TestParsingFiltersFromQuerystring(object): | ||
|  |     def test_parse_empty_list(self): | ||
|  |         # The AWS query protocol serializes empty lists as an empty string. | ||
|  |         querystring = { | ||
|  |             "Filters.Filter.1.Name": ["empty-filter"], | ||
|  |             "Filters.Filter.1.Value.1": [""], | ||
|  |         } | ||
|  |         filters = filters_from_querystring(querystring) | ||
|  |         assert filters == {"empty-filter": []} | ||
|  | 
 | ||
|  |     def test_multiple_values(self): | ||
|  |         querystring = { | ||
|  |             "Filters.Filter.1.Name": ["multi-value"], | ||
|  |             "Filters.Filter.1.Value.1": ["value1"], | ||
|  |             "Filters.Filter.1.Value.2": ["value2"], | ||
|  |         } | ||
|  |         filters = filters_from_querystring(querystring) | ||
|  |         values = filters["multi-value"] | ||
|  |         assert len(values) == 2 | ||
|  |         assert "value1" in values | ||
|  |         assert "value2" in values | ||
|  | 
 | ||
|  |     def test_multiple_filters(self): | ||
|  |         querystring = { | ||
|  |             "Filters.Filter.1.Name": ["filter-1"], | ||
|  |             "Filters.Filter.1.Value.1": ["value1"], | ||
|  |             "Filters.Filter.2.Name": ["filter-2"], | ||
|  |             "Filters.Filter.2.Value.1": ["value2"], | ||
|  |         } | ||
|  |         filters = filters_from_querystring(querystring) | ||
|  |         assert len(filters.keys()) == 2 | ||
|  |         assert filters["filter-1"] == ["value1"] | ||
|  |         assert filters["filter-2"] == ["value2"] |