def setup(self):
        self.graph = create_app(testing=True)
        self.user_store = self.graph.user_store
        self.follower_relationship_store = self.graph.follower_relationship_store

        self.username1 = "glen.runciter"
        self.user1 = User(
            username=self.username1,
            email="*****@*****.**",
            first_name="Glen",
            last_name="Runciter",
            title="Big Boss",
            bio="Ubik-- get it today!",
        )

        self.username2 = "joe.chip"
        self.user2 = User(
            username=self.username2,
            email="*****@*****.**",
            first_name="Joe",
            last_name="Chip",
            title="Technician",
            bio="Ubik-- get it today!",
        )

        self.context = SessionContext(self.graph)
        self.context.recreate_all()
        self.context.open()

        with transaction():
            self.user1.create()
            self.user2.create()
Exemplo n.º 2
0
    def setup(self):
        self.graph = create_object_graph(
            "microcosm_eventsource",
            root_path=join(dirname(__file__), pardir),
            testing=True,
        )
        self.graph.use(
            "sub_task_store",
            "sub_task_event_store",
        )
        self.store = SubTaskRollUpStore(self.graph)

        self.context = SessionContext(self.graph)
        self.context.recreate_all()
        self.context.open()

        with transaction():
            self.sub_task = SubTask().create()
            self.sub_task_created_event = SubTaskEvent(
                event_type=SubTaskEventType.CREATED,
                sub_task_id=self.sub_task.id,
            ).create()
            self.sub_task_assigned_event = SubTaskEvent(
                assignee="Alice",
                event_type=SubTaskEventType.ASSIGNED,
                parent_id=self.sub_task_created_event.id,
                sub_task_id=self.sub_task.id,
            ).create()
Exemplo n.º 3
0
    def test_transition_to_revised(self):
        with SessionContext(self.graph), transaction():
            reassigned_event = list(islice(self.iter_events(), 4))[-1]
            assert_that(reassigned_event.event_type,
                        is_(equal_to(TaskEventType.STARTED)))

        response = self.client.post(
            "/api/v1/task_event",
            data=dumps(
                dict(
                    taskId=str(self.task.id),
                    eventType=TaskEventType.REVISED.name,
                )),
        )
        assert_that(response.status_code, is_(equal_to(201)))

        data = loads(response.data.decode("utf-8"))
        assert_that(data, has_entry("taskId", str(self.task.id)))
        assert_that(data, has_entry("clock", 5))
        assert_that(data, has_entry("parentId", str(reassigned_event.id)))
        assert_that(data, has_entry("version", 2))

        self.graph.sns_producer.produce.assert_called_with(
            media_type=
            "application/vnd.globality.pubsub._.created.task_event.revised",
            uri="http://localhost/api/v1/task_event/{}".format(data["id"]),
        )

        with SessionContext(self.graph), transaction():
            task_event = self.graph.task_event_store.retrieve(data["id"])
            assert_that(task_event.state, is_(contains(TaskEventType.CREATED)))
Exemplo n.º 4
0
    def setup(self):
        self.graph = create_app(testing=True)
        self.tweet_store = self.graph.tweet_store
        self.user_store = self.graph.user_store

        self.username = "******"
        self.user = User(
            username=self.username,
            email="*****@*****.**",
            first_name="Joe",
            last_name="Chip",
            title="Technician",
            bio="Ubik-- get it today!",
        )

        self.context = SessionContext(self.graph)
        self.context.recreate_all()
        self.context.open()

        with transaction():
            self.user_store.create(self.user)

        self.tweet_content = """
            Friends, this is clean-up time and we’re discounting all our silent,
            electric Ubiks by this much money. Yes, we’re throwing away the blue-book.
            And remember: every Ubik on our lot has been used only as directed.
        """

        self.tweet = Tweet(
            user_id=self.user.id,
            tweet_content=self.tweet_content,
        )
