Beispiel #1
0
def test_prepare_upgrades_schema_and_sets_position():
    source = MockSource(feed_end=50)
    worker = MockWorker()
    db = MockDB(is_initialized=False)
    settings = MockSettings(source=source, worker=worker, db=db)
    with spy_on(db.upgrade_schema), spy_on(worker.set_initial_position):
        prepare(settings)
        assert db.upgrade_schema.called
        assert worker.set_initial_position.calls[0].args[1] == 50
Beispiel #2
0
    def test_put_revoke_ship_it_timestamp(self):
        """Testing the PUT <URL> API with revoking Ship It does not update
        timestamp
        """
        # ReviewRequest.last_update is a
        # django.db.fields.ModificationTimestampField, which retrieves its
        # value from datetime.utcnow().replace(tzinfo=utc).
        #
        # django.utils.timezone.now has the same implementation.
        #
        # Unfortunately, we cannot spy on datetime.utcnow since it is a
        # builtin. So we replace get_tz_aware_utcnow with timezone.now and we
        # will replace that with a constant function in the spy_on calls below.
        self.spy_on(get_tz_aware_utcnow, call_fake=lambda: timezone.now())
        creation_timestamp = datetime.fromtimestamp(0, timezone.utc)
        review_timestamp = creation_timestamp + timedelta(hours=1)
        revoke_timestamp = review_timestamp + timedelta(hours=1)

        with spy_on(timezone.now, call_fake=lambda: creation_timestamp):
            review_request = self.create_review_request(publish=True,
                                                        submitter=self.user)

        with spy_on(timezone.now, call_fake=lambda: review_timestamp):
            review = self.create_review(review_request,
                                        body_top=Review.SHIP_IT_TEXT,
                                        ship_it=True,
                                        publish=True,
                                        user=self.user)

        review_request = ReviewRequest.objects.get(pk=review_request.pk)

        self.assertEqual(review_request.time_added, creation_timestamp)
        self.assertEqual(review_request.last_updated, review_timestamp)
        self.assertEqual(review.timestamp, review_timestamp)

        with spy_on(timezone.now, call_fake=lambda: revoke_timestamp):
            rsp = self.api_put(
                get_review_item_url(review_request, review.pk),
                {'ship_it': False},
                expected_mimetype=review_item_mimetype,
            )

        self.assertIn('stat', rsp)
        self.assertEqual(rsp['stat'], 'ok')

        review = Review.objects.get(pk=review.pk)
        review_request = ReviewRequest.objects.get(pk=review_request.pk)

        self.assertEqual(review_request.time_added, creation_timestamp)
        self.assertEqual(review_request.last_updated, review_timestamp)
        self.assertEqual(review.timestamp, review_timestamp)
def test_prepare_doesnt_upgrade_schema_if_already_initialized():
    db = MockDB(is_initialized=True)
    settings = MockSettings(db=db)
    with spy_on(db.upgrade_schema) as spy:
        with pytest.raises(DBInitializedError):
            prepare(settings)
        assert not spy.called
Beispiel #4
0
def test_migrate_doesnt_upgrade_schema_if_not_initialized():
    db = MockDB(is_initialized=False)
    settings = MockSettings(db=db)
    with spy_on(db.upgrade_schema) as spy:
        with pytest.raises(DBNotInitializedError):
            migrate(settings)
        assert not spy.called
Beispiel #5
0
def test_processes_with_minimal_context_if_full_context_error():
    event = {
        "isSecure": True,
        "timestamp": 0,
        "context": {
            "thisContextIsMissingProperties": True,
        },
        "minimalContext": {
            "revision": {
                "revisionId": 1,
                "link": "link",
            },
            "recipients": [{
                "username": "******",
                "email": "2@mail",
                "timezoneOffset": 0,
                "isActor": False,
            }],
        },
    }
    mail = MockMail()
    render = Render(JinjaTemplateStore("", "", False))
    logger = logging.create_dev_logger()
    with spy_on(mail.send) as spy:
        process_event(event, render, MockThreadStore(), logger, 0, Mock(),
                      mail)
        assert len(spy.calls) == 1
        assert spy.calls[0].args[0].template_path == "minimal"
