Beispiel #1
0
        def test_true(self, valid_threat):
            states = ["pending", "active"]

            for state in states:
                threat = Threat(
                    **assoc(
                        valid_threat,
                        "occurrences",
                        [
                            {
                                "id": 1,
                                "state": state,
                                "created_at": datetime.utcnow(),
                                "updated_at": datetime.utcnow(),
                            }
                        ],
                    )
                )
                assert threat.is_being_monitored() is True
Beispiel #2
0
async def create_pending_occurrence(threat: Threat) -> Threat:
    print(threat)
    if threat.is_being_monitored():
        raise ThreatMonitoredError(threat)

    initial_state = State.PENDING
    query = OccurrenceModel.insert().values(threat_id=threat.id,
                                            state=initial_state)

    await database.execute(query)
    return await fetch_or_raise(threat.id)
Beispiel #3
0
async def fetch_or_raise(threat_id: int) -> Threat:
    query = ThreatModel.select().where(ThreatModel.c.id == threat_id)
    threat = await database.fetch_one(query)

    if not threat:
        raise ThreatNotFoundError()

    query = OccurrenceModel.select().where(
        OccurrenceModel.c.threat_id == threat_id)
    occurrences = await database.fetch_all(query)

    return Threat.parse_obj(assoc(dict(threat), "occurrences", occurrences))
Beispiel #4
0
async def fetch_by_name(threat_name: str) -> Optional[Threat]:
    query = ThreatModel.select().where(ThreatModel.c.name == threat_name)
    threat = await database.fetch_one(query)

    if not threat:
        return None

    query = OccurrenceModel.select().where(
        OccurrenceModel.c.threat_id == threat["id"])
    occurrences = await database.fetch_all(query)

    return Threat.parse_obj(assoc(dict(threat), "occurrences", occurrences))
Beispiel #5
0
        def test_is_sequence(self, valid_threat):
            with pytest.raises(ValidationError) as excinfo:
                Threat(
                    **assoc(
                        valid_threat,
                        "occurrences",
                        {
                            "id": 1,
                            "state": "resolved",
                            "created_at": datetime.utcnow(),
                            "updated_at": datetime.utcnow(),
                        },
                    )
                )

            self.assert_validation_error("type_error", excinfo)
Beispiel #6
0
async def upsert(dto: ReportThreatDto) -> Threat:
    threat = await fetch_by_name(dto.name)

    if threat:
        # Update
        values = dto.dict(exclude={"name"})
        query = (ThreatModel.update().where(
            ThreatModel.c.id == threat.id).values(**values))
        await database.execute(query)
        await register_history_change(threat.id, dto)
        return await fetch_or_raise(threat.id)
    else:
        # Create
        values = dto.dict()
        query = ThreatModel.insert().values(**values)
        last_record_id = await database.execute(query)
        await register_history_change(last_record_id, dto)
        return Threat.parse_obj({
            **values, "id": last_record_id,
            "occurrences": ()
        })
Beispiel #7
0
 def test_sorting_order(self, valid_threat):
     threat = Threat(
         **assoc(
             valid_threat,
             "occurrences",
             [
                 {
                     "id": 1,
                     "state": "resolved",
                     "created_at": datetime(2020, 1, 2),
                     "updated_at": datetime(2020, 2, 2),
                 },
                 {
                     "id": 2,
                     "state": "resolved",
                     "created_at": datetime(2020, 1, 1),
                     "updated_at": datetime(2020, 2, 1),
                 },
             ],
         )
     )
     first, second = threat.occurrences
     assert first.created_at < second.created_at
Beispiel #8
0
        def test_only_one_monitored_state(self, valid_threat):
            with pytest.raises(ValidationError) as excinfo:
                Threat(
                    **assoc(
                        valid_threat,
                        "occurrences",
                        [
                            {
                                "id": 1,
                                "state": "pending",
                                "created_at": datetime(2020, 1, 2),
                                "updated_at": datetime(2020, 1, 2),
                            },
                            {
                                "id": 2,
                                "state": "active",
                                "created_at": datetime(2020, 1, 1),
                                "updated_at": datetime(2020, 1, 1),
                            },
                        ],
                    )
                )

            self.assert_validation_error("value_error", excinfo)
Beispiel #9
0
        def test_false(self, valid_threat):
            threat = Threat(**assoc(valid_threat, "occurrences", []))
            assert threat.is_being_monitored() is False

            threat = Threat(
                **assoc(
                    valid_threat,
                    "occurrences",
                    [
                        {
                            "id": 1,
                            "state": "resolved",
                            "created_at": datetime.utcnow(),
                            "updated_at": datetime.utcnow(),
                        }
                    ],
                )
            )
            assert threat.is_being_monitored() is False
Beispiel #10
0
        def test_is_required(self, valid_threat):
            with pytest.raises(ValidationError) as excinfo:
                Threat(**dissoc(valid_threat, "occurrences"))

            self.assert_validation_error("value_error.missing", excinfo)
Beispiel #11
0
        def test_must_be_danger_level(self, valid_threat):
            with pytest.raises(ValidationError) as excinfo:
                Threat(**{**valid_threat, "danger_level": 9000})

            self.assert_validation_error("type_error.enum", excinfo)
Beispiel #12
0
        def test_must_be_str(self, valid_threat):
            with pytest.raises(ValidationError) as excinfo:
                Threat(**{**valid_threat, "name": ["Some name"]})

            self.assert_validation_error("type_error.str", excinfo)
Beispiel #13
0
        def test_must_be_int(self, valid_threat):
            with pytest.raises(ValidationError) as excinfo:
                Threat(**{**valid_threat, "id": "some_id"})

            self.assert_validation_error("type_error.integer", excinfo)
Beispiel #14
0
 def test_immutability(self, valid_threat):
     entity = Threat(**valid_threat)
     for key in entity.dict().keys():
         with pytest.raises(TypeError):
             setattr(entity, key, "some value")
Beispiel #15
0
 def test_invalidation(self, invalid_threat):
     with pytest.raises(ValidationError):
         Threat(**invalid_threat)
Beispiel #16
0
 def test_validation(self, valid_threat):
     assert Threat(**valid_threat)