Example #1
0
def test_that_only_ints_or_strings_are_allowed_in_identifiers():
    identifier = Identifier()

    invalid_values = [42.0, {"a": 1}, ["a", "b"], True, datetime.utcnow()]
    for value in invalid_values:
        with pytest.raises(ValidationError):
            identifier._load(value)
Example #2
0
def test_string_identifiers_are_preserved_as_strings_in_as_dict():
    identifier = Identifier()

    value = identifier._load("42")

    assert isinstance(value, str)
    assert identifier.as_dict(value) == "42"
Example #3
0
def test_int_identifiers_are_preserved_as_ints_in_as_dict():
    identifier = Identifier()

    value = identifier._load(42)

    assert isinstance(value, int)
    assert identifier.as_dict(value) == 42
Example #4
0
def test_UUID_identifiers_are_converted_into_strings_in_as_dict():
    uuid_val = uuid4()
    identifier = Identifier()

    value = identifier._load(uuid_val)

    assert isinstance(value, UUID)
    assert identifier.as_dict(value) == str(uuid_val)
Example #5
0
class User(BaseEventSourcedAggregate):
    user_id = Identifier(identifier=True)
    email = String()
    name = String()
    password_hash = String()
    address = String()

    is_registered = Boolean()

    @classmethod
    def register(cls, command: Register) -> User:
        user = cls(
            user_id=command.user_id,
            email=command.email,
            name=command.name,
            password_hash=command.password_hash,
        )
        user.raise_(
            Registered(
                user_id=command.user_id,
                email=command.email,
                name=command.name,
                password_hash=command.password_hash,
            ))

        return user

    @apply(Registered)
    def registered(self, _: Registered) -> None:
        self.is_registered = True
Example #6
0
class User(BaseEventSourcedAggregate):
    user_id = Identifier(identifier=True)
    name = String(max_length=50, required=True)
    email = String(required=True)
    status = String(choices=UserStatus)

    @classmethod
    def register(cls, user_id, name, email):
        user = cls(user_id=user_id, name=name, email=email)
        user.raise_(UserRegistered(user_id=user_id, name=name, email=email))
        return user

    def activate(self):
        self.raise_(UserActivated(user_id=self.user_id))

    def change_name(self, name):
        self.raise_(UserRenamed(user_id=self.user_id, name=name))

    @apply(UserRegistered)
    def registered(self, _: UserRegistered):
        self.status = UserStatus.INACTIVE.value

    @apply(UserActivated)
    def activated(self, _: UserActivated):
        self.status = UserStatus.ACTIVE.value

    @apply(UserRenamed)
    def renamed(self, event: UserRenamed):
        self.name = event.name
class Registered(BaseEvent):
    id = Identifier(identifier=True)
    email = String()
    name = String()

    class Meta:
        aggregate_cls = User
class Create(BaseCommand):
    id = Identifier(identifier=True)
    topic = String()
    content = Text()

    class Meta:
        aggregate_cls = Post
Example #9
0
class Registered(BaseEvent):
    user_id = Identifier()
    email = String()
    name = String()
    password_hash = String()

    class Meta:
        stream_name = "user"
class Registered(BaseEvent):
    id = Identifier()
    email = String()
    name = String()
    password_hash = String()

    class Meta:
        aggregate_cls = User
Example #11
0
class OrderedPerson(BaseView):
    person_id = Identifier(identifier=True)
    first_name = String(max_length=50, required=True)
    last_name = String(max_length=50)
    age = Integer(default=21)

    class Meta:
        order_by = "first_name"
Example #12
0
class DbPerson(BaseView):
    person_id = Identifier(identifier=True)
    first_name = String(max_length=50, required=True)
    last_name = String(max_length=50)
    age = Integer(default=21)

    class Meta:
        schema_name = "peoples"
Example #13
0
class Subscribed(BaseEvent):
    """An event generated by an external system in its own stream,
    that is consumed and stored as part of the User aggregate.
    """

    id = Identifier()

    class Meta:
        stream_name = "subscriptions"
Example #14
0
class Building(BaseView):
    building_id = Identifier(identifier=True)
    name = String(max_length=50)
    floors = Integer()
    status = String(choices=BuildingStatus)

    def defaults(self):
        if not self.status:
            if self.floors == 4:
                self.status = BuildingStatus.DONE.value
            else:
                self.status = BuildingStatus.WIP.value

    def clean(self):
        errors = defaultdict(list)

        if self.floors >= 4 and self.status != BuildingStatus.DONE.value:
            errors["status"].append("should be DONE")

        return errors
class User(BaseEventSourcedAggregate):
    user_id = Identifier(identifier=True)
    email = String()
    name = String()
    password_hash = String()
    address = String()

    is_registered = Boolean()

    @classmethod
    def register(cls, command: Register) -> User:
        user = cls(
            user_id=command.user_id,
            email=command.email,
            name=command.name,
            password_hash=command.password_hash,
        )
        user.raise_(
            Registered(
                user_id=command.user_id,
                email=command.email,
                name=command.name,
                password_hash=command.password_hash,
            )
        )

        return user

    def change_address(self, address: String) -> None:
        if address != self.address:
            self.address = address
            self.raise_(AddressChanged(user_id=self.user_id, address=address))

    @apply(Registered)
    def registered(self, event: Registered) -> None:
        self.is_registered = True

    @apply(AddressChanged)
    def address_changed(self, event: AddressChanged) -> None:
        self.address = event.address
class Activated(BaseEvent):
    id = Identifier(required=True)

    class Meta:
        aggregate_cls = User
class Renamed(BaseEvent):
    id = Identifier(required=True)
    name = String(required=True, max_length=50)

    class Meta:
        aggregate_cls = User
class Registered(BaseEvent):
    id = Identifier()
    email = String()
    name = String()
    password_hash = String()
class Activated(BaseEvent):
    id = Identifier()
    activated_at = DateTime()
class User(BaseEventSourcedAggregate):
    id = Identifier(identifier=True)
    email = String()
    name = String()
Example #21
0
class PersonAdded(BaseEvent):
    id = Identifier(required=True)
    email = String(max_length=255, required=True)
    first_name = String(max_length=50, required=True)
    last_name = String(max_length=50, required=True)
    age = Integer(default=21)
class Activate(BaseCommand):
    user_id = Identifier()
class Register(BaseCommand):
    user_id = Identifier()
    email = String()
Example #24
0
class LoggedIn(BaseEvent):
    id = Identifier()
    activated_at = DateTime()

    class Meta:
        aggregate_cls = User
Example #25
0
class Register(BaseCommand):
    user_id = Identifier()
    email = String()
    name = String()
    password_hash = String()
class Published(BaseEvent):
    id = Identifier(required=True)
    published_time = DateTime(default=datetime.utcnow)

    class Meta:
        aggregate_cls = Post
class Published(BaseEvent):
    id = Identifier(required=True)
    published_time = DateTime(default=datetime.utcnow)
class Register(BaseCommand):
    user_id = Identifier()
    email = String()

    class Meta:
        aggregate_cls = User
class Created(BaseEvent):
    id = Identifier(identifier=True)
    topic = String()
    content = Text()
class Activate(BaseCommand):
    user_id = Identifier()

    class Meta:
        aggregate_cls = User