Beispiel #6
0
    def test_revoke_ship_it_timestamp(self):
        """Testing Review.revoke_ship_it does not modify the review timestamp
        """
        # ReviewRequest.last_update is a
        # django.db.fields.ModificationTimestampField, which retrieves its
        # value from datetime.utcnow().replace(tzinfo=utc).
        #
        # django.utils.timezone.now has the same implementation.
        #
        # Unfortunately, we cannot spy on datetime.utcnow since it is a
        # builtin. So we replace get_tz_aware_utcnow with timezone.now and we
        # will replace that with a constant function in the spy_on calls below.
        self.spy_on(get_tz_aware_utcnow, call_fake=lambda: timezone.now())

        creation_timestamp = datetime.fromtimestamp(0, timezone.utc)
        review_timestamp = creation_timestamp + timedelta(hours=1)
        revoke_timestamp = review_timestamp + timedelta(hours=1)

        with spy_on(timezone.now, call_fake=lambda: creation_timestamp):
            review_request = self.create_review_request(publish=True)

        with spy_on(timezone.now, call_fake=lambda: review_timestamp):
            review = self.create_review(review_request,
                                        body_top=Review.SHIP_IT_TEXT,
                                        ship_it=True,
                                        publish=True)

        review_request = ReviewRequest.objects.get(pk=review_request.pk)

        self.assertEqual(review_request.time_added, creation_timestamp)
        self.assertEqual(review_request.last_updated, review_timestamp)
        self.assertEqual(review.timestamp, review_timestamp)

        with spy_on(timezone.now, call_fake=lambda: revoke_timestamp):
            review.revoke_ship_it(review.user)

        review = Review.objects.get(pk=review.pk)
        review_request = ReviewRequest.objects.get(pk=review_request.pk)

        self.assertEqual(review_request.time_added, creation_timestamp)
        self.assertEqual(review_request.last_updated, review_timestamp)
        self.assertEqual(review.timestamp, review_timestamp)
    def test_revoke_ship_it_timestamp(self):
        """Testing Review.revoke_ship_it does not modify the review timestamp
        """
        # ReviewRequest.last_update is a
        # django.db.fields.ModificationTimestampField, which retrieves its
        # value from datetime.utcnow().replace(tzinfo=utc).
        #
        # django.utils.timezone.now has the same implementation.
        #
        # Unfortunately, we cannot spy on datetime.utcnow since it is a
        # builtin. So we replace get_tz_aware_utcnow with timezone.now and we
        # will replace that with a constant function in the spy_on calls below.
        self.spy_on(get_tz_aware_utcnow, call_fake=lambda: timezone.now())

        creation_timestamp = datetime.fromtimestamp(0, timezone.utc)
        review_timestamp = creation_timestamp + timedelta(hours=1)
        revoke_timestamp = review_timestamp + timedelta(hours=1)

        with spy_on(timezone.now, call_fake=lambda: creation_timestamp):
            review_request = self.create_review_request(publish=True)

        with spy_on(timezone.now, call_fake=lambda: review_timestamp):
            review = self.create_review(review_request,
                                        body_top=Review.SHIP_IT_TEXT,
                                        ship_it=True,
                                        publish=True)

        review_request = ReviewRequest.objects.get(pk=review_request.pk)

        self.assertEqual(review_request.time_added, creation_timestamp)
        self.assertEqual(review_request.last_updated, review_timestamp)
        self.assertEqual(review.timestamp, review_timestamp)

        with spy_on(timezone.now, call_fake=lambda: revoke_timestamp):
            review.revoke_ship_it(review.user)

        review = Review.objects.get(pk=review.pk)
        review_request = ReviewRequest.objects.get(pk=review_request.pk)

        self.assertEqual(review_request.time_added, creation_timestamp)
        self.assertEqual(review_request.last_updated, review_timestamp)
        self.assertEqual(review.timestamp, review_timestamp)
