コード例 #1
0
    def test_upcast_created_event_from_v4(self):
        app = Application()

        aggregate = self.UpcastFixtureV4.create(A="TEXT", b=1, c=[1, 2])
        app.save(aggregate)
        copy = app.repository.get(aggregate.id)
        self.assertFalse(hasattr(copy, "a"))
        self.assertEqual(copy.A, "TEXT")
        self.assertEqual(copy.b, 1)
        self.assertEqual(copy.c, [1, 2])
        self.assertEqual(copy.d, None)
コード例 #2
0
 def test_take_snapshot_raises_assertion_error_if_snapshotting_not_enabled(
         self):
     app = Application()
     with self.assertRaises(AssertionError) as cm:
         app.take_snapshot(uuid4())
     self.assertEqual(
         cm.exception.args[0],
         ("Can't take snapshot without snapshots store. "
          "Please set environment variable IS_SNAPSHOTTING_ENABLED "
          "to a true value (e.g. 'y')."),
     )
コード例 #3
0
 def test_take_snapshot_raises_assertion_error_if_snapshotting_not_enabled(
         self):
     app = Application()
     with self.assertRaises(AssertionError) as cm:
         app.take_snapshot(uuid4())
     self.assertEqual(
         cm.exception.args[0],
         ("Can't take snapshot without snapshots store. Please "
          "set environment variable IS_SNAPSHOTTING_ENABLED to "
          "a true value (e.g. 'y'), or set 'is_snapshotting_enabled' "
          "on application class, or set 'snapshotting_intervals' on "
          "application class."),
     )
コード例 #4
0
    def test_event_decorator_uses_explicit_event_classes(self) -> None:
        # Here we just use the @event decorator to trigger events
        # that are applied using the decorated method.
        @aggregate
        class Order:
            class Confirmed(AggregateEvent):
                at: datetime

            @triggers(Confirmed)
            def confirm(self, at):
                self.confirmed_at = at

        order = Order()

        order.confirm(datetime.now())
        self.assertIsInstance(order.confirmed_at, datetime)

        app: Application = Application()
        app.save(order)

        copy = app.repository.get(order.id)

        self.assertEqual(copy.confirmed_at, order.confirmed_at)

        self.assertIsInstance(order, Aggregate)
        self.assertIsInstance(order, Order)
        self.assertIsInstance(copy, Aggregate)
        self.assertIsInstance(copy, Order)
コード例 #5
0
    def test(self) -> None:
        invoice = Invoice(
            number="INV/2021/11/01",
            amount=Decimal("34.20"),
            issued_to=Person("Oscar the Grouch", "123 Sesame Street"),
        )
        self.assertEqual(invoice.number, "INV/2021/11/01")
        self.assertEqual(invoice.amount, Decimal("34.20"))
        self.assertEqual(invoice.issued_to,
                         Person("Oscar the Grouch", "123 Sesame Street"))
        self.assertEqual(invoice.status, Status.INITIATED)

        invoice.number = "INV/2021/11/02"  # type: ignore
        self.assertEqual(invoice.number, "INV/2021/11/02")

        invoice.amount = Decimal("43.20")  # type: ignore
        self.assertEqual(invoice.number, "INV/2021/11/02")

        invoice.issue(issued_by="Cookie Monster")
        self.assertEqual(invoice.issued_by, "Cookie Monster")
        self.assertEqual(invoice.status, Status.ISSUED)

        with self.assertRaises(AssertionError):
            invoice.number = "INV/2021/11/03"  # type: ignore

        with self.assertRaises(AssertionError):
            invoice.amount = Decimal("54.20")  # type: ignore

        invoice.send(sent_via=SendMethod.EMAIL)
        self.assertEqual(invoice.sent_via, SendMethod.EMAIL)
        self.assertEqual(invoice.status, Status.SENT)

        app: Application = Application(env={"IS_SNAPSHOTTING_ENABLED": "y"})
        app.mapper.transcoder.register(PersonAsDict())
        app.mapper.transcoder.register(SendMethodAsStr())
        app.mapper.transcoder.register(StatusAsStr())

        app.save(invoice)

        copy = app.repository.get(invoice.id)
        self.assertEqual(invoice, copy)

        assert app.snapshots is not None
        snapshots = list(app.snapshots.get(invoice.id))
        self.assertEqual(len(snapshots), 0)

        app.take_snapshot(invoice.id)

        copy = app.repository.get(invoice.id)
        self.assertEqual(invoice, copy)

        copy = app.repository.get(invoice.id, version=1)
        self.assertNotEqual(invoice, copy)

        snapshots = list(app.snapshots.get(invoice.id))
        self.assertEqual(len(snapshots), 1)

        snapshot = snapshots[0]
        copy2 = snapshot.mutate(None)
        self.assertEqual(invoice, copy2)