Exemplo n.º 5
0
    def setup(self):
        self.graph = create_app(testing=True)
        self.client = self.graph.flask.test_client()
        recreate_all(self.graph)

        self.username1 = "glen.runciter"
        self.user1 = User(
            username=self.username1,
            email="*****@*****.**",
            first_name="Glen",
            last_name="Runciter",
            title="Big Boss",
            bio="Ubik-- get it today!",
        )

        self.username2 = "joe.chip"
        self.user2 = User(
            username=self.username2,
            email="*****@*****.**",
            first_name="Joe",
            last_name="Chip",
            title="Technician",
            bio="Ubik-- get it today!",
        )

        with SessionContext(self.graph), transaction():
            self.user1.create()
            self.user2.create()

        self.user1_follow_user2 = FollowerRelationship(
            id=new_object_id(),
            user_id=self.user2.id,
            follower_id=self.user1.id,
        )

        self.user2_tweet_content1 = """
            Friends, this is clean-up time and we’re discounting all our silent,
            electric Ubiks by this much money. Yes, we’re throwing away the blue-book.
            And remember: every Ubik on our lot has been used only as directed.
        """
        self.user2_tweet_content2 = """
            The best way to ask for beer is to sing out Ubik.
            Made from select hops, choice water, slow-aged for perfect flavor,
            Ubik is the nation’s number-one choice in beer. Made only in Cleveland.
        """

        with SessionContext(self.graph), transaction():
            self.user1_follow_user2.create()

            self.user2_tweet1 = Tweet(
                id=new_object_id(),
                user_id=self.user2.id,
                tweet_content=self.user2_tweet_content1,
            ).create()
            self.user2_tweet2 = Tweet(
                id=new_object_id(),
                user_id=self.user2.id,
                tweet_content=self.user2_tweet_content2,
            ).create()
Exemplo n.º 6
0
    def setup(self):
        self.graph = create_object_graph(name="example", testing=True, import_name="microcosm_postgres")
        self.company_store = self.graph.company_store
        self.employee_store = self.graph.employee_store

        self.context = SessionContext(self.graph)
        self.context.recreate_all()
        self.context.open()
Exemplo n.º 7
0
 def setup(self):
     self.graph = create_object_graph(name="example",
                                      testing=True,
                                      import_name="microcosm_postgres")
     self.context = SessionContext(self.graph)
     self.context.recreate_all()
     self.context.open()
     self.store = Store(self.graph, Sequential)
    def setup(self):
        self.graph = create_object_graph(name="example",
                                         testing=True,
                                         import_name="microcosm_postgres")
        self.graph.use("company_store")

        context = SessionContext(self.graph)
        context.recreate_all()
Exemplo n.º 9
0
    def setup(self):
        self.graph = create_app(testing=True)
        self.pizza_store = self.graph.pizza_store

        self.name = "NAME"

        self.context = SessionContext(self.graph)
        self.context.recreate_all()
        self.context.open()
Exemplo n.º 10
0
    def test_delete(self):
        with SessionContext(self.graph), transaction():
            self.order1.create()

        response = self.client.delete(self.detail_uri)
        assert_that(response.status_code, is_(equal_to(204)))

        with SessionContext(self.graph) as session:
            assert session.session.query(Order).get(self.order_id) is None
Exemplo n.º 11
0
    def setup(self):
        self.graph = create_app(testing=True)
        self.order_event_store = self.graph.order_event_store

        self.order_id = new_object_id()

        self.context = SessionContext(self.graph)
        self.context.recreate_all()
        self.context.open()
Exemplo n.º 12
0
    def setup(self):
        self.graph = create_app(testing=True)
        self.customer_event_store = self.graph.customer_event_store
        self.pizza_store = self.graph.pizza_store
        self.order_store = self.graph.order_store
        self.topping_store = self.graph.topping_store

        self.context = SessionContext(self.graph)
        self.context.recreate_all()
        self.context.open()
Exemplo n.º 13
0
    def setup(self):
        self.graph = create_app(testing=True)
        self.pizza_store = self.graph.pizza_store
        self.order_store = self.graph.order_store

        self.pizza_type = PizzaType.HANDTOSSED.name
        self.pizza_size = PizzaSize.SMALL.name

        self.context = SessionContext(self.graph)
        self.context.recreate_all()
        self.context.open()
Exemplo n.º 14
0
    def setup(self):
        self.graph = create_app(testing=True)
        self.user_store = self.graph.user_store

        self.username = "******"
        self.email = "*****@*****.**"
        self.first_name = "Joe"
        self.last_name = "Chip"
        self.title = "Technician"
        self.bio = "Ubik-- get it today!"

        self.context = SessionContext(self.graph)
        self.context.recreate_all()
        self.context.open()
