Пример #1
0
    def test_can_insert_keys(self):
        default_values = {}
        keys = {}

        for x in range(3):
            key_name = 'key.%d' % x
            keys[key_name] = {'category': 'cat.%d' % x}

            description = 'description %s' % key_name
            value = 'value %s' % key_name
            default_values[key_name] = {
                'value': value,
                'description': description
            }

        Key.insert_keys(self.db, keys, default_values)

        loaded_keys = self.db.query(Key).all()

        expect(loaded_keys).to_length(3)

        for key in loaded_keys:
            expect(keys).to_include(key.name)
            expect(key.to_dict()).to_equal(keys[key.name]['key'].to_dict())
            expect(key.category.name).to_be_like(keys[key.name]['category'])
            expect(keys[key.name]['default_value_description']).to_equal(
                'description %s' % key.name)
            expect(keys[key.name]['default_value']).to_equal('value %s' %
                                                             key.name)
Пример #2
0
    def test_can_insert_keys(self):
        default_values = {}
        keys = {}

        for x in range(3):
            key_name = 'key.%d' % x
            keys[key_name] = {'category': 'cat.%d' % x}

            description = 'description %s' % key_name
            value = 'value %s' % key_name
            default_values[key_name] = {
                'value': value, 'description': description
            }

        Key.insert_keys(self.db, keys, default_values)

        loaded_keys = self.db.query(Key).all()

        expect(loaded_keys).to_length(3)

        for key in loaded_keys:
            expect(keys).to_include(key.name)
            expect(key.to_dict()).to_equal(keys[key.name]['key'].to_dict())
            expect(key.category.name).to_be_like(keys[key.name]['category'])
            expect(keys[key.name]['default_value_description']).to_equal(
                'description %s' % key.name
            )
            expect(keys[key.name]['default_value']).to_equal(
                'value %s' % key.name
            )
Пример #3
0
    def test_can_update_keys(self):
        default_values = {
            'some.random.key': {
                'value': 100,
                'description': 'my description'
            }
        }

        # Insert key and category

        keys = {'some.random.key': {'category': 'SEO'}}

        Key.insert_keys(self.db, keys, default_values)

        loaded_key = self.db.query(Key).one()

        expect(keys).to_include(loaded_key.name)
        expect(loaded_key.name).to_equal('some.random.key')
        expect(loaded_key.category.name).to_equal('SEO')

        # Update category

        keys = {'some.random.key': {'category': 'HTTP'}}

        Key.insert_keys(self.db, keys, default_values)

        loaded_key = self.db.query(Key).one()

        expect(keys).to_include(loaded_key.name)
        expect(loaded_key.name).to_equal('some.random.key')
        expect(loaded_key.category.name).to_equal('HTTP')
Пример #4
0
    def test_can_update_keys(self):
        default_values = {'some.random.key': {
            'value': 100, 'description': 'my description'}
        }

        # Insert key and category

        keys = {'some.random.key': {'category': 'SEO'}}

        Key.insert_keys(self.db, keys, default_values)

        loaded_key = self.db.query(Key).one()

        expect(keys).to_include(loaded_key.name)
        expect(loaded_key.name).to_equal('some.random.key')
        expect(loaded_key.category.name).to_equal('SEO')

        # Update category

        keys = {'some.random.key': {'category': 'HTTP'}}

        Key.insert_keys(self.db, keys, default_values)

        loaded_key = self.db.query(Key).one()

        expect(keys).to_include(loaded_key.name)
        expect(loaded_key.name).to_equal('some.random.key')
        expect(loaded_key.category.name).to_equal('HTTP')
Пример #5
0
    def initialize(self):
        self.uuid = uuid4().hex
        self.working_url = None
        self.domain_name = None
        self.last_ping = None
        self.last_update_pages_score = None

        authnz_wrapper_class = self.load_authnz_wrapper()
        if authnz_wrapper_class:
            self.authnz_wrapper = authnz_wrapper_class(self.config)
        else:
            self.authnz_wrapper = None

        self.facters = self._load_facters()
        self.validators = self._load_validators()
        self.error_handlers = [handler(self.config) for handler in self.load_error_handlers()]

        self.connect_sqlalchemy()

        self.search_provider = self.load_search_provider()(
            config=self.config,
            db=self.db,
            authnz_wrapper=self.authnz_wrapper
        )

        self.connect_to_redis()
        self.start_otto()

        self.fact_definitions = {}
        self.violation_definitions = {}

        self.default_violations_values = {}

        for facter in self.facters:
            self.fact_definitions.update(facter.get_fact_definitions())

        Key.insert_keys(self.db, self.fact_definitions)

        for validator in self.validators:
            self.violation_definitions.update(validator.get_violation_definitions())

            self.default_violations_values.update(
                validator.get_default_violations_values(self.config)
            )

        Key.insert_keys(
            self.db, self.violation_definitions, self.default_violations_values
        )

        self.configure_material_girl()

        DomainsViolationsPrefs.insert_default_violations_values_for_all_domains(
            self.db,
            self.default_violations_values,
            self.violation_definitions,
            self.cache
        )

        self.load_all_domains_violations_prefs()
Пример #6
0
    def test_can_get_or_create(self):
        # Create
        key1 = Key.get_or_create(self.db, 'some.random.key')
        expect(key1.name).to_equal('some.random.key')

        # Get
        key2 = Key.get_or_create(self.db, 'some.random.key')
        expect(key1.id).to_equal(key2.id)
Пример #7
0
    def test_can_get_or_create(self):
        # Create
        key1 = Key.get_or_create(self.db, 'some.random.key')
        expect(key1.name).to_equal('some.random.key')

        # Get
        key2 = Key.get_or_create(self.db, 'some.random.key')
        expect(key1.id).to_equal(key2.id)
Пример #8
0
    def initialize(self):
        self.uuid = uuid4().hex
        self.working_url = None
        self.domain_name = None
        self.last_ping = None

        authnz_wrapper_class = self.load_authnz_wrapper()
        if authnz_wrapper_class:
            self.authnz_wrapper = authnz_wrapper_class(self.config)
        else:
            self.authnz_wrapper = None

        self.facters = self._load_facters()
        self.validators = self._load_validators()
        self.error_handlers = [
            handler(self.config) for handler in self.load_error_handlers()
        ]

        self.connect_sqlalchemy()

        self.search_provider = self.load_search_provider()(
            config=self.config, db=self.db, authnz_wrapper=self.authnz_wrapper)

        self.connect_to_redis()
        self.start_otto()

        self.fact_definitions = {}
        self.violation_definitions = {}

        self.default_violations_values = {}

        for facter in self.facters:
            self.fact_definitions.update(facter.get_fact_definitions())

        Key.insert_keys(self.db, self.fact_definitions)

        for validator in self.validators:
            self.violation_definitions.update(
                validator.get_violation_definitions())

            self.default_violations_values.update(
                validator.get_default_violations_values(self.config))

        Key.insert_keys(self.db, self.violation_definitions,
                        self.default_violations_values)

        self.configure_material_girl()

        DomainsViolationsPrefs.insert_default_violations_values_for_all_domains(
            self.db, self.default_violations_values,
            self.violation_definitions, self.cache)

        self.load_all_domains_violations_prefs()