コード例 #6
0
    def test_upcast_created_event_from_v1(self):
        app = Application()

        topic_v1 = get_topic(self.UpcastFixtureV1)
        topic_v1_created = get_topic(self.UpcastFixtureV1.Created)

        aggregate = self.UpcastFixtureV1.create(a="text")
        app.save(aggregate)
        copy = app.repository.get(aggregate.id)
        self.assertEqual(copy.a, "text")
        self.assertFalse(hasattr(copy, "b"))
        self.assertFalse(hasattr(copy, "c"))
        self.assertFalse(hasattr(copy, "d"))

        # "Deploy" v2.
        del _topic_cache[topic_v1]
        del _topic_cache[topic_v1_created]
        type(self).UpcastFixtureV1 = self.UpcastFixtureV2

        copy = app.repository.get(aggregate.id)
        self.assertFalse(hasattr(copy, "a"))
        self.assertEqual(copy.A, "TEXT")
        self.assertEqual(copy.b, 0)
        self.assertFalse(hasattr(copy, "c"))
        self.assertFalse(hasattr(copy, "d"))

        # "Deploy" v3.
        del _topic_cache[topic_v1]
        del _topic_cache[topic_v1_created]
        type(self).UpcastFixtureV1 = self.UpcastFixtureV3

        copy = app.repository.get(aggregate.id)
        self.assertFalse(hasattr(copy, "a"))
        self.assertEqual(copy.A, "TEXT")
        self.assertEqual(copy.b, 0)
        self.assertEqual(copy.c, [])

        # "Deploy" v4.
        del _topic_cache[topic_v1]
        type(self).UpcastFixtureV1 = self.UpcastFixtureV4

        copy = app.repository.get(aggregate.id)
        self.assertFalse(hasattr(copy, "a"))
        self.assertEqual(copy.A, "TEXT")
        self.assertEqual(copy.b, 0)
        self.assertEqual(copy.c, [])
        self.assertEqual(copy.d, None)
コード例 #7
0
    def test_upcast_aggregate_snapshot_from_v3(self):
        app = Application()

        topic_v3 = get_topic(self.UpcastFixtureV3)

        aggregate = self.UpcastFixtureV3.create(A="TEXT", b=1, c=[1, 2])
        app.save(aggregate)
        copy = app.repository.get(aggregate.id)
        self.assertFalse(hasattr(copy, "a"))
        self.assertEqual(copy.A, "TEXT")
        self.assertEqual(copy.b, 1)
        self.assertEqual(copy.c, [1, 2])
        self.assertFalse(hasattr(copy, "d"))

        app.take_snapshot(aggregate.id)

        # "Deploy" v3.
        del _topic_cache[topic_v3]
        type(self).UpcastFixtureV3 = self.UpcastFixtureV4

        copy = app.repository.get(aggregate.id)
        self.assertFalse(hasattr(copy, "a"))
        self.assertEqual(copy.A, "TEXT")
        self.assertEqual(copy.b, 1)
        self.assertEqual(copy.c, [1, 2])
        self.assertEqual(copy.d, None)

        copy.set_d(value=Decimal("10.0"))
        app.save(copy)

        copy = app.repository.get(aggregate.id)
        self.assertFalse(hasattr(copy, "a"))
        self.assertEqual(copy.A, "TEXT")
        self.assertEqual(copy.b, 1)
        self.assertEqual(copy.c, [1, 2])
        self.assertEqual(copy.d, 10)

        app.take_snapshot(aggregate.id)

        copy = app.repository.get(aggregate.id)
        self.assertFalse(hasattr(copy, "a"))
        self.assertEqual(copy.A, "TEXT")
        self.assertEqual(copy.b, 1)
        self.assertEqual(copy.c, [1, 2])
        self.assertEqual(copy.d, 10)