Exemplo n.º 15
0
    def test_update_with_key(self):
        with SessionContext(self.graph):
            with transaction():
                encryptable = self.encryptable_store.create(
                    Encryptable(
                        key="private",
                        value="value",
                    ),
                )

        with SessionContext(self.graph):
            with transaction():
                res = self.encryptable_store.update(
                    encryptable.id,
                    Encryptable(
                        id=encryptable.id,
                        # Pass the key
                        key="private",
                        value="new-value",
                    ),
                )
                assert_that(
                    res,
                    has_properties(
                        key=is_(equal_to("private")),
                        value=is_(equal_to("new-value")),
                        encrypted_id=is_not(none()),
                    ),
                )

        with SessionContext(self.graph):
            encryptable = self.encryptable_store.retrieve(encryptable.id)

            assert_that(
                encryptable,
                has_properties(
                    key=is_(equal_to("private")),
                    value=is_(equal_to("new-value")),
                    encrypted_id=is_not(none()),
                ),
            )

            assert_that(
                self.encryptable_store.count(), is_(equal_to(1)),
            )
            assert_that(
                self.encrypted_store.count(), is_(equal_to(1)),
            )
Exemplo n.º 16
0
    def setup(self):
        loader = load_from_dict(
            secret=dict(postgres=dict(host=environ.get(
                "MICROCOSM_EVENTSOURCE__POSTGRES__HOST", "localhost"), ), ),
            postgres=dict(host=environ.get(
                "MICROCOSM_EVENTSOURCE__POSTGRES__HOST", "localhost"), ),
            sns_producer=dict(mock_sns=False, ),
        )
        self.graph = create_object_graph(
            "microcosm_eventsource",
            loader=loader,
            root_path=dirname(__file__),
            testing=True,
        )
        self.graph.use(
            "session_factory",
            "task_store",
            "task_event_store",
            "task_event_controller",
            "task_crud_routes",
        )
        self.client = self.graph.flask.test_client()
        recreate_all(self.graph)

        with SessionContext(self.graph), transaction():
            self.task = Task().create()
            self.graph.sns_producer.sns_client.reset_mock()
Exemplo n.º 17
0
    def test_not_encrypted(self):
        with SessionContext(self.graph):
            with transaction():
                encryptable = self.encryptable_store.create(
                    Encryptable(
                        key="key",
                        value="value",
                    ), )

            assert_that(
                encryptable,
                has_properties(
                    key=is_(equal_to("key")),
                    value=is_(equal_to("value")),
                    encrypted_id=is_(none()),
                ),
            )
            assert_that(
                self.encryptable_store.count(),
                is_(equal_to(1)),
            )
            assert_that(
                self.encrypted_store.count(),
                is_(equal_to(0)),
            )

            with transaction():
                self.encryptable_store.delete(encryptable.id)

            assert_that(
                self.encryptable_store.count(),
                is_(equal_to(0)),
            )
Exemplo n.º 18
0
    def test_created_event(self):
        created_event_id = new_object_id()
        with patch.object(self.graph.task_event_store,
                          "new_object_id") as mocked:
            mocked.return_value = created_event_id
            response = self.client.post(
                "/api/v1/task_event",
                data=dumps(
                    dict(
                        taskId=str(self.task.id),
                        eventType=TaskEventType.CREATED.name,
                        parentId=str(self.task.id),
                    )),
            )
        assert_that(response.status_code, is_(equal_to(201)))

        data = loads(response.data.decode("utf-8"))
        assert_that(data, has_entry("id", str(created_event_id)))
        assert_that(data, has_entry("taskId", str(self.task.id)))
        assert_that(data, has_entry("clock", 1))
        assert_that(data, has_entry("parentId", none()))

        self.graph.sns_producer.produce.assert_called_with(
            media_type=
            "application/vnd.globality.pubsub._.created.task_event.created",
            uri="http://localhost/api/v1/task_event/{}".format(data["id"]),
        )

        with SessionContext(self.graph), transaction():
            task_event = self.graph.task_event_store.retrieve(data["id"])
            assert_that(task_event.state, is_(contains(TaskEventType.CREATED)))