Пример #9
0
    def test_can_get_domain_top_category_violations(self):
        domain1 = DomainFactory.create()
        domain2 = DomainFactory.create()

        page1 = PageFactory.create(domain=domain1)
        page2 = PageFactory.create(domain=domain1)
        page3 = PageFactory.create(domain=domain2)

        ReviewFactory.create(domain=domain1,
                             page=page1,
                             is_active=True,
                             number_of_violations=5)
        ReviewFactory.create(domain=domain1,
                             page=page2,
                             is_active=True,
                             number_of_violations=7)
        ReviewFactory.create(domain=domain2,
                             page=page3,
                             is_active=True,
                             number_of_violations=9)

        self.server.application.violation_definitions = {
            'key.%s' % i: {
                'title':
                'title.%s' % i,
                'category':
                'category.%s' % (i % 3),
                'key':
                Key.get_or_create(self.db, 'key.%d' % i,
                                  'category.%d' % (i % 3))
            }
            for i in range(9)
        }

        key = Key.get_by_name(self.db, 'key.0')

        response = yield self.authenticated_fetch(
            '/domains/%s/violations/%d/' % (domain1.name, key.category_id))

        expect(response.code).to_equal(200)

        domain_top_category = loads(response.body)

        expect(domain_top_category).to_length(5)
        expect(domain_top_category.keys()).to_be_like([
            'violations', 'domainId', 'categoryId', 'domainURL', 'domainName'
        ])
        expect(domain_top_category['violations']).to_length(3)

        counts = map(lambda v: v['count'], domain_top_category['violations'])
        expect(counts).to_be_like([2, 1, 1])
Пример #10
0
    def _adjust_kwargs(cls, **kwargs):
        if 'page' in kwargs:
            kwargs['domain'] = kwargs['page'].domain

        if 'page' in kwargs and 'uuid' in kwargs:
            kwargs['page'].last_review_uuid = kwargs['uuid']

        if 'number_of_violations' in kwargs:
            number_of_violations = kwargs['number_of_violations']
            del kwargs['number_of_violations']

            if 'page' in kwargs:
                kwargs['page'].violations_count = number_of_violations

            violations = []
            for i in range(number_of_violations):
                db = cls.FACTORY_SESSION
                key = Key.get_or_create(db, "violation.%d" % i)
                violations.append(
                    Violation(
                        key=key,
                        value="value %d" % i,
                        points=i,
                        domain=kwargs['page'].domain
                    )
                )

            kwargs['violations'] = violations

        return kwargs
Пример #11
0
    def test_can_get_domain_grouped_violations(self):
        domain1 = DomainFactory.create()
        domain2 = DomainFactory.create()

        page1 = PageFactory.create(domain=domain1)
        page2 = PageFactory.create(domain=domain1)
        page3 = PageFactory.create(domain=domain2)

        ReviewFactory.create(domain=domain1, page=page1, is_active=True, number_of_violations=5)
        ReviewFactory.create(domain=domain1, page=page2, is_active=True, number_of_violations=7)
        ReviewFactory.create(domain=domain2, page=page3, is_active=True, number_of_violations=9)

        self.server.application.violation_definitions = {
            'key.%s' % i: {
                'title': 'title.%s' % i,
                'category': 'category.%s' % (i % 3),
                'key': Key.get_or_create(self.db, 'key.%d' % i, 'category.%d' % (i % 3))
            } for i in xrange(9)
        }

        response = yield self.http_client.fetch(
            self.get_url('/domains/%s/violations' % domain1.name)
        )

        expect(response.code).to_equal(200)

        domain_violations = loads(response.body)

        expect(domain_violations).to_length(5)
        expect(domain_violations.keys()).to_be_like(['domainName', 'violations', 'total', 'domainURL', 'domainId'])
        expect(domain_violations['total']).to_equal(12)
        expect(domain_violations['violations']).to_length(3)

        counts = map(lambda v: v['count'], domain_violations['violations'])
        expect(counts).to_be_like([5, 4, 3])
Пример #12
0
    def update_by_user(cls, db, user, data):
        from holmes.models import Key

        if not user or not data:
            return

        for item in data:
            if 'key' not in item or 'is_active' not in item:
                continue

            key = Key.get_by_name(db, item.get('key'))
            if not key:
                continue

            is_active = item.get('is_active', True)

            db \
                .query(UsersViolationsPrefs) \
                .filter(
                    UsersViolationsPrefs.user_id == user.id,
                    UsersViolationsPrefs.key_id == key.id
                ) \
                .update(
                    {'is_active': is_active}
                )

        db.flush()
Пример #13
0
    def test_get_by_name(self):
        key = KeyFactory.create(name='some.random.key')

        loadded_key = Key.get_by_name(self.db, 'some.random.key')

        expect(key).to_equal(loadded_key)
        expect(loadded_key.name).to_equal('some.random.key')
Пример #14
0
    def test_can_insert_default_violations_values_for_all_domains(self):
        DomainsViolationsPrefsFactory.create(domain=Domain(name='globo.com'),
                                             key=Key(name='some.random.fact'),
                                             value='whatever')

        for x in range(3):
            DomainFactory.create(name='g%d.com' % x)

        domains_violations_prefs = \
            DomainsViolationsPrefs.get_domains_violations_prefs(self.db)

        expect(domains_violations_prefs).to_length(1)

        default_violations_values = {
            'page.title.size': 100,
            'total.requests.img': 5,
        }

        page_title_size = KeyFactory.create(name='page.title.size')
        total_requests_img = KeyFactory.create(name='total.requests.img')

        violation_definitions = {
            'page.title.size': {
                'key': page_title_size,
                'default_value': 100
            },
            'total.requests.img': {
                'key': total_requests_img,
                'default_value': 5
            }
        }

        DomainsViolationsPrefs.insert_default_violations_values_for_all_domains(
            self.db, default_violations_values, violation_definitions,
            self.cache)

        domains_violations_prefs = \
            DomainsViolationsPrefs.get_domains_violations_prefs(self.db)

        expect(domains_violations_prefs).to_length(4)

        expect(domains_violations_prefs).to_be_like({
            'globo.com': {
                'some.random.fact': 'whatever',
                'total.requests.img': 5,
                'page.title.size': 100
            },
            'g0.com': {
                'page.title.size': 100,
                'total.requests.img': 5
            },
            'g1.com': {
                'page.title.size': 100,
                'total.requests.img': 5
            },
            'g2.com': {
                'page.title.size': 100,
                'total.requests.img': 5
            },
        })