Beispiel #8
0
def test_either_field_subclass():
    """Testing projector.fields.EitherField when one field type is a subclass of another"""

    class Special(int):
        pass

    class SuperSpecial(Special):
        pass

    class NotSoSpecial(int):
        pass

    int_field = fields.Raw()
    special_field = fields.Raw()

    class TestSchema(Schema):
        field = EitherField(required=True, fields={Special: special_field, int: int_field})

    schema = TestSchema()

    with spy_on(int_field._deserialize) as int_spy, spy_on(
        special_field._deserialize
    ) as special_spy:
        assert schema.load({"field": 3}) == {"field": 3}
        assert int_spy.called
        assert not special_spy.called

        int_spy.reset_calls()

        assert schema.load({"field": Special(3)}) == {"field": Special(3)}
        assert not int_spy.called
        assert special_spy.called

        special_spy.reset_calls()

        assert schema.load({"field": SuperSpecial(3)}) == {"field": SuperSpecial(3)}
        assert not int_spy.called
        assert special_spy.called

        special_spy.reset_calls()

        assert schema.load({"field": NotSoSpecial(3)}) == {"field": NotSoSpecial(3)}
        assert int_spy.called
        assert not special_spy.called

    with spy_on(int_field._serialize) as int_spy, spy_on(special_field._serialize) as special_spy:
        assert schema.dump({"field": 3}) == {"field": 3}
        assert int_spy.called
        assert not special_spy.called

        int_spy.reset_calls()

        assert schema.dump({"field": Special(3)}) == {"field": Special(3)}
        assert not int_spy.called
        assert special_spy.called

        special_spy.reset_calls()

        assert schema.dump({"field": SuperSpecial(3)}) == {"field": SuperSpecial(3)}
        assert not int_spy.called
        assert special_spy.called

        special_spy.reset_calls()

        assert schema.dump({"field": NotSoSpecial(3)}) == {"field": NotSoSpecial(3)}
        assert int_spy.called
        assert not special_spy.called
Beispiel #9
0
def test_migrate_upgrades_schema():
    db = MockDB(is_initialized=True)
    settings = MockSettings(db=db)
    with spy_on(db.upgrade_schema) as spy:
        migrate(settings)
        assert spy.called
Beispiel #10
0
def test_integration_pipeline():
    source = MockSource(
        next_result={
            "data": {
                "storyErrors":
                0,
                "events": [
                    {
                        "isSecure": True,
                        "timestamp": 0,
                        "context": {
                            "eventKind": "revision-reclaimed",
                            "actor": {
                                "userName": "******",
                                "realName": "1"
                            },
                            "body": {
                                "reviewers": [
                                    {
                                        "name":
                                        "2",
                                        "isActionable":
                                        False,
                                        "status":
                                        "accepted",
                                        "recipients": [{
                                            "timezoneOffset": 0,
                                            "username": "******",
                                            "email": "2@mail",
                                            "isActor": False,
                                        }],
                                    },
                                    {
                                        "name":
                                        "3",
                                        "isActionable":
                                        True,
                                        "status":
                                        "requested-changes",
                                        "recipients": [{
                                            "timezoneOffset": 0,
                                            "username": "******",
                                            "email": "3@mail",
                                            "isActor": False,
                                        }],
                                    },
                                ],
                                "subscribers": [{
                                    "email": "3@mail",
                                    "username": "******",
                                    "timezoneOffset": 0,
                                    "isActor": False,
                                }],
                                "commentCount":
                                1,
                                "transactionLink":
                                "link",
                            },
                            "revision": {
                                "revisionId": 1,
                                "repositoryName": "repo",
                                "link": "link",
                                "bug": {
                                    "bugId": 1,
                                    "link": "link"
                                },
                            },
                        },
                    },
                    {
                        "isSecure": False,
                        "timestamp": 1,
                        "context": {
                            "eventKind": "revision-abandoned",
                            "actor": {
                                "userName": "******",
                                "realName": "4"
                            },
                            "body": {
                                "reviewers": [{
                                    "username": "******",
                                    "email": "5@mail",
                                    "timezoneOffset": 0,
                                    "isActor": False,
                                }],
                                "subscribers": [],
                                "mainCommentMessage": {
                                    "asText": "Main comment",
                                    "asHtml": "<p>Main comment</p>",
                                },
                                "inlineComments": [{
                                    "contextKind": "code",
                                    "context": {
                                        "diff": [{
                                            "lineNumber": 10,
                                            "type": "added",
                                            "rawContent": "hello world",
                                        }]
                                    },
                                    "fileContext": "/README:20",
                                    "link": "link",
                                    "message": {
                                        "asText": "great content here.",
                                        "asHtml":
                                        "<em>great content here.</em>",
                                    },
                                }],
                                "transactionLink":
                                "link",
                            },
                            "revision": {
                                "revisionId": 2,
                                "name": "name 2",
                                "repositoryName": "repo",
                                "link": "link",
                            },
                        },
                    },
                ],
            },
            "cursor": {
                "after": 20
            },
        })
    mail = MockMail()
    render = Render(JinjaTemplateStore("", "", False))
    logger = logging.create_dev_logger()
    pipeline = Pipeline(source, render, mail, logger, 0, Mock(), False)
    with spy_on(mail.send) as send_spy, spy_on(source.fetch_next) as fetch_spy:
        new_position = pipeline.run(MockThreadStore(), 10)
        assert new_position == 20
        assert fetch_spy.calls[0].args[0] == 10

        emails = []
        for call in send_spy.calls:
            emails.append(call.args[0])

    _assert_mail(
        emails[0],
        "D1: (secure bug 1)",
        "2@mail",
        "1 reclaimed this revision that you've accepted and submitted a comment.",
    )
    _assert_mail(
        emails[1],
        "D1: (secure bug 1)",
        "3@mail",
        "1 reclaimed this revision and submitted a comment.",
    )
    _assert_mail(
        emails[2],
        "D2: name 2",
        "5@mail",
        "4 abandoned this revision and submitted comments.",
    )