Exemplo n.º 19
0
    def test_search_task_events_by_clock(self):
        with SessionContext(self.graph), transaction():
            created_event = list(islice(self.iter_events(), 4))[-1]
            assert_that(created_event.event_type,
                        is_(equal_to(TaskEventType.STARTED)))

        descending_response = self.client.get(
            "/api/v1/task_event?sort_by_clock=true", )
        assert_that(descending_response.status_code, is_(equal_to(200)))
        data = loads(descending_response.data.decode("utf-8"))
        descending_order_clock_list = [
            event['clock'] for event in data["items"]
        ]
        assert_that(descending_order_clock_list, is_(equal_to([4, 3, 2, 1])))

        ascending_response = self.client.get(
            "/api/v1/task_event?sort_by_clock=true&sort_clock_in_ascending_order=true",
        )
        assert_that(ascending_response.status_code, is_(equal_to(200)))
        data = loads(ascending_response.data.decode("utf-8"))
        ascending_order_clock_list = [
            event['clock'] for event in data["items"]
        ]
        assert_that(ascending_order_clock_list, is_(equal_to([1, 2, 3, 4])))

        invalid_response = self.client.get(
            "/api/v1/task_event?sort_clock_in_ascending_order=true", )
        assert_that(invalid_response.status_code, is_(equal_to(422)))
Exemplo n.º 20
0
    def test_create(self):
        uri = "/api/v1/pizza"
        with SessionContext(self.graph), transaction():
            self.order.create()

        customer_id = str(new_object_id())
        with patch.object(self.graph.pizza_store, "new_object_id") as mocked:
            mocked.return_value = self.pizza1.id
            response = self.client.post(
                uri,
                json=dict(customerId=customer_id,
                          crustType="thin",
                          size=12,
                          orderId=self.order_id),
            )

        assert_that(response.status_code, is_(equal_to(201)))
        assert_that(
            response.json,
            has_entries(
                id=str(self.pizza1.id),
                customerId=customer_id,
                crustType="thin",
                size=12,
            ),
        )
Exemplo n.º 21
0
    def setup(self):
        loaders = load_each(
            load_from_dict(
                multi_tenant_key_registry=dict(
                    context_keys=[
                        "private",
                    ],
                    key_ids=[
                        "key_id",
                    ],
                ),
            ),
            load_from_environ,
        )
        self.graph = create_object_graph(
            name="example",
            testing=True,
            import_name="microcosm_postgres",
            loader=loaders,
        )
        self.encryptable_store = self.graph.encryptable_store
        self.encrypted_store = self.graph.encrypted_store
        self.json_encryptable_store = self.graph.json_encryptable_store
        self.json_encrypted_store = self.graph.json_encrypted_store
        self.nullable_encryptable_store = self.graph.nullable_encryptable_store
        self.nullable_encrypted_store = self.graph.nullable_encrypted_store
        self.encryptor = self.graph.multi_tenant_encryptor

        with SessionContext(self.graph) as context:
            context.recreate_all()
Exemplo n.º 22
0
 def test_clone(self):
     with SessionContext(self.graph):
         substitutions = dict(name="newname")
         dag = DAG.from_nodes(self.company,
                              self.employee).clone(substitutions)
         assert_that(dag.nodes, has_length(2))
         assert_that(dag.edges, has_length(1))
Exemplo n.º 23
0
    def setup(self):
        self.graph = create_object_graph(
            name="example",
            testing=True,
            import_name="microcosm_postgres",
        )
        self.company_store = self.graph.company_store

        self.companies = [
            Company(
                name="name1",
                type=CompanyType.private,
            ),
            Company(
                name="name2",
                type=CompanyType.private,
            ),
            Company(
                name="name3",
                type=CompanyType.private,
            ),
        ]

        with SessionContext(self.graph) as context:
            context.recreate_all()
Exemplo n.º 24
0
 def _make_company(self):
     with SessionContext(self.graph):
         with transaction():
             return Company(
                 name="name",
                 type=CompanyType.private,
             ).create()
Exemplo n.º 25
0
 def test_select_from_none(self):
     with SessionContext(self.graph):
         with transient(Company) as transient_company:
             assert_that(
                 transient_company.select_from(Company),
                 contains(),
             )