Пример #15
0
    def test_can_get_domains_full_data(self):
        domains = []
        for i in range(3):
            domains.append(DomainFactory.create(name='domain-%d.com' % i))

        pages = []
        for i, domain in enumerate(domains):
            pages.append([])
            for j in range(3):
                pages[i].append(PageFactory.create(domain=domain))

        requests = reviews = []
        for i, (domain, page) in enumerate(zip(domains, pages)):
            for j in range(i + 1):
                reviews.append(
                    ReviewFactory.create(domain=domain,
                                         page=page[j],
                                         is_active=True,
                                         number_of_violations=(5 + 2 * j)))
                requests.append(
                    RequestFactory.create(status_code=200 if j %
                                          2 == 0 else 404,
                                          domain_name=domain.name,
                                          response_time=0.25 * (i + 1)))

        self.server.application.violation_definitions = {
            'key.%s' % i: {
                'title':
                'title.%s' % i,
                'category':
                'category.%s' % (i % 3),
                'key':
                Key.get_or_create(self.db, 'key.%d' % i,
                                  'category.%d' % (i % 3))
            }
            for i in range(9)
        }

        response = yield self.authenticated_fetch('/domains-details')

        expect(response.code).to_equal(200)

        full_data = loads(response.body)

        expect(full_data).to_length(3)
        expect(full_data[0].keys()).to_length(10)

        expect(map(lambda d: d['name'], full_data)).to_be_like(
            ['domain-0.com', 'domain-1.com', 'domain-2.com'])
        expect(map(lambda d: d['pageCount'], full_data)).to_be_like([3, 3, 3])
        expect(map(lambda d: d['reviewCount'],
                   full_data)).to_be_like([1, 2, 3])
        expect(map(lambda d: d['violationCount'],
                   full_data)).to_be_like([5, 12, 21])
        expect(map(lambda d: d['reviewPercentage'],
                   full_data)).to_be_like([33.33, 66.67, 100.0])
        expect(map(lambda d: d['errorPercentage'],
                   full_data)).to_be_like([0.0, 50.0, 33.33])
        expect(map(lambda d: d['averageResponseTime'],
                   full_data)).to_be_like([0.25, 0.5, 0.75])
    def update_by_user(cls, db, user, data):
        from holmes.models import Key

        if not user or not data:
            return

        for item in data:
            if 'key' not in item or 'is_active' not in item:
                continue

            key = Key.get_by_name(db, item.get('key'))
            if not key:
                continue

            is_active = item.get('is_active', True)

            db \
                .query(UsersViolationsPrefs) \
                .filter(
                    UsersViolationsPrefs.user_id == user.id,
                    UsersViolationsPrefs.key_id == key.id
                ) \
                .update(
                    {'is_active': is_active}
                )

        db.flush()
Пример #17
0
    def test_get_by_name(self):
        key = KeyFactory.create(name='some.random.key')

        loadded_key = Key.get_by_name(self.db, 'some.random.key')

        expect(key).to_equal(loadded_key)
        expect(loadded_key.name).to_equal('some.random.key')
Пример #18
0
    def test_can_update_by_domain(self):
        domain = DomainFactory.create(name='globo.com')

        DomainsViolationsPrefsFactory.create(domain=domain,
                                             key=Key(name='some.random'),
                                             value='whatever')

        loaded = DomainsViolationsPrefs.get_domains_violations_prefs_by_domain(
            self.db, domain.name)

        expect(loaded).not_to_be_null()
        expect(loaded).to_length(1)
        expect(loaded).to_be_like([{
            'key': 'some.random',
            'value': 'whatever'
        }])

        data = [{
            'key': 'some.random',
            'value': '10'
        }, {
            'invalid_key': 'some.random.1',
            'invalid_value': '101'
        }]

        DomainsViolationsPrefs.update_by_domain(self.db, self.cache, domain,
                                                data)

        loaded = DomainsViolationsPrefs.get_domains_violations_prefs_by_domain(
            self.db, domain.name)

        expect(loaded).not_to_be_null()
        expect(loaded).to_length(1)
        expect(loaded).to_be_like([{'key': 'some.random', 'value': '10'}])
Пример #19
0
    def test_can_create_facts(self):
        fact = FactFactory.create(key=Key(name='some.random.fact'),
                                  value='whatever')

        loaded_fact = self.db.query(Fact).get(fact.id)

        expect(loaded_fact.key.name).to_equal('some.random.fact')
        expect(loaded_fact.value).to_equal('whatever')
Пример #20
0
    def test_can_validate_title_size_with_domain(self):
        self.db.query(Key).delete()
        self.db.query(KeysCategory).delete()

        config = Config()
        config.MAX_TITLE_SIZE = 70

        key = Key(name='page.title.size')
        domain = DomainFactory.create(name='globo.com', url='http://globo.com')
        page = PageFactory.create(domain=domain, url='http://globo.com/a.html')

        self.sync_cache.redis.delete('violations-prefs-%s' % domain.name)

        DomainsViolationsPrefsFactory.create(domain=domain,
                                             key=key,
                                             value='10')

        reviewer = Reviewer(api_url='http://localhost:2368',
                            page_uuid=page.uuid,
                            page_url=page.url,
                            page_score=0.0,
                            config=config,
                            validators=[],
                            cache=self.sync_cache)

        title = 'a' * 80
        content = '<html><title>%s</title></html>' % title

        result = {
            'url': page.url,
            'status': 200,
            'content': content,
            'html': lxml.html.fromstring(content)
        }
        reviewer.responses[page.url] = result
        reviewer.get_response = Mock(return_value=result)

        reviewer.violation_definitions = {
            'page.title.size': {
                'default_value': 70,
                'key': key
            },
        }

        validator = TitleValidator(reviewer)
        validator.add_violation = Mock()
        validator.review.data = {'page.title_count': 1, 'page.title': title}

        validator.validate()

        validator.add_violation.assert_called_once_with(key='page.title.size',
                                                        value={
                                                            'max_size': 10,
                                                            'page_url':
                                                            page.url
                                                        },
                                                        points=10)
Пример #21
0
    def _insert_keys(self, keys):
        from holmes.models import Key

        for name in keys.keys():
            self.db.begin(subtransactions=True)
            key = Key.get_or_create(self.db, name)
            keys[name]['key'] = key
            self.db.add(key)
            self.db.commit()
    def test_users_violations_prefs_str(self):
        data = UsersViolationsPrefsFactory.create(
            user=User(email='*****@*****.**', fullname='Sherlock Holmes'),
            key=Key(name='some.random.fact'),
            is_active=False)

        loaded = self.db.query(UsersViolationsPrefs).get(data.id)

        expect(str(loaded)).to_be_like('[email protected]: some.random.fact')