コード例 #8
0
    def test_application_log(self):
        # Check the old 'log' attribute presents the 'notification log' object.
        app = Application()
        with warnings.catch_warnings(record=True) as w:
            self.assertIs(app.log, app.notification_log)

        # Verify deprecation warning.
        assert len(w) == 1
        assert issubclass(w[-1].category, DeprecationWarning)
        assert "'log' is deprecated, use 'notifications' instead" in str(
            w[-1].message)
コード例 #9
0
    def test_upcast_created_event_from_v2(self):
        app = Application()

        topic_v2 = get_topic(self.UpcastFixtureV2)
        topic_v2_created = get_topic(self.UpcastFixtureV2.Created)

        aggregate = self.UpcastFixtureV2.create(A="TEXT", b=1)
        app.save(aggregate)
        copy = app.repository.get(aggregate.id)
        self.assertFalse(hasattr(copy, "a"))
        self.assertEqual(copy.A, "TEXT")
        self.assertEqual(copy.b, 1)
        self.assertFalse(hasattr(copy, "c"))
        self.assertFalse(hasattr(copy, "d"))

        # "Deploy" v3.
        del _topic_cache[topic_v2]
        del _topic_cache[topic_v2_created]
        type(self).UpcastFixtureV2 = self.UpcastFixtureV3

        copy = app.repository.get(aggregate.id)
        self.assertFalse(hasattr(copy, "a"))
        self.assertEqual(copy.A, "TEXT")
        self.assertEqual(copy.b, 1)
        self.assertEqual(copy.c, [])
        self.assertFalse(hasattr(copy, "d"))

        # "Deploy" v4.
        del _topic_cache[topic_v2]
        del _topic_cache[topic_v2_created]
        type(self).UpcastFixtureV2 = self.UpcastFixtureV4

        copy = app.repository.get(aggregate.id)
        self.assertFalse(hasattr(copy, "a"))
        self.assertEqual(copy.A, "TEXT")
        self.assertEqual(copy.b, 1)
        self.assertEqual(copy.c, [])
        self.assertEqual(copy.d, None)
コード例 #10
0
    def test_save_returns_recording_event(self):
        app = Application()

        recordings = app.save()
        self.assertEqual(recordings, [])

        recordings = app.save(None)
        self.assertEqual(recordings, [])

        recordings = app.save(Aggregate())
        self.assertEqual(len(recordings), 1)
        self.assertEqual(recordings[0].notification.id, 1)

        recordings = app.save(Aggregate())
        self.assertEqual(len(recordings), 1)
        self.assertEqual(recordings[0].notification.id, 2)

        recordings = app.save(Aggregate(), Aggregate())
        self.assertEqual(len(recordings), 2)
        self.assertEqual(recordings[0].notification.id, 3)
        self.assertEqual(recordings[1].notification.id, 4)
コード例 #11
0
    def test_resolve_persistence_topics(self):
        # None specified.
        app = Application()
        self.assertIsInstance(app.factory, InfrastructureFactory)

        # Legacy 'INFRASTRUCTURE_FACTORY'.
        app = Application(
            env={"INFRASTRUCTURE_FACTORY": "eventsourcing.popo:Factory"})
        self.assertIsInstance(app.factory, InfrastructureFactory)

        # Legacy 'FACTORY_TOPIC'.
        app = Application(env={"FACTORY_TOPIC": "eventsourcing.popo:Factory"})
        self.assertIsInstance(app.factory, InfrastructureFactory)

        # Check 'PERSISTENCE_MODULE' resolves to a class.
        app = Application(env={"PERSISTENCE_MODULE": "eventsourcing.popo"})
        self.assertIsInstance(app.factory, InfrastructureFactory)

        # Check exceptions.
        with self.assertRaises(AssertionError) as cm:
            Application(
                env={"PERSISTENCE_MODULE": "eventsourcing.application"})
        self.assertEqual(
            cm.exception.args[0],
            ("Found 0 infrastructure factory classes in "
             "'eventsourcing.application', expected 1."),
        )

        with self.assertRaises(AssertionError) as cm:
            Application(env={
                "PERSISTENCE_MODULE":
                "eventsourcing.application:Application"
            })
        self.assertEqual(
            cm.exception.args[0],
            ("Not an infrastructure factory class or module: "
             "eventsourcing.application:Application"),
        )
コード例 #12
0
    def test_application_with_cached_aggregates(self):
        app = Application(env={"AGGREGATE_CACHE_MAXSIZE": "10"})

        aggregate = Aggregate()
        app.save(aggregate)
        self.assertEqual(aggregate, app.repository.cache.get(aggregate.id))