Exemplo n.º 26
0
    def setup(self):
        self.graph = create_app(testing=True)
        self.client = self.graph.flask.test_client()
        recreate_all(self.graph)

        with SessionContext(self.graph), transaction():
            self.new_order = Order().create()

            self.new_pizza = Pizza(
                id=new_object_id(),
                order_id=self.new_order.id,
                pizza_size=PizzaSize.SMALL.name,
                pizza_type=PizzaType.HANDTOSSED.name,
            ).create()

        self.first_topping = Topping(
            id=new_object_id(),
            pizza_id=self.new_pizza.id,
            topping_type=ToppingType.ONIONS,
        )

        self.second_topping = Topping(
            id=new_object_id(),
            pizza_id=self.new_pizza.id,
            topping_type=ToppingType.CHICKEN,
        )
Exemplo n.º 27
0
    def setup(self):
        self.graph = create_object_graph(
            "microcosm_eventsource",
            root_path=join(dirname(__file__), pardir),
            testing=True,
        )
        self.graph.use(
            "simple_test_object_store",
            "simple_test_object_event_store",
        )
        self.store = SimpleObjectTestRollupStore(self.graph)
        self.event_store = self.graph.simple_test_object_event_store

        self.context = SessionContext(self.graph)
        self.context.recreate_all()
        self.context.open()
    def setup(self):
        self.graph = create_object_graph(name="example", testing=True, import_name="microcosm_postgres")
        self.company_store = self.graph.company_store

        self.context = SessionContext(self.graph)
        self.context.recreate_all()
        self.context.open()
Exemplo n.º 29
0
    def setup(self):
        self.graph = create_object_graph(
            "microcosm_eventsource",
            root_path=join(dirname(__file__), pardir),
            testing=True,
        )
        self.graph.use(
            "task_store",
            "task_event_store",
            "activity_store",
            "activity_event_store",
        )
        self.store = self.graph.task_event_store
        self.activity_store = self.graph.activity_event_store

        self.context = SessionContext(self.graph)
        self.context.recreate_all()
        self.context.open()

        with transaction():
            self.task = Task().create()
            self.created_event = TaskEvent(
                event_type=TaskEventType.CREATED,
                task_id=self.task.id,
            ).create()
            self.scheduled_event = TaskEvent(
                deadline=datetime.utcnow(),
                event_type=TaskEventType.SCHEDULED,
                parent_id=self.created_event.id,
                state=[TaskEventType.CREATED, TaskEventType.SCHEDULED],
                task_id=self.task.id,
            ).create()
            self.assigned_event = TaskEvent(
                deadline=datetime.utcnow(),
                event_type=TaskEventType.ASSIGNED,
                parent_id=self.scheduled_event.id,
                state=[TaskEventType.ASSIGNED, TaskEventType.CREATED, TaskEventType.SCHEDULED],
                assignee="assignee",
                task_id=self.task.id,
            ).create()
            self.started_event = TaskEvent(
                event_type=TaskEventType.STARTED,
                parent_id=self.assigned_event.id,
                task_id=self.task.id,
            ).create()
            # flush sqlalchemy cache before sql operation
            self.store.session.expire_all()
Exemplo n.º 30
0
    def test_delete(self):
        with SessionContext(self.graph), transaction():
            self.example1.create()

        uri = f"/api/v1/example/{self.example1.id}"

        response = self.client.delete(uri)
        assert_that(response.status_code, is_(equal_to(204)))
Exemplo n.º 31
0
    def setup(self):
        self.graph = create_app(testing=True)
        self.account_store = self.graph.account_store

        self.name = "NAME"

        with SessionContext(self.graph) as context:
            context.recreate_all()
    def setup(self):
        self.graph = create_app(testing=True)
        self.example_store = self.graph.example_store

        self.name = "NAME"

        self.context = SessionContext(self.graph)
        self.context.recreate_all()
        self.context.open()
    def setup(self):
        self.graph = create_object_graph(name="example", testing=True, import_name="microcosm_postgres")
        self.company_store = self.graph.company_store
        self.employee_store = self.graph.employee_store

        self.context = SessionContext(self.graph)
        self.context.recreate_all()
        self.context.open()

        with transaction():
            self.company = Company(
                name="name"
            ).create()