Пример #23
0
    def test_fact_str(self):
        fact = FactFactory.create(
            key=Key(name="some.random.fact"),
            value=1203,
        )

        loaded_fact = self.db.query(Fact).get(fact.id)

        expect(str(loaded_fact)).to_be_like('some.random.fact: 1203')
Пример #24
0
    def test_domains_violations_prefs_str(self):
        data = DomainsViolationsPrefsFactory.create(
            domain=Domain(name='globo.com'),
            key=Key(name='some.random.fact'),
            value='whatever')

        loaded = self.db.query(DomainsViolationsPrefs).get(data.id)

        expect(
            str(loaded)).to_be_like('some.random.fact (globo.com): whatever')
Пример #25
0
    def test_can_get_most_common_violations(self):
        self.db.query(Violation).delete()

        review = ReviewFactory.create()

        for i in range(5):
            key = Key.get_or_create(self.db, 'violation.0')
            review.add_violation(key, 'value', 100, review.domain)

        for j in range(2):
            key = Key.get_or_create(self.db, 'violation.1')
            review.add_violation(key, 'value', 300, review.domain)

        self.server.application.violation_definitions = {
            'violation.%d' % i: {
                'title': 'title.%s' % i,
                'category': 'category.%s' % i,
                'key': Key.get_or_create(self.db, 'violation.%d' % i, 'category.%d' % i)
            } for i in range(3)
        }

        self.db.flush()

        response = yield self.authenticated_fetch('/most-common-violations/')

        violations = loads(response.body)

        expect(response.code).to_equal(200)
        expect(violations).to_be_like([
            {'count': 5, 'name': 'title.0', 'category': 'category.0', 'key': 'violation.0'},
            {'count': 2, 'name': 'title.1', 'category': 'category.1', 'key': 'violation.1'},
            {'count': 0, 'name': 'title.2', 'category': 'category.2', 'key': 'violation.2'},
        ])

        self.db.query(Violation).delete()

        response = yield self.authenticated_fetch('/most-common-violations/')

        violations_from_cache = loads(response.body)

        expect(response.code).to_equal(200)
        expect(violations_from_cache).to_be_like(violations)
    def test_can_create_users_violations_prefs(self):
        data = UsersViolationsPrefsFactory.create(
            user=User(email='*****@*****.**', fullname='Sherlock Holmes'),
            key=Key(name='some.random.fact'),
            is_active=False)

        loaded = self.db.query(UsersViolationsPrefs).get(data.id)

        expect(loaded.user.email).to_equal('*****@*****.**')
        expect(loaded.key.name).to_equal('some.random.fact')
        expect(loaded.is_active).to_equal(False)
Пример #27
0
    def test_can_create_domains_violations_prefs(self):
        data = DomainsViolationsPrefsFactory.create(
            domain=Domain(name='globo.com'),
            key=Key(name='some.random.fact'),
            value='whatever')

        loaded = self.db.query(DomainsViolationsPrefs).get(data.id)

        expect(loaded.domain.name).to_equal('globo.com')
        expect(loaded.key.name).to_equal('some.random.fact')
        expect(loaded.value).to_equal('whatever')
Пример #28
0
    def test_can_convert_to_dict(self):
        data = DomainsViolationsPrefsFactory.create(
            domain=Domain(name='globo.com'),
            key=Key(name='some.random.fact'),
            value='whatever')

        expect(data.to_dict()).to_be_like({
            'domain': 'globo.com',
            'key': 'some.random.fact',
            'value': 'whatever',
        })
    def test_can_convert_to_dict(self):
        data = UsersViolationsPrefsFactory.create(
            user=User(email='*****@*****.**', fullname='Sherlock Holmes'),
            key=Key(name='some.random.fact'),
            is_active=False)

        expect(data.to_dict()).to_be_like({
            'user': '******',
            'key': 'some.random.fact',
            'is_active': False
        })
Пример #30
0
    def _adjust_kwargs(cls, **kwargs):
        if 'page' in kwargs:
            kwargs['domain'] = kwargs['page'].domain

        if 'page' in kwargs and 'uuid' in kwargs:
            kwargs['page'].last_review_uuid = kwargs['uuid']

        if 'number_of_violations' in kwargs:
            number_of_violations = kwargs['number_of_violations']
            del kwargs['number_of_violations']

            if 'page' in kwargs:
                kwargs['page'].violations_count = number_of_violations

            violations = []
            for i in range(number_of_violations):
                key = Key.get_or_create(db, 'key.%d' % i, 'category.%d' % (i % 3))
                violations.append(
                    Violation(
                        key=key,
                        value="value %d" % i,
                        points=i,
                        domain=kwargs['page'].domain,
                        review_is_active=kwargs['is_active']
                    )
                )

            kwargs['violations'] = violations

        if 'number_of_facts' in kwargs:
            number_of_facts = kwargs['number_of_facts']
            del kwargs['number_of_facts']

            facts = []
            for i in range(number_of_facts):
                key = Key.get_or_create(db, 'key.%d' % i, 'category.%d' % (i % 3))
                facts.append(Fact(key=key, value="value %d" % i))

            kwargs['facts'] = facts

        return kwargs
Пример #31
0
    def test_can_get_domains_violations_prefs(self):
        data = DomainsViolationsPrefsFactory.create(
            domain=Domain(name='globo.com'),
            key=Key(name='some.random.fact'),
            value='whatever')

        data = DomainsViolationsPrefs.get_domains_violations_prefs(self.db)

        expect(data).to_be_like(
            {'globo.com': {
                'some.random.fact': 'whatever'
            }})
Пример #32
0
    def _adjust_kwargs(cls, **kwargs):
        if 'page' in kwargs:
            kwargs['domain'] = kwargs['page'].domain

        if 'page' in kwargs and 'uuid' in kwargs:
            kwargs['page'].last_review_uuid = kwargs['uuid']

        if 'number_of_violations' in kwargs:
            number_of_violations = kwargs['number_of_violations']
            del kwargs['number_of_violations']

            if 'page' in kwargs:
                kwargs['page'].violations_count = number_of_violations

            violations = []
            for i in range(number_of_violations):
                key = Key.get_or_create(db, 'key.%d' % i,
                                        'category.%d' % (i % 3))
                violations.append(
                    Violation(key=key,
                              value="value %d" % i,
                              points=i,
                              domain=kwargs['page'].domain,
                              review_is_active=kwargs['is_active']))

            kwargs['violations'] = violations

        if 'number_of_facts' in kwargs:
            number_of_facts = kwargs['number_of_facts']
            del kwargs['number_of_facts']

            facts = []
            for i in range(number_of_facts):
                key = Key.get_or_create(db, 'key.%d' % i,
                                        'category.%d' % (i % 3))
                facts.append(Fact(key=key, value="value %d" % i))

            kwargs['facts'] = facts

        return kwargs