Beispiel #11
0
def test_config_schema():
    scm_tools = {"Git": Git}

    schema = ConfigSchema()

    try:
        with spy_on(_get_scm_tools_uncached, call_fake=lambda: scm_tools):
            with pytest.raises(ValidationError) as excinfo:
                schema.load({})

            assert excinfo.value.messages == {
                "directories": ["Missing data for required field."],
                "repositories": ["Missing data for required field."],
            }

            with pytest.raises(ValidationError) as excinfo:
                schema.load({
                    "directories": {
                        "source": "/src"
                    },
                    "repositories": {
                        "my-repo": {
                            "scm": "unknown-scm"
                        }
                    },
                })

            assert excinfo.value.messages == {
                "repositories": {
                    "my-repo": {
                        "value": {
                            "config": ["Missing data for required field."]
                        }
                    }
                }
            }

            with pytest.raises(ValidationError) as excinfo:
                schema.load({
                    "directories": {
                        "source": "/src"
                    },
                    "repositories": {
                        "my-repo": {
                            "scm": "unknown-scm",
                            "config": {}
                        }
                    },
                })
            assert excinfo.value.messages == {
                "repositories": {
                    "my-repo": {
                        "value": {
                            "scm": ["Unknown SCM: `unknown-scm'"]
                        }
                    }
                }
            }

            assert schema.load({
                "directories": {
                    "source": "/src"
                },
                "repositories": {}
            }) == {
                "directories": {
                    "source": Path("/src")
                },
                "repositories": {},
            }

            assert schema.load({
                "directories": {
                    "source": "/src"
                },
                "repositories": {
                    "projector": {
                        "scm": "Git",
                        "config": {
                            "remotes": {
                                "origin": {
                                    "url":
                                    "[email protected]:brennie/projector.git"
                                }
                            }
                        },
                    }
                },
            }) == {
                "directories": {
                    "source": Path("/src")
                },
                "repositories": {
                    "projector": {
                        "scm": "Git",
                        "config": {
                            "ref": "master",
                            "detach": False,
                            "remotes": {
                                "origin":
                                Remote(
                                    kind=RemoteKind.EXPLICIT,
                                    inner={
                                        "url":
                                        "[email protected]:brennie/projector.git",
                                        "default": True,
                                    },
                                )
                            },
                        },
                    }
                },
            }
    finally:
        get_scm_tools.cache_clear()