class TestCloning:

    def setup(self):
        self.graph = create_object_graph(name="example", testing=True, import_name="microcosm_postgres")
        self.company_store = self.graph.company_store

        self.context = SessionContext(self.graph)
        self.context.recreate_all()
        self.context.open()

    def teardown(self):
        self.context.close()
        self.graph.postgres.dispose()

    def test_clone(self):
        with transaction():
            company = Company(
                name="name",
                type=CompanyType.private,
            ).create()
            copy = clone(company, dict(name="newname"))

        assert_that(copy.id, is_not(equal_to(company.id)))
        assert_that(self.company_store.retrieve(copy.id), is_(not_none()))
class TestEmployeeStore:

    def setup(self):
        self.graph = create_object_graph(name="example", testing=True, import_name="microcosm_postgres")
        self.company_store = self.graph.company_store
        self.employee_store = self.graph.employee_store

        self.context = SessionContext(self.graph)
        self.context.recreate_all()
        self.context.open()

        with transaction():
            self.company = Company(
                name="name"
            ).create()

    def teardown(self):
        self.context.close()
        self.graph.postgres.dispose()

    def test_create(self):
        """
        Should be able to retrieve an employee after creating it.

        """
        with transaction():
            employee = Employee(
                first="first",
                last="last",
                company_id=self.company.id,
            ).create()

        retrieved_employee = Employee.retrieve(employee.id)
        assert_that(retrieved_employee.first, is_(equal_to("first")))
        assert_that(retrieved_employee.last, is_(equal_to("last")))

    def test_create_requires_foreign_key(self):
        """
        Should not be able to create an employee without a company.

        """
        employee = Employee(
            first="first",
            last="last",
        )

        assert_that(calling(employee.create), raises(ModelIntegrityError))

    def test_update(self):
        """
        Should be able to update an employee after creating it.

        """
        with transaction():
            employee = Employee(
                first="first",
                last="last",
                company_id=self.company.id,
            ).create()

        with transaction():
            updated_employee = Employee(
                id=employee.id,
                first="Jane",
                last="Doe",
            ).update()
            assert_that(updated_employee.first, is_(equal_to("Jane")))
            assert_that(updated_employee.last, is_(equal_to("Doe")))
            assert_that(updated_employee.company_id, is_(equal_to(self.company.id)))

        with transaction():
            retrieved_employee = Employee.retrieve(employee.id)
            assert_that(retrieved_employee.first, is_(equal_to("Jane")))
            assert_that(retrieved_employee.last, is_(equal_to("Doe")))
            assert_that(Employee.count(), is_(equal_to(1)))

    def test_update_with_diff(self):
        """
        Should be able to update an employee after creating it and get a diff.

        """
        with transaction():
            employee = Employee(
                first="first",
                last="last",
                company_id=self.company.id,
            ).create()

        with transaction():
            _, diff = Employee(
                id=employee.id,
                last="Doe",
            ).update_with_diff()
            assert_that(list(diff.keys()), contains_inanyorder("last", "updated_at"))
            assert_that(diff["last"].before, is_(equal_to("last")))
            assert_that(diff["last"].after, is_(equal_to("Doe")))

        with transaction():
            retrieved_employee = Employee.retrieve(employee.id)
            assert_that(retrieved_employee.first, is_(equal_to("first")))
            assert_that(retrieved_employee.last, is_(equal_to("Doe")))
            assert_that(Employee.count(), is_(equal_to(1)))

    def test_update_not_found(self):
        """
        Should not be able to update an employee that does not exist.

        """
        with transaction():
            employee = Employee(
                first="first",
                last="last",
                company_id=self.company.id,
            )
            assert_that(calling(employee.update), raises(ModelNotFoundError))

    def test_replace(self):
        """
        Should be able to replace an employee after creating it.

        """
        with transaction():
            employee = Employee(
                first="first",
                last="last",
                company_id=self.company.id,
            ).create()

        with transaction():
            updated_employee = Employee(
                id=employee.id,
                first="Jane",
                last="Doe",
            ).replace()
            assert_that(updated_employee.first, is_(equal_to("Jane")))
            assert_that(updated_employee.last, is_(equal_to("Doe")))

        with transaction():
            retrieved_employee = Employee.retrieve(employee.id)
            assert_that(retrieved_employee.first, is_(equal_to("Jane")))
            assert_that(retrieved_employee.last, is_(equal_to("Doe")))
            assert_that(Employee.count(), is_(equal_to(1)))

    def test_replace_not_found(self):
        """
        Should be able to replace an employee that does not exist.

        """
        with transaction():
            employee = Employee(
                first="first",
                last="last",
                company_id=self.company.id,
            ).replace()

        with transaction():
            retrieved_employee = Employee.retrieve(employee.id)
            assert_that(retrieved_employee.first, is_(equal_to("first")))
            assert_that(retrieved_employee.last, is_(equal_to("last")))
            assert_that(Employee.count(), is_(equal_to(1)))

    def test_search_by_company(self):
        """
        Should be able to retrieve an employee after creating it.

        """
        with transaction():
            employee1 = Employee(
                first="first",
                last="last",
                company_id=self.company.id,
            ).create()
            employee2 = Employee(
                first="Jane",
                last="Doe",
                company_id=self.company.id,
            ).create()
            company2 = Company(
                name="other",
            ).create()
            employee3 = Employee(
                first="John",
                last="Doe",
                company_id=company2.id,
            ).create()

        assert_that(Employee.count(), is_(equal_to(3)))
        assert_that(
            [employee.last for employee in self.employee_store.search_by_company(self.company.id)],
            contains("Doe", "last"),
        )
        assert_that(
            [employee.id for employee in self.employee_store.search_by_company(self.company.id)],
            contains_inanyorder(employee1.id, employee2.id)
        )
        assert_that(
            [employee.id for employee in self.employee_store.search_by_company(company2.id)],
            contains_inanyorder(employee3.id)
        )

    def test_search_by_company_kwargs(self):
        """
        Should be able to filter searches using kwargs.

        """
        with transaction():
            employee1 = Employee(
                first="first",
                last="last",
                company_id=self.company.id,
            ).create()
            employee2 = Employee(
                first="Jane",
                last="Doe",
                company_id=self.company.id,
            ).create()
            company2 = Company(
                name="other",
            ).create()
            employee3 = Employee(
                first="John",
                last="Doe",
                company_id=company2.id,
            ).create()

        assert_that(Employee.count(), is_(equal_to(3)))
        assert_that(
            [employee.id for employee in self.employee_store.search(company_id=self.company.id, offset=0, limit=10)],
            contains_inanyorder(employee1.id, employee2.id)
        )
        assert_that(self.employee_store.count(company_id=self.company.id, offset=0, limit=10), is_(equal_to(2)))
        assert_that(
            [employee.id for employee in self.employee_store.search(company_id=company2.id, offset=0, limit=10)],
            contains_inanyorder(employee3.id)
        )
        assert_that(self.employee_store.count(company_id=company2.id, offset=0, limit=10), is_(equal_to(1)))

    def test_search_first(self):
        """
        Should be able to search for the first item with matching criteria after creation.

        """
        with transaction():
            Employee(
                first="first",
                last="last",
                company_id=self.company.id,
            ).create()
            Employee(
                first="Jane",
                last="Doe",
                company_id=self.company.id,
            ).create()

        retrieved_real_employee = self.employee_store.search_first(first="Jane")
        assert_that(retrieved_real_employee.last, is_(equal_to("Doe")))
        retrieved_fake_employee = self.employee_store.search_first(first="Tarzan")
        assert_that(retrieved_fake_employee, is_(equal_to(None)))