Пример #33
0
    def test_can_get_domains_full_data(self):
        domains = []
        for i in xrange(3):
            domains.append(DomainFactory.create(name='domain-%d.com' % i))

        pages = []
        for i, domain in enumerate(domains):
            pages.append([])
            for j in xrange(3):
                pages[i].append(PageFactory.create(domain=domain))

        requests = reviews = []
        for i, (domain, page) in enumerate(zip(domains, pages)):
            for j in xrange(i + 1):
                reviews.append(ReviewFactory.create(
                    domain=domain,
                    page=page[j],
                    is_active=True,
                    number_of_violations=(5 + 2 * j)
                ))
                requests.append(RequestFactory.create(
                    status_code=200 if j % 2 == 0 else 404,
                    domain_name=domain.name,
                    response_time=0.25 * (i + 1)
                ))

        self.server.application.violation_definitions = {
            'key.%s' % i: {
                'title': 'title.%s' % i,
                'category': 'category.%s' % (i % 3),
                'key': Key.get_or_create(self.db, 'key.%d' % i, 'category.%d' % (i % 3))
            } for i in xrange(9)
        }

        response = yield self.http_client.fetch(
            self.get_url('/domains-details')
        )

        expect(response.code).to_equal(200)

        full_data = loads(response.body)

        expect(full_data).to_length(3)
        expect(full_data[0].keys()).to_length(10)

        expect(map(lambda d: d['name'], full_data)).to_be_like(['domain-0.com', 'domain-1.com', 'domain-2.com'])
        expect(map(lambda d: d['pageCount'], full_data)).to_be_like([3, 3, 3])
        expect(map(lambda d: d['reviewCount'], full_data)).to_be_like([1, 2, 3])
        expect(map(lambda d: d['violationCount'], full_data)).to_be_like([5, 12, 21])
        expect(map(lambda d: d['reviewPercentage'], full_data)).to_be_like([33.33, 66.67, 100.0])
        expect(map(lambda d: d['errorPercentage'], full_data)).to_be_like([0.0, 50.0, 33.33])
        expect(map(lambda d: d['averageResponseTime'], full_data)).to_be_like([0.25, 0.5, 0.75])
Пример #34
0
    def _insert_keys(self, keys):
        for name in keys.keys():
            key = Key.get_or_create(self.application.db, name)
            keys[name]['key'] = key

            category_name = keys[name].get('category', None)
            if category_name:
                category = self._insert_key_category(key, category_name)
                key.category = category

            self.application.db.add(key)
            self.application.db.flush()
            self.application.db.commit()
Пример #35
0
    def test_count_by_violation_key_name(self):
        self.db.query(Review).delete()
        self.db.query(Violation).delete()

        review = ReviewFactory.create(is_active=True)
        for i in range(3):
            key = Key.get_or_create(self.db, 'violation.%d' % i)
            review.add_violation(key, 'value', 100, review.domain)

        self.db.flush()

        key_id = review.violations[0].key_id
        count = Review.count_by_violation_key_name(self.db, key_id)
        expect(count).to_equal(1)

        for i in range(3):
            key = Key.get_or_create(self.db, 'violation.0')
            review.add_violation(key, 'value', 100, review.domain)

        key_id = review.violations[0].key_id
        count = Review.count_by_violation_key_name(self.db, key_id)
        expect(count).to_equal(4)
Пример #36
0
    def test_can_get_most_common_violations(self):
        self.db.query(Violation).delete()
        self.clean_cache(cache_keys=['most-common-violations'])

        review = ReviewFactory.create()

        for i in range(5):
            key = Key.get_or_create(self.db, 'violation1')
            review.add_violation(key, 'value', 100, review.domain)

        for j in range(2):
            key = Key.get_or_create(self.db, 'violation2')
            review.add_violation(key, 'value', 300, review.domain)

        self.db.flush()

        response = yield self.http_client.fetch(
            self.get_url('/most-common-violations/')
        )

        violations = loads(response.body)

        expect(response.code).to_equal(200)
        expect(violations).to_be_like([
            {'count': 5, 'name': 'undefined', 'category': 'undefined', 'key': 'violation1'},
            {'count': 2, 'name': 'undefined', 'category': 'undefined', 'key': 'violation2'}
        ])

        self.db.query(Violation).delete()

        response = yield self.http_client.fetch(
            self.get_url('/most-common-violations/')
        )

        violations_from_cache = loads(response.body)

        expect(response.code).to_equal(200)
        expect(violations_from_cache).to_be_like(violations)
Пример #37
0
    def test_can_create_violation(self):
        violation = ViolationFactory.create(key=Key(name='some.random.fact'),
                                            value='value',
                                            points=1203)

        loaded_violation = self.db.query(Violation).get(violation.id)

        expect(loaded_violation.value).to_equal('value')
        expect(loaded_violation.key.name).to_equal('some.random.fact')
        expect(loaded_violation.points).to_equal(1203)
        expect(str(loaded_violation)).to_be_like('%s: %s' % (
            violation.key.name,
            violation.value,
        ))
Пример #38
0
    def test_can_get_domain_top_category_violations(self):
        domain1 = DomainFactory.create()
        domain2 = DomainFactory.create()

        page1 = PageFactory.create(domain=domain1)
        page2 = PageFactory.create(domain=domain1)
        page3 = PageFactory.create(domain=domain2)

        ReviewFactory.create(domain=domain1, page=page1, is_active=True, number_of_violations=5)
        ReviewFactory.create(domain=domain1, page=page2, is_active=True, number_of_violations=7)
        ReviewFactory.create(domain=domain2, page=page3, is_active=True, number_of_violations=9)

        self.server.application.violation_definitions = {
            'key.%s' % i: {
                'title': 'title.%s' % i,
                'category': 'category.%s' % (i % 3),
                'key': Key.get_or_create(self.db, 'key.%d' % i, 'category.%d' % (i % 3))
            } for i in range(9)
        }

        key = Key.get_by_name(self.db, 'key.0')

        response = yield self.authenticated_fetch(
            '/domains/%s/violations/%d/' % (domain1.name, key.category_id)
        )

        expect(response.code).to_equal(200)

        domain_top_category = loads(response.body)

        expect(domain_top_category).to_length(5)
        expect(domain_top_category.keys()).to_be_like(['violations', 'domainId', 'categoryId', 'domainURL', 'domainName'])
        expect(domain_top_category['violations']).to_length(3)

        counts = map(lambda v: v['count'], domain_top_category['violations'])
        expect(counts).to_be_like([2, 1, 1])