Beispiel #12
0
def test_config_schema():
    scm_tools = {"Git": Git}

    schema = ConfigSchema()

    try:
        with spy_on(_get_scm_tools_uncached, call_fake=lambda: scm_tools):
            with pytest.raises(ValidationError) as excinfo:
                schema.load({})

            assert excinfo.value.messages == {
                "directories": ["Missing data for required field."],
                "repositories": ["Missing data for required field."],
            }

            with pytest.raises(ValidationError) as excinfo:
                schema.load(
                    {
                        "directories": {"source": "/src"},
                        "repositories": {"my-repo": {"scm": "unknown-scm"}},
                    }
                )

            assert excinfo.value.messages == {
                "repositories": {
                    "my-repo": {"value": {"config": ["Missing data for required field."]}}
                }
            }

            with pytest.raises(ValidationError) as excinfo:
                schema.load(
                    {
                        "directories": {"source": "/src"},
                        "repositories": {"my-repo": {"scm": "unknown-scm", "config": {}}},
                    }
                )
            assert excinfo.value.messages == {
                "repositories": {"my-repo": {"value": {"scm": ["Unknown SCM: `unknown-scm'"]}}}
            }

            assert schema.load({"directories": {"source": "/src"}, "repositories": {}}) == {
                "directories": {"source": Path("/src")},
                "repositories": {},
            }

            assert schema.load(
                {
                    "directories": {"source": "/src"},
                    "repositories": {
                        "projector": {
                            "scm": "Git",
                            "config": {
                                "remotes": {
                                    "origin": {"url": "[email protected]:brennie/projector.git"}
                                }
                            },
                        }
                    },
                }
            ) == {
                "directories": {"source": Path("/src")},
                "repositories": {
                    "projector": {
                        "scm": "Git",
                        "config": {
                            "ref": "master",
                            "detach": False,
                            "remotes": {
                                "origin": Remote(
                                    kind=RemoteKind.EXPLICIT,
                                    inner={
                                        "url": "[email protected]:brennie/projector.git",
                                        "default": True,
                                    },
                                )
                            },
                        },
                    }
                },
            }
    finally:
        get_scm_tools.cache_clear()
Beispiel #13
0
def test_either_field_subclass():
    """Testing projector.fields.EitherField when one field type is a subclass of another"""
    class Special(int):
        pass

    class SuperSpecial(Special):
        pass

    class NotSoSpecial(int):
        pass

    int_field = fields.Raw()
    special_field = fields.Raw()

    class TestSchema(Schema):
        field = EitherField(required=True,
                            fields={
                                Special: special_field,
                                int: int_field
                            })

    schema = TestSchema()

    with spy_on(int_field._deserialize) as int_spy, spy_on(
            special_field._deserialize) as special_spy:
        assert schema.load({"field": 3}) == {"field": 3}
        assert int_spy.called
        assert not special_spy.called

        int_spy.reset_calls()

        assert schema.load({"field": Special(3)}) == {"field": Special(3)}
        assert not int_spy.called
        assert special_spy.called

        special_spy.reset_calls()

        assert schema.load({"field": SuperSpecial(3)}) == {
            "field": SuperSpecial(3)
        }
        assert not int_spy.called
        assert special_spy.called

        special_spy.reset_calls()

        assert schema.load({"field": NotSoSpecial(3)}) == {
            "field": NotSoSpecial(3)
        }
        assert int_spy.called
        assert not special_spy.called

    with spy_on(int_field._serialize) as int_spy, spy_on(
            special_field._serialize) as special_spy:
        assert schema.dump({"field": 3}) == {"field": 3}
        assert int_spy.called
        assert not special_spy.called

        int_spy.reset_calls()

        assert schema.dump({"field": Special(3)}) == {"field": Special(3)}
        assert not int_spy.called
        assert special_spy.called

        special_spy.reset_calls()

        assert schema.dump({"field": SuperSpecial(3)}) == {
            "field": SuperSpecial(3)
        }
        assert not int_spy.called
        assert special_spy.called

        special_spy.reset_calls()

        assert schema.dump({"field": NotSoSpecial(3)}) == {
            "field": NotSoSpecial(3)
        }
        assert int_spy.called
        assert not special_spy.called