class TestCompany:

    def setup(self):
        self.graph = create_object_graph(name="example", testing=True, import_name="microcosm_postgres")
        self.company_store = self.graph.company_store
        self.employee_store = self.graph.employee_store

        self.context = SessionContext(self.graph)
        self.context.recreate_all()
        self.context.open()

    def teardown(self):
        self.context.close()
        self.graph.postgres.dispose()

    def test_create_retrieve_company(self):
        """
        Should be able to retrieve a company after creating it.

        """
        with transaction():
            company = Company(
                name="name",
                type=CompanyType.private,
            ).create()

        retrieved_company = Company.retrieve(company.id)
        assert_that(retrieved_company.name, is_(equal_to("name")))
        assert_that(retrieved_company.type, is_(equal_to(CompanyType.private)))

    def test_search_company(self):
        """
        Should be able to search for companies.

        """
        with transaction():
            company = Company(
                name="name",
                type=CompanyType.private,
            ).create()

        assert_that(Company.search(), contains(company))
        assert_that(Company.search(name="whatever"), is_(empty()))
        assert_that(Company.search(name=company.name), contains(company))
        # NB: filtering is skipped if None
        assert_that(Company.search(name=None), contains(company))

    def test_create_duplicate_company(self):
        """
        Should not be able to retrieve a company with a duplicate name.

        """
        with transaction():
            Company(name="name").create()

        company = Company(name="name")
        assert_that(calling(company.create), raises(DuplicateModelError))

    def test_create_delete_company(self):
        """
        Should not be able to retrieve a company after deleting it.

        """
        with transaction():
            company = Company(name="name").create()

        with transaction():
            company.delete()

        assert_that(
            calling(Company.retrieve).with_args(company.id),
            raises(ModelNotFoundError, pattern="Company not found"),
        )

    def test_create_search_count_company(self):
        """
        Should be able to search and count companies after creation.

        """
        with transaction():
            company1 = Company(name="name1").create()
            company2 = Company(name="name2").create()

        assert_that(Company.count(), is_(equal_to(2)))

        # Pagination fields do not affect count calculations
        assert_that(self.company_store.count(offset=1, limit=1), is_(equal_to(2)))

        assert_that([company.id for company in Company.search()], contains_inanyorder(company1.id, company2.id))

    def test_create_update_company(self):
        """
        Should be able to update a company after creating it.

        """
        with transaction():
            company = Company(
                name="name",
            ).create()

        with transaction():
            updated_company = Company(
                id=company.id,
                name="new_name",
            ).update()
            assert_that(updated_company.name, is_(equal_to("new_name")))

        with transaction():
            retrieved_company = Company.retrieve(company.id)
            assert_that(retrieved_company.name, is_(equal_to("new_name")))

    def test_create_update_with_diff_company(self):
        """
        Should be able to update a company after creating it and get a diff.

        """
        with transaction():
            company = Company(name="name").create()

        with transaction():
            _, diff = Company(
                id=company.id,
                name="new_name",
            ).update_with_diff()
            assert_that(list(diff.keys()), contains_inanyorder("name", "updated_at"))
            assert_that(diff["name"].before, is_(equal_to("name")))
            assert_that(diff["name"].after, is_(equal_to("new_name")))

        with transaction():
            retrieved_company = Company.retrieve(company.id)
            assert_that(retrieved_company.name, is_(equal_to("new_name")))

    def test_create_update_duplicate_company(self):
        """
        Should be not able to update a company to a duplicate name.

        """
        with transaction():
            Company(name="name1").create()
            company = Company(name="name2").create()

        company.name = "name1"
        assert_that(calling(company.update), raises(DuplicateModelError))

    def test_delete_company_with_employees(self):
        """
        Should be not able to delete a company with employees.

        """
        with transaction():
            Company(
                name="name1",
            ).create()
            company = Company(
                name="name2",
            ).create()

        with transaction():
            Employee(
                first="first",
                last="last",
                company_id=company.id,
            ).create()

        assert_that(calling(company.delete), raises(ReferencedModelError))