Пример #39
0
    def test_can_get_domains_violations_prefs_by_key(self):
        self.db.query(DomainsViolationsPrefs).delete()
        self.db.query(Page).delete()
        self.db.query(Domain).delete()
        self.db.query(Key).delete()

        domain = DomainFactory.create(name='t.com')
        page = PageFactory.create(domain=domain, url='http://t.com/a.html')

        prefs = DomainsViolationsPrefsFactory.create(
            domain=domain, key=Key(name='page.title.size'), value='70')

        reviewer = self.get_reviewer(page_uuid=page.uuid,
                                     page_url=page.url,
                                     cache=self.sync_cache)

        # Get default value

        reviewer.violation_definitions = None

        self.sync_cache.redis.delete('violations-prefs-%s' % domain.name)
        prefs = reviewer.get_domains_violations_prefs_by_key(None)
        expect(prefs).to_be_null()

        prefs = reviewer.get_domains_violations_prefs_by_key('my-key')
        expect(prefs).to_be_null()

        reviewer.violation_definitions = {
            'page.title.size': {
                'default_value': '70'
            },
        }

        self.sync_cache.redis.delete('violations-prefs-%s' % domain.name)
        prefs = reviewer.get_domains_violations_prefs_by_key('my-key')
        expect(prefs).to_be_null()

        self.sync_cache.redis.delete('violations-prefs-%s' % domain.name)
        prefs = reviewer.get_domains_violations_prefs_by_key('page.title.size')
        expect(prefs).to_equal('70')

        # Get configured value

        data = [{'key': 'page.title.size', 'value': '10'}]
        DomainsViolationsPrefs.update_by_domain(self.db, self.sync_cache,
                                                domain, data)
        prefs = reviewer.get_domains_violations_prefs_by_key('page.title.size')
        expect(prefs).to_equal('10')
Пример #40
0
    def test_to_dict(self):
        violation = ViolationFactory.create(
            key=Key(name='some.random.fact'),
            value='value',
            points=1203,
        )

        violations_definitions = {'some.random.fact': {}}

        expect(violation.to_dict(violations_definitions, _)).to_be_like({
            'key': 'some.random.fact',
            'description': 'value',
            'title': 'undefined',
            'points': 1203,
            'category': 'undefined'
        })
Пример #41
0
    def test_get_by_violation_key_name(self):
        self.db.query(Review).delete()
        self.db.query(Violation).delete()

        review = ReviewFactory.create(is_active=True)
        for i in range(3):
            key = Key.get_or_create(self.db, "violation.%d" % i)
            review.add_violation(key, "value", 100, review.domain)
            review.page.last_review_id = review.id
            review.page.last_review_uuid = review.uuid
            review.page.last_review_date = review.completed_date

        self.db.flush()

        key_id = review.violations[0].key_id
        reviews = Review.get_by_violation_key_name(self.db, key_id)
        expect(reviews).to_length(1)
Пример #42
0
    def delete_prefs(cls, db, user, items):
        from holmes.models import Key

        for key_name in items:
            key = Key.get_by_name(db, key_name)
            if not key:
                continue

            db \
                .query(UsersViolationsPrefs) \
                .filter(
                    UsersViolationsPrefs.key_id == key.id,
                    UsersViolationsPrefs.user_id == user.id
                ) \
                .delete()

        db.flush()
Пример #43
0
    def test_get_by_violation_key_name(self):
        self.db.query(Review).delete()
        self.db.query(Violation).delete()

        review = ReviewFactory.create(is_active=True)
        for i in range(3):
            key = Key.get_or_create(self.db, 'violation.%d' % i)
            review.add_violation(key, 'value', 100, review.domain)
            review.page.last_review_id = review.id
            review.page.last_review_uuid = review.uuid
            review.page.last_review_date = review.completed_date

        self.db.flush()

        key_id = review.violations[0].key_id
        reviews = Review.get_by_violation_key_name(self.db, key_id)
        expect(reviews).to_length(1)
    def delete_prefs(cls, db, user, items):
        from holmes.models import Key

        for key_name in items:
            key = Key.get_by_name(db, key_name)
            if not key:
                continue

            db \
                .query(UsersViolationsPrefs) \
                .filter(
                    UsersViolationsPrefs.key_id == key.id,
                    UsersViolationsPrefs.user_id == user.id
                ) \
                .delete()

        db.flush()
Пример #45
0
    def test_to_dict(self):
        fact = FactFactory.create(
            key=Key(name='some.random.fact'),
            value='whatever',
        )

        facts_definitions = {'some.random.fact': {}}

        expect(fact.to_dict(facts_definitions, _)).to_be_like({
            'key':
            'some.random.fact',
            'value':
            'whatever',
            'unit':
            'value',
            'title':
            'unknown',
            'category':
            'unknown'
        })
Пример #46
0
    def insert_prefs(cls, db, user, items):
        from holmes.models import Key

        if not user:
            return

        data = []
        for key_name in items:
            key = Key.get_by_name(db, key_name)

            if not key:
                continue

            data.append({
                'user_id': user.id,
                'key_id': key.id,
                'is_active': True
            })

        db.execute(UsersViolationsPrefs.__table__.insert(), data)
    def insert_prefs(cls, db, user, items):
        from holmes.models import Key

        if not user:
            return

        data = []
        for key_name in items:
            key = Key.get_by_name(db, key_name)

            if not key:
                continue

            data.append({
                'user_id': user.id,
                'key_id': key.id,
                'is_active': True
            })

        db.execute(UsersViolationsPrefs.__table__.insert(), data)
