Repository: bvanelli/actualpy
Pull request #22 (2024-05-25 05:46:40)

fix: Fix simplyFin and goCardless missing columns.
Closes https://github.com/bvanelli/actualpy/issues/20

codecov-commenter: ## [Codecov](https://app.codecov.io/gh/bvanelli/actualpy/pull/22?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Brunno+Vanelli) Report
Attention: Patch coverage is `83.33333%` with `1 lines` in your changes are missing coverage. Please review.
> Project coverage is 94.61%. Comparing base [(`24fe835`)](https://app.codecov.io/gh/bvanelli/actualpy/commit/24fe835300c7b865db9728fe2e892ab1486610b0?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Brunno+Vanelli) to head [(`07201c9`)](https://app.codecov.io/gh/bvanelli/actualpy/commit/07201c9c606e9527d548fffe3219f4f3e5b8c249?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Brunno+Vanelli).

| [Files](https://app.codecov.io/gh/bvanelli/actualpy/pull/22?dropdown=coverage&src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Brunno+Vanelli) | Patch % | Lines |
|---|---|---|
| [actual/\_\_init\_\_.py](https://app.codecov.io/gh/bvanelli/actualpy/pull/22?src=pr&el=tree&filepath=actual%2F__init__.py&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Brunno+Vanelli#diff-YWN0dWFsL19faW5pdF9fLnB5) | 50.00% | [1 Missing :warning: ](https://app.codecov.io/gh/bvanelli/actualpy/pull/22?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Brunno+Vanelli) |

:exclamation: Your organization needs to install the [Codecov GitHub app](https://github.com/apps/codecov/installations/select_target) to enable full functionality.

<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##             main      #22      +/-   ##
==========================================
- Coverage   94.67%   94.61%   -0.06%     
==========================================
  Files           9        9              
  Lines        1408     1412       +4     
==========================================
+ Hits         1333     1336       +3     
- Misses         75       76       +1     
```



</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/bvanelli/actualpy/pull/22?dropdown=coverage&src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Brunno+Vanelli).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Brunno+Vanelli).


Patch:
diff --git a/actual/__init__.py b/actual/__init__.py
index 78ea868..438f8d9 100644
--- a/actual/__init__.py
+++ b/actual/__init__.py
@@ -230,9 +230,14 @@ class Actual(ActualServer):
                 table = get_class_by_table_name(message.dataset)
                 if table is None:
                     raise ActualError(
-                        f"Actual is at a version not supported by the library: '{message.dataset}' not found"
+                        f"Actual found a table not supported by the library: table '{message.dataset}' not found"
                     )
                 column = get_attribute_by_table_name(message.dataset, message.column)
+                if column is None:
+                    raise ActualError(
+                        f"Actual found a column not supported by the library: "
+                        f"column '{message.column}' at table '{message.dataset}' not found"
+                    )
                 entry = s.get(table, message.row)
                 if not entry:
                     entry = table(id=message.row)
diff --git a/actual/database.py b/actual/database.py
index 657a407..e223afa 100644
--- a/actual/database.py
+++ b/actual/database.py
@@ -80,7 +80,7 @@ def strong_reference_session(session):
             raise ActualInvalidOperationError(
                 "Actual does not allow deleting entries, set the `tombstone` to 1 instead or call the .delete() method"
             )
-        if "refs" not in sess.info:
+        if "messages" not in sess.info:
             sess.info["messages"] = messages = []
         else:
             messages = sess.info["messages"]
@@ -95,7 +95,8 @@ def strong_reference_session(session):
     @event.listens_for(session, "after_commit")
     @event.listens_for(session, "after_soft_rollback")
     def after_commit_or_rollback(sess):
-        del sess.info["messages"]
+        if sess.info.get("messages"):
+            del sess.info["messages"]
 
     return session
 
@@ -168,6 +169,7 @@ class Accounts(BaseModel, table=True):
     tombstone: Optional[int] = Field(default=None, sa_column=Column("tombstone", Integer, server_default=text("0")))
     sort_order: Optional[float] = Field(default=None, sa_column=Column("sort_order", Float))
     type: Optional[str] = Field(default=None, sa_column=Column("type", Text))
+    account_sync_source: Optional[str] = Field(default=None, sa_column=Column("account_sync_source", Text))
 
     payee: "Payees" = Relationship(back_populates="account", sa_relationship_kwargs={"uselist": False})
     pending_transactions: List["PendingTransactions"] = Relationship(back_populates="account")


Test patch:
diff --git a/tests/test_api.py b/tests/test_api.py
new file mode 100644
index 0000000..7c5720b
--- /dev/null
+++ b/tests/test_api.py
@@ -0,0 +1,18 @@
+import pytest
+
+from actual import Actual
+from actual.exceptions import ActualError
+from actual.protobuf_models import Message
+
+
+def test_api_apply(mocker):
+    actual = Actual.__new__(Actual)
+    actual.session_maker = mocker.MagicMock()
+    # not found table
+    m = Message(dict(dataset="foo", row="foobar", column="bar"))
+    m.set_value("foobar")
+    with pytest.raises(ActualError, match="table 'foo' not found"):
+        actual.apply_changes([m])
+    m.dataset = "accounts"
+    with pytest.raises(ActualError, match="column 'bar' at table 'accounts' not found"):
+        actual.apply_changes([m])