class TestExamples:

    def setup(self):
        self.graph = create_app(testing=True)
        self.example_store = self.graph.example_store

        self.name = "NAME"

        self.context = SessionContext(self.graph)
        self.context.recreate_all()
        self.context.open()

    def teardown(self):
        self.context.close()
        self.graph.postgres.dispose()

    def test_create(self):
        """
        Examples can be persisted.

        """
        new_example = Example(
            name=self.name,
        )

        with transaction():
            self.example_store.create(new_example)

        retrieved_example = self.example_store.retrieve(new_example.id)
        assert_that(retrieved_example, is_(equal_to(new_example)))

    def test_create_duplicate(self):
        """
        Examples enforce uniqueness on type/external id.

        """
        example1 = Example(
            name=self.name,
        )
        example2 = Example(
            name=self.name,
        )

        with transaction():
            self.example_store.create(example1)

        assert_that(
            calling(self.example_store.create).with_args(example2),
            raises(DuplicateModelError),
        )

    def test_retrieve_by_name(self):
        """
        Examples can be retrieved by name.

        """
        new_example = Example(
            name=self.name,
        )

        with transaction():
            self.example_store.create(new_example)

        retrieved_example = self.example_store.retrieve_by_name(
            self.name
        )

        assert_that(retrieved_example, is_(equal_to(new_example)))