Пример #48
0
    def test_can_get_violation_by_key_name(self):
        domains = [DomainFactory.create(
            name='g%s.com' % chr(i),
            url='http://g%s.com/' % chr(i)
        ) for i in xrange(ord('a'), ord('d'))]

        pages = [PageFactory.create(
            domain=domains[i % 3],
            url='%s%d' % (domains[i % 3].url, i % 2)
        ) for i in xrange(6)]

        for i, page in enumerate(pages):
            ReviewFactory.create(page=page, is_active=True, number_of_violations=i)

        self.db.flush()

        self.server.application.violation_definitions = {
            'key.%s' % i: {
                'title': 'title.%s' % i,
                'category': 'category.%s' % (i % 3),
                'key': Key.get_or_create(self.db, 'key.%d' % i, 'category.%d' % (i % 3))
            } for i in xrange(6)
        }

        response = yield self.http_client.fetch(
            self.get_url('/violation/key.1')
        )
        violations = loads(response.body)
        expect(response.code).to_equal(200)
        expect(violations).to_length(3)
        expect(violations['title']).to_equal('title.1')
        expect(violations['reviews']).to_length(4)
        expect(violations['reviewsCount']).to_equal(4)

        response = yield self.http_client.fetch(
            self.get_url('/violation/key.1?page_size=2&current_page=1')
        )
        violations = loads(response.body)
        expect(response.code).to_equal(200)
        expect(violations).to_length(3)
        expect(violations['title']).to_equal('title.1')
        expect(violations['reviews']).to_length(2)
        expect(violations['reviewsCount']).to_equal(4)

        response = yield self.http_client.fetch(
            self.get_url('/violation/key.1?page_filter=1')
        )
        violations = loads(response.body)
        expect(response.code).to_equal(200)
        expect(violations).to_length(3)
        expect(violations['title']).to_equal('title.1')
        expect(violations['reviews']).to_length(2)
        expect(violations['reviewsCount']).to_equal(2)

        response = yield self.http_client.fetch(
            self.get_url('/violation/key.1?domain_filter=gc.com')
        )
        violations = loads(response.body)
        expect(response.code).to_equal(200)
        expect(violations).to_length(3)
        expect(violations['title']).to_equal('title.1')
        expect(violations['reviews']).to_length(2)
        expect(violations['reviewsCount']).to_equal(8)

        response = yield self.http_client.fetch(
            self.get_url('/violation/key.1?domain_filter=foobar')
        )
        violations = loads(response.body)
        expect(response.code).to_equal(200)
        expect(violations).to_length(3)
        expect(violations['title']).to_equal('title.1')
        expect(violations['reviews']).to_length(4)
        expect(violations['reviewsCount']).to_equal(4)

        response = yield self.http_client.fetch(
            self.get_url('/violation/key.1?domain_filter=gc.com&page_filter=1')
        )
        violations = loads(response.body)
        expect(response.code).to_equal(200)
        expect(violations).to_length(3)
        expect(violations['title']).to_equal('title.1')
        expect(violations['reviews']).to_length(1)
        expect(violations['reviewsCount']).to_equal(1)
Пример #49
0
    def test_can_get_most_common_violations(self):
        self.db.query(Violation).delete()

        review = ReviewFactory.create()

        for i in range(5):
            key = Key.get_or_create(self.db, 'violation.0')
            review.add_violation(key, 'value', 100, review.domain)

        for j in range(2):
            key = Key.get_or_create(self.db, 'violation.1')
            review.add_violation(key, 'value', 300, review.domain)

        self.server.application.violation_definitions = {
            'violation.%d' % i: {
                'title':
                'title.%s' % i,
                'category':
                'category.%s' % i,
                'key':
                Key.get_or_create(self.db, 'violation.%d' % i,
                                  'category.%d' % i)
            }
            for i in range(3)
        }

        self.db.flush()

        response = yield self.authenticated_fetch('/most-common-violations/')

        violations = loads(response.body)

        expect(response.code).to_equal(200)
        expect(violations).to_be_like([
            {
                'count': 5,
                'name': 'title.0',
                'category': 'category.0',
                'key': 'violation.0'
            },
            {
                'count': 2,
                'name': 'title.1',
                'category': 'category.1',
                'key': 'violation.1'
            },
            {
                'count': 0,
                'name': 'title.2',
                'category': 'category.2',
                'key': 'violation.2'
            },
        ])

        self.db.query(Violation).delete()

        response = yield self.authenticated_fetch('/most-common-violations/')

        violations_from_cache = loads(response.body)

        expect(response.code).to_equal(200)
        expect(violations_from_cache).to_be_like(violations)
Пример #50
0
    def after_start(self, io_loop):
        if self.db is not None:
            self.application.db = self.db
        else:
            self.application.db = self.application.get_sqlalchemy_session()

        if self.debug:
            from sqltap import sqltap
            self.sqltap = sqltap.start()

        authnz_wrapper_class = self._load_authnz_wrapper()
        if authnz_wrapper_class:
            self.application.authnz_wrapper = authnz_wrapper_class(self.application.config)
        else:
            self.application.authnz_wrapper = None

        self.application.facters = self._load_facters()
        self.application.validators = self._load_validators()
        self.application.error_handlers = [handler(self.application.config) for handler in self._load_error_handlers()]

        self.application.search_provider = self._load_search_provider()(
            config=self.application.config,
            db=self.application.db,
            authnz_wrapper=self.application.authnz_wrapper,
            io_loop=io_loop
        )

        self.application.fact_definitions = {}
        self.application.violation_definitions = {}

        self.application.default_violations_values = {}

        for facter in self.application.facters:
            self.application.fact_definitions.update(facter.get_fact_definitions())

        Key.insert_keys(self.application.db, self.application.fact_definitions)

        for validator in self.application.validators:
            self.application.violation_definitions.update(validator.get_violation_definitions())

            self.application.default_violations_values.update(
                validator.get_default_violations_values(self.application.config)
            )

        Key.insert_keys(
            self.application.db,
            self.application.violation_definitions,
            self.application.default_violations_values
        )

        self.application.event_bus = EventBus(self.application)
        self.application.http_client = AsyncHTTPClient(io_loop=io_loop)

        self.application.cache = Cache(self.application)

        self.configure_material_girl()

        self.configure_i18n()

        DomainsViolationsPrefs.insert_default_violations_values_for_all_domains(
            self.application.db,
            self.application.default_violations_values,
            self.application.violation_definitions,
            self.application.cache
        )
Пример #51
0
    def test_can_get_violation_by_key_name_using_no_external_search_provider(
            self):
        self.use_no_external_search_provider()

        domains = [
            DomainFactory.create(name='g%s.com' % chr(i),
                                 url='http://g%s.com' % chr(i))
            for i in range(ord('a'), ord('d'))
        ]

        pages = [
            PageFactory.create(domain=domains[i % 3],
                               url='%s/%d' % (domains[i % 3].url, i % 2))
            for i in range(6)
        ]

        for i, page in enumerate(pages):
            review = ReviewFactory.create(
                page=page,
                is_active=True,
                number_of_violations=i,
                created_date=datetime(2014, 04, 15, 11, 44, i),
                completed_date=datetime(2014, 04, 15, 11, 44, i * 2))
            review.page.last_review_id = review.id
            review.page.last_review_uuid = review.uuid
            review.page.last_review_date = review.completed_date

        self.db.flush()

        self.server.application.violation_definitions = {
            'key.%s' % i: {
                'title':
                'title.%s' % i,
                'category':
                'category.%s' % (i % 3),
                'generic_description':
                'description.%s' % (i % 3),
                'key':
                Key.get_or_create(self.db, 'key.%d' % i,
                                  'category.%d' % (i % 3))
            }
            for i in range(6)
        }

        dt = datetime(2014, 04, 15, 11, 44, 4)
        dt_timestamp = calendar.timegm(dt.utctimetuple())

        response = yield self.authenticated_fetch('/violation/key.1')
        violations = loads(response.body)
        expect(response.code).to_equal(200)
        expect(violations).to_length(3)
        expect(violations['title']).to_equal('title.1')
        expect(violations['reviews']).to_length(4)
        expect(violations['reviewsCount']).to_equal(4)
        expect(violations['reviews'][3]['domain']).to_equal('gc.com')
        expect(violations['reviews'][3]['page']['url']).to_equal(
            'http://gc.com/0')
        expect(violations['reviews'][3]['page']['completedAt']).to_equal(
            dt_timestamp)

        response = yield self.authenticated_fetch(
            '/violation/key.1?page_size=2&current_page=1')
        violations = loads(response.body)
        expect(response.code).to_equal(200)
        expect(violations).to_length(3)
        expect(violations['title']).to_equal('title.1')
        expect(violations['reviews']).to_length(2)
        expect(violations['reviewsCount']).to_equal(4)

        response = yield self.authenticated_fetch(
            '/violation/key.1?page_filter=1')
        violations = loads(response.body)
        expect(response.code).to_equal(200)
        expect(violations).to_length(3)
        expect(violations['title']).to_equal('title.1')
        expect(violations['reviews']).to_length(4)
        expect(violations['reviewsCount']).to_be_null()

        response = yield self.authenticated_fetch(
            '/violation/key.1?domain_filter=gc.com')
        violations = loads(response.body)
        expect(response.code).to_equal(200)
        expect(violations).to_length(3)
        expect(violations['title']).to_equal('title.1')
        expect(violations['reviews']).to_length(2)
        expect(violations['reviewsCount']).to_be_null()

        response = yield self.authenticated_fetch(
            '/violation/key.1?domain_filter=gc.com&page_filter=1')
        violations = loads(response.body)
        expect(response.code).to_equal(200)
        expect(violations).to_length(3)
        expect(violations['title']).to_equal('title.1')
        expect(violations['reviews']).to_length(1)
        expect(violations['reviewsCount']).to_be_null()

        try:
            response = yield self.authenticated_fetch('/violation/foobar')
        except HTTPError:
            err = sys.exc_info()[1]
            expect(err).not_to_be_null()
            expect(err.code).to_equal(404)
            expect(
                err.response.reason).to_be_like('Invalid violation key foobar')
        else:
            assert False, 'Should not get this far'

        try:
            response = yield self.authenticated_fetch(
                '/violation/key.1?domain_filter=foobar')
        except HTTPError:
            err = sys.exc_info()[1]
            expect(err).not_to_be_null()
            expect(err.code).to_equal(404)
            expect(err.response.reason).to_be_like('Domain foobar not found')
        else:
            assert False, 'Should not get this far'
Пример #52
0
    def test_can_get_violation_by_key_name_using_no_external_search_provider(self):
        self.use_no_external_search_provider()

        domains = [DomainFactory.create(
            name='g%s.com' % chr(i),
            url='http://g%s.com' % chr(i)
        ) for i in range(ord('a'), ord('d'))]

        pages = [PageFactory.create(
            domain=domains[i % 3],
            url='%s/%d' % (domains[i % 3].url, i % 2)
        ) for i in range(6)]

        for i, page in enumerate(pages):
            review = ReviewFactory.create(
                page=page,
                is_active=True,
                number_of_violations=i,
                created_date=datetime(2014, 04, 15, 11, 44, i),
                completed_date=datetime(2014, 04, 15, 11, 44, i * 2)
            )
            review.page.last_review_id = review.id
            review.page.last_review_uuid = review.uuid
            review.page.last_review_date = review.completed_date

        self.db.flush()

        self.server.application.violation_definitions = {
            'key.%s' % i: {
                'title': 'title.%s' % i,
                'category': 'category.%s' % (i % 3),
                'generic_description': 'description.%s' % (i % 3),
                'key': Key.get_or_create(self.db, 'key.%d' % i, 'category.%d' % (i % 3))
            } for i in range(6)
        }

        dt = datetime(2014, 04, 15, 11, 44, 4)
        dt_timestamp = calendar.timegm(dt.utctimetuple())

        response = yield self.authenticated_fetch('/violation/key.1')
        violations = loads(response.body)
        expect(response.code).to_equal(200)
        expect(violations).to_length(3)
        expect(violations['title']).to_equal('title.1')
        expect(violations['reviews']).to_length(4)
        expect(violations['reviewsCount']).to_equal(4)
        expect(violations['reviews'][3]['domain']).to_equal('gc.com')
        expect(violations['reviews'][3]['page']['url']).to_equal('http://gc.com/0')
        expect(violations['reviews'][3]['page']['completedAt']).to_equal(dt_timestamp)

        response = yield self.authenticated_fetch(
            '/violation/key.1?page_size=2&current_page=1'
        )
        violations = loads(response.body)
        expect(response.code).to_equal(200)
        expect(violations).to_length(3)
        expect(violations['title']).to_equal('title.1')
        expect(violations['reviews']).to_length(2)
        expect(violations['reviewsCount']).to_equal(4)

        response = yield self.authenticated_fetch(
            '/violation/key.1?page_filter=1'
        )
        violations = loads(response.body)
        expect(response.code).to_equal(200)
        expect(violations).to_length(3)
        expect(violations['title']).to_equal('title.1')
        expect(violations['reviews']).to_length(4)
        expect(violations['reviewsCount']).to_be_null()

        response = yield self.authenticated_fetch(
            '/violation/key.1?domain_filter=gc.com'
        )
        violations = loads(response.body)
        expect(response.code).to_equal(200)
        expect(violations).to_length(3)
        expect(violations['title']).to_equal('title.1')
        expect(violations['reviews']).to_length(2)
        expect(violations['reviewsCount']).to_be_null()

        response = yield self.authenticated_fetch(
            '/violation/key.1?domain_filter=gc.com&page_filter=1'
        )
        violations = loads(response.body)
        expect(response.code).to_equal(200)
        expect(violations).to_length(3)
        expect(violations['title']).to_equal('title.1')
        expect(violations['reviews']).to_length(1)
        expect(violations['reviewsCount']).to_be_null()

        try:
            response = yield self.authenticated_fetch(
                '/violation/foobar'
            )
        except HTTPError:
            err = sys.exc_info()[1]
            expect(err).not_to_be_null()
            expect(err.code).to_equal(404)
            expect(err.response.reason).to_be_like('Invalid violation key foobar')
        else:
            assert False, 'Should not get this far'

        try:
            response = yield self.authenticated_fetch(
                '/violation/key.1?domain_filter=foobar'
            )
        except HTTPError:
            err = sys.exc_info()[1]
            expect(err).not_to_be_null()
            expect(err.code).to_equal(404)
            expect(err.response.reason).to_be_like('Domain foobar not found')
        else:
            assert False, 'Should not get this far'