Skip to content

tests: Test for REST API migration changes#883

Merged
Hrishabh17 merged 7 commits intomasterfrom
rest-migration-test-1
Jan 6, 2026
Merged

tests: Test for REST API migration changes#883
Hrishabh17 merged 7 commits intomasterfrom
rest-migration-test-1

Conversation

@Hrishabh17
Copy link
Member

@Hrishabh17 Hrishabh17 commented Dec 26, 2025

Summary by CodeRabbit

  • New Features

    • Enhanced Sage Intacct REST integration with improved credential handling and REST error pathways.
  • Tests

    • Large expansion of test coverage for Sage Intacct exports (bills, AP payments, charge card & charge transactions, expense reports, journal entries, reimbursements), helpers, connector flows, and REST error scenarios; added fixtures and mocks for SDKs.
  • Chores

    • Added environment-backed configuration entries to support Intacct REST credentials.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 26, 2025

Walkthrough

Renames a connector keyword for charge card line items, adds Intacct REST client credentials to environment and test settings, and introduces extensive Sage Intacct test coverage, fixtures, and REST-error handling tests across many export and connector flows.

Changes

Cohort / File(s) Summary
Connector & Config
apps/sage_intacct/connector.py, docker-compose-pipeline.yml, fyle_intacct_api/tests/settings.py
Renamed keyword in post_charge_card_transaction call: charge_card_transaction_lineitemscharge_card_transaction_line_items. Added INTACCT_CLIENT_ID and INTACCT_CLIENT_SECRET environment/settings entries.
Test Fixtures & Conftest
tests/test_sageintacct/conftest.py, tests/test_sageintacct/fixtures.py
Added mocks and pytest fixtures for IntacctRESTSDK/SageIntacctSDK, IntacctSyncedTimestamp, SageIntacctAttributesCount, expected-keys lists, and REST error response fixtures.
Export Payload Tests
tests/test_sageintacct/exports/*
tests/test_sageintacct/exports/test_ap_payments.py, .../test_bills.py, .../test_charge_card_transactions.py, .../test_expense_reports.py, .../test_journal_entries.py, .../test_reimbursements.py
Added comprehensive unit tests for payload construction and edge cases (structure, tax behavior, attachments, dates, multiple line items).
Helper Tests
tests/test_sageintacct/exports/test_helpers.py
Added tests for helper utilities: date formatting, tax calculations, location/entity lookups, and source entity resolution across mapping scenarios.
Connector & Tasks Tests
tests/test_sageintacct/test_connector.py, tests/test_sageintacct/test_tasks.py
Added extensive tests covering connector init, session/token flows, dimension sync, create/retry flows, REST error parsing/handling, and task-level status/check functions.
Workspace View Tests (REST creds)
tests/test_workspaces/test_views.py
Added tests for REST credential creation/update and error handling (InvalidToken, BadRequest, InternalServerError).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • Ashutosh619-sudo
  • ashwin1111

Poem

🐰 With hops and hops I test and play,

I mock the REST and chase bugs away.
New env keys tucked in snug and neat,
Line items renamed — tidy and sweet.
Hooray for tests — a carrot treat! 🥕

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Description check ⚠️ Warning The pull request description is completely missing. The repository requires a description following the specified template with Description and Clickup sections. Add a pull request description following the repository template, including what changes were made and relevant ClickUp link for context.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'tests: Test for REST API migration changes' accurately describes the main changeset, which adds comprehensive test coverage for REST API migration functionality across multiple test modules.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions bot added the size/XL Extra Large PR label Dec 26, 2025
@github-actions
Copy link

Coverage

Coverage Report
FileStmtsMissCoverMissing
apps
   exceptions.py471177%27, 33, 39–44, 50, 56–61, 67, 73, 79–80
apps/fyle
   actions.py124794%214, 263, 319–323
   constants.py10100% 
   helpers.py2352291%50–57, 66, 146–162, 376, 470, 477–480, 483–484
   models.py3322194%313–315, 319–321, 325–327, 331–333, 337–339, 343–345, 406, 510–531, 554, 571
   queue.py470100% 
   serializers.py410100% 
   signals.py35683%22, 55–56, 69–71
   tasks.py4887385%135–136, 139–140, 143–144, 166–167, 201–211, 223–228, 271–274, 295–299, 309–317, 355–356, 450–497, 781–785
   views.py1721591%84–91, 145, 245–246, 290–291, 316–320, 413–417
apps/internal
   actions.py39295%26–27
   helpers.py361364%18–35
   serializers.py300100% 
   views.py83199%39
apps/internal/services
   e2e_setup.py590100% 
   fixture_factory.py59395%218–220
apps/mappings
   constants.py20100% 
   exceptions.py71692%69–71, 79–81
   helpers.py300100% 
   models.py500100% 
   schedules.py150100% 
   serializers.py100100% 
   signals.py1111487%90–92, 127, 179–184, 190–194, 200–203, 209–210
   tasks.py1732983%117–118, 141–142, 145, 209–226, 254, 257, 260, 266, 269, 275, 314–316, 327, 399
   utils.py340100% 
   views.py46491%34–35, 114–115
apps/sage_intacct
   actions.py29486%21–22, 49–50
   connector.py8002597%132, 308, 320, 326, 402, 1413, 1712, 1839–1840, 1891–1892, 1913–1914, 1943–1944, 1952–1963, 1995–1996, 2016–2017
   dependent_fields.py2744285%320, 356–359, 388–397, 399–400, 402–404, 406–407, 409–410, 412–413, 417–419, 463, 483, 523–525, 571–573, 621–627, 631–632
   enums.py250100% 
   helpers.py56689%38–41, 58, 95
   models.py9396293%69–70, 220, 327, 334, 378, 399–416, 475, 487, 537, 543, 578, 628–630, 644–657, 668, 704, 756–757, 831, 870, 1070, 1164–1167, 1200, 1265, 1366–1386, 1464, 1480, 1590, 1936–1938, 2000
   queue.py1711691%45, 53, 58, 105, 130–133, 173, 187, 205–208, 243, 267–270, 305, 330–333
   serializers.py350100% 
   tasks.py136618586%90, 104, 137, 173–174, 178–181, 183, 186, 236, 270–271, 390–391, 397, 400, 443–444, 485–490, 555, 561, 569, 733–734, 754–755, 816–817, 821, 840, 855, 860, 865, 872, 878, 881–883, 886–889, 892–894, 908, 945–946, 1022–1023, 1027, 1048, 1063, 1069, 1072–1075, 1082, 1085–1087, 1090–1093, 1096–1098, 1112–1116, 1153–1154, 1223–1224, 1226, 1247, 1262, 1268, 1271–1274, 1281, 1284–1286, 1289–1292, 1295–1297, 1311–1315, 1351–1352, 1422–1423, 1426, 1447, 1462, 1468, 1474, 1481, 1487, 1490–1492, 1495–1498, 1501–1503, 1517, 1569–1570, 1631, 1643–1652, 1694, 1697–1702, 1705–1709, 1874–1878, 1974–1975, 2181–2191, 2194, 2203–2208, 2242–2244, 2278–2281, 2349–2353, 2362, 2451–2456, 2469, 2484, 2499
   utils.py8854895%97, 109, 112, 537–538, 715–719, 861, 866, 877, 1183, 1199–1205, 1214–1215, 1693–1703, 1941–1945, 1973–1977, 2005–2009, 2051–2055, 2108–2112, 2132, 2141, 2150, 2159–2160, 2171, 2194–2196
   views.py1453377%127–129, 134–135, 141–142, 185–188, 258–288, 299–314, 327–331
apps/sage_intacct/errors
   errors.py20100% 
   helpers.py26196%73
apps/sage_intacct/exports
   ap_payments.py130100% 
   bills.py280100% 
   charge_card_transactions.py220100% 
   expense_reports.py280100% 
   helpers.py56296%68, 141
   journal_entries.py76889%177–180, 316–319
   reimbursements.py130100% 
apps/tasks
   models.py690100% 
   serializers.py60100% 
   views.py370100% 
apps/users
   helpers.py120100% 
   models.py530100% 
   views.py170100% 
apps/workspaces
   actions.py46980%65, 84–85, 103, 122–133, 147
   enums.py50100% 
   helpers.py80100% 
   models.py1740100% 
   permissions.py34974%33, 59–67
   serializers.py43198%54
   signals.py310100% 
   tasks.py165995%53–59, 187–194, 235, 267–268, 379
   utils.py90100% 
   views.py318997%105–107, 134–137, 657–658
apps/workspaces/apis/advanced_settings
   serializers.py80396%260, 263, 266
   triggers.py100100% 
   views.py110100% 
apps/workspaces/apis/errors
   serializers.py200100% 
   views.py150100% 
apps/workspaces/apis/export_settings
   helpers.py730100% 
   serializers.py103397%267, 270, 273
   triggers.py39295%32–33
   views.py110100% 
apps/workspaces/apis/import_settings
   serializers.py1411887%232–238, 243–249, 257–265, 283, 286, 314, 317–318, 326
   triggers.py47198%31
   views.py330100% 
fyle_integrations_imports
   dataclasses.py310100% 
   models.py230100% 
   queues.py34585%24, 99, 136, 148–149
   signals.py100100% 
   tasks.py1097135%68–105, 114–120, 133–202, 206–221
fyle_integrations_imports/modules
   base.py1881095%75, 91–92, 95, 126, 230–231, 237–238, 351
   categories.py1773381%80, 96, 99–100, 103–104, 272–273, 283, 296, 298, 342, 351–355, 364–410
   cost_centers.py961288%132–133, 152–153, 162, 178, 180, 226, 235–239
   expense_custom_fields.py121794%83–88, 247, 263, 265, 294
   merchants.py1062576%80–83, 111–129, 155–162, 179–180, 190, 203, 205, 235, 238–242
   projects.py88990%109–110, 120, 144, 191, 205–209
   tax_groups.py180100% 
   webhook_attributes.py130695%95, 97–99, 210–211
workers
   actions.py210100% 
   helpers.py410100% 
   worker.py56591%44–45, 77–78, 125
TOTAL1021890691% 

Tests Skipped Failures Errors Time
690 0 💤 0 ❌ 0 🔥 51.731s ⏱️

@github-actions
Copy link


Diff Coverage
Diff: origin/master..HEAD, staged and unstaged changes

No lines with coverage information in this diff.

@github-actions
Copy link

Coverage

Coverage Report
FileStmtsMissCoverMissing
apps
   exceptions.py471177%27, 33, 39–44, 50, 56–61, 67, 73, 79–80
apps/fyle
   actions.py124794%214, 263, 319–323
   constants.py10100% 
   helpers.py2352291%50–57, 66, 146–162, 376, 470, 477–480, 483–484
   models.py3322194%313–315, 319–321, 325–327, 331–333, 337–339, 343–345, 406, 510–531, 554, 571
   queue.py470100% 
   serializers.py410100% 
   signals.py35683%22, 55–56, 69–71
   tasks.py4887385%135–136, 139–140, 143–144, 166–167, 201–211, 223–228, 271–274, 295–299, 309–317, 355–356, 450–497, 781–785
   views.py1721591%84–91, 145, 245–246, 290–291, 316–320, 413–417
apps/internal
   actions.py39295%26–27
   helpers.py361364%18–35
   serializers.py300100% 
   views.py83199%39
apps/internal/services
   e2e_setup.py590100% 
   fixture_factory.py59395%218–220
apps/mappings
   constants.py20100% 
   exceptions.py71692%69–71, 79–81
   helpers.py300100% 
   models.py500100% 
   schedules.py150100% 
   serializers.py100100% 
   signals.py1111487%90–92, 127, 179–184, 190–194, 200–203, 209–210
   tasks.py1732983%117–118, 141–142, 145, 209–226, 254, 257, 260, 266, 269, 275, 314–316, 327, 399
   utils.py340100% 
   views.py46491%34–35, 114–115
apps/sage_intacct
   actions.py29486%21–22, 49–50
   connector.py8002597%132, 308, 320, 326, 402, 1413, 1712, 1839–1840, 1891–1892, 1913–1914, 1943–1944, 1952–1963, 1995–1996, 2016–2017
   dependent_fields.py2744285%320, 356–359, 388–397, 399–400, 402–404, 406–407, 409–410, 412–413, 417–419, 463, 483, 523–525, 571–573, 621–627, 631–632
   enums.py250100% 
   helpers.py56689%38–41, 58, 95
   models.py9396293%69–70, 220, 327, 334, 378, 399–416, 475, 487, 537, 543, 578, 628–630, 644–657, 668, 704, 756–757, 831, 870, 1070, 1164–1167, 1200, 1265, 1366–1386, 1464, 1480, 1590, 1936–1938, 2000
   queue.py1711691%45, 53, 58, 105, 130–133, 173, 187, 205–208, 243, 267–270, 305, 330–333
   serializers.py350100% 
   tasks.py136618586%90, 104, 137, 173–174, 178–181, 183, 186, 236, 270–271, 390–391, 397, 400, 443–444, 485–490, 555, 561, 569, 733–734, 754–755, 816–817, 821, 840, 855, 860, 865, 872, 878, 881–883, 886–889, 892–894, 908, 945–946, 1022–1023, 1027, 1048, 1063, 1069, 1072–1075, 1082, 1085–1087, 1090–1093, 1096–1098, 1112–1116, 1153–1154, 1223–1224, 1226, 1247, 1262, 1268, 1271–1274, 1281, 1284–1286, 1289–1292, 1295–1297, 1311–1315, 1351–1352, 1422–1423, 1426, 1447, 1462, 1468, 1474, 1481, 1487, 1490–1492, 1495–1498, 1501–1503, 1517, 1569–1570, 1631, 1643–1652, 1694, 1697–1702, 1705–1709, 1874–1878, 1974–1975, 2181–2191, 2194, 2203–2208, 2242–2244, 2278–2281, 2349–2353, 2362, 2451–2456, 2469, 2484, 2499
   utils.py8854895%97, 109, 112, 537–538, 715–719, 861, 866, 877, 1183, 1199–1205, 1214–1215, 1693–1703, 1941–1945, 1973–1977, 2005–2009, 2051–2055, 2108–2112, 2132, 2141, 2150, 2159–2160, 2171, 2194–2196
   views.py1453377%127–129, 134–135, 141–142, 185–188, 258–288, 299–314, 327–331
apps/sage_intacct/errors
   errors.py20100% 
   helpers.py26196%73
apps/sage_intacct/exports
   ap_payments.py130100% 
   bills.py280100% 
   charge_card_transactions.py220100% 
   expense_reports.py280100% 
   helpers.py56296%68, 141
   journal_entries.py76889%177–180, 316–319
   reimbursements.py130100% 
apps/tasks
   models.py690100% 
   serializers.py60100% 
   views.py370100% 
apps/users
   helpers.py120100% 
   models.py530100% 
   views.py170100% 
apps/workspaces
   actions.py46980%65, 84–85, 103, 122–133, 147
   enums.py50100% 
   helpers.py80100% 
   models.py1740100% 
   permissions.py34974%33, 59–67
   serializers.py43198%54
   signals.py310100% 
   tasks.py165995%53–59, 187–194, 235, 267–268, 379
   utils.py90100% 
   views.py318997%105–107, 134–137, 657–658
apps/workspaces/apis/advanced_settings
   serializers.py80396%260, 263, 266
   triggers.py100100% 
   views.py110100% 
apps/workspaces/apis/errors
   serializers.py200100% 
   views.py150100% 
apps/workspaces/apis/export_settings
   helpers.py730100% 
   serializers.py103397%267, 270, 273
   triggers.py39295%32–33
   views.py110100% 
apps/workspaces/apis/import_settings
   serializers.py1411887%232–238, 243–249, 257–265, 283, 286, 314, 317–318, 326
   triggers.py47198%31
   views.py330100% 
fyle_integrations_imports
   dataclasses.py310100% 
   models.py230100% 
   queues.py34585%24, 99, 136, 148–149
   signals.py100100% 
   tasks.py1097135%68–105, 114–120, 133–202, 206–221
fyle_integrations_imports/modules
   base.py1881095%75, 91–92, 95, 126, 230–231, 237–238, 351
   categories.py1773381%80, 96, 99–100, 103–104, 272–273, 283, 296, 298, 342, 351–355, 364–410
   cost_centers.py961288%132–133, 152–153, 162, 178, 180, 226, 235–239
   expense_custom_fields.py121794%83–88, 247, 263, 265, 294
   merchants.py1062576%80–83, 111–129, 155–162, 179–180, 190, 203, 205, 235, 238–242
   projects.py88990%109–110, 120, 144, 191, 205–209
   tax_groups.py180100% 
   webhook_attributes.py130695%95, 97–99, 210–211
workers
   actions.py210100% 
   helpers.py410100% 
   worker.py56591%44–45, 77–78, 125
TOTAL1021890691% 

Tests Skipped Failures Errors Time
690 0 💤 0 ❌ 0 🔥 47.155s ⏱️

@github-actions
Copy link


Diff Coverage
Diff: origin/master..HEAD, staged and unstaged changes

No lines with coverage information in this diff.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (7)
tests/test_sageintacct/exports/test_reimbursements.py (1)

7-7: Minor test hygiene: unused db arg and tiny datetime flakiness

  • db is only used to activate the Django DB fixture, so Ruff flags it as unused (ARG001). If you care about a clean lint run, consider renaming it to _db in these tests to signal intentional use.
  • In test_construct_reimbursement_payload_payment_date, both the code under test and the assertion call datetime.now() separately. The chance of crossing midnight between the two is tiny but non‑zero; if this ever bites you, you could inject the date into construct_reimbursement_payload or freeze time in the test. For now it’s acceptable as-is.

Also applies to: 32-32, 56-72

tests/test_sageintacct/exports/test_bills.py (1)

9-9: Bill payload tests look solid; only lint noise around db fixture

The scenarios around tax codes, supdoc handling, refunds, and dimensions line up with construct_bill_payload / construct_bill_line_item_payload. The only thing Ruff will complain about is the unused db argument in these tests; if you want to silence ARG001, rename it to _db while keeping the fixture.

Also applies to: 31-31, 54-54, 73-73, 95-95, 117-117

tests/test_workspaces/test_views.py (1)

12-16: REST connection tests are well‑structured; hardcoded tokens may need S105 suppression only if linting tests

The new tests around handle_sage_intacct_rest_api_connection_* cover both happy paths (new/existing credentials) and REST error scenarios (invalid token, bad request, internal server error) in a way that matches the view snippet and feature‑flag behavior. The access_token test values Ruff flags (S105/S106) are harmless here; if your linters run on tests, you can either adjust config to ignore S105 in tests/ or add # noqa: S105 on those specific lines.

Also applies to: 765-987

tests/test_sageintacct/exports/test_journal_entries.py (1)

17-403: Comprehensive journal entry tests; only minor db lint noise

The journal entry tests cover the important branches (tax codes, brand‑id switch, supdoc handling, negative/refund amounts, single vs multi credit lines, billable flags, CCC vs PERSONAL mappings) and align with the helper implementations you shared. The only minor issue is Ruff’s ARG001 on unused db—if you want to appease it, rename the arg to _db while still requesting the fixture.

tests/test_sageintacct/test_tasks.py (1)

16-20: REST error‑handling and status tests are thorough; remaining issues are cosmetic

  • The new imports for IntacctRESTBadRequestError / IntacctRESTInvalidTokenError / IntacctRESTInternalServerError and the added tests for handle_sage_intacct_rest_errors, create_ap_payment (REST paths), and check_sage_intacct_object_status_rest give good coverage across detail/no‑detail, invalid JSON, token expiry, internal errors, and “skip vs fail” semantics.
  • The db fixture parameters in these new tests are only used to activate Django’s DB, so Ruff flags ARG001; if you want a clean lint run, rename them to _db (and similarly consider _args, _kwargs on the dummy lambda used with import_string).
  • Very minor: test_handle_sage_intacct_rest_errors_with_string_response has a docstring that says “response is already a dict” while the name says “string response”; if that ever causes confusion, consider aligning name/docstring to the actual scenario you’re testing.

Also applies to: 2296-3200

tests/test_sageintacct/test_connector.py (1)

26-26: Connector and sync tests are solid; lots of benign Ruff ARG001/RUF059 in fixtures/mocks

The new tests exercise the REST connector session handling, all the sync_* entry points (including upper‑limit skipping vs legacy behavior), and posting/retrieving all the relevant Intacct objects. The numerous Ruff ARG001 / RUF059 warnings (unused db / create_intacct_synced_timestamp / create_sage_intacct_attributes_count params and unused unpacked mock classes like mock_rest_sdk_class) are cosmetic: if you want to quiet them, you can rename arguments to _db / _create_intacct_synced_timestamp etc., and prefix unused unpacked variables with _ when you only need the instance.

Also applies to: 56-57, 81-321

tests/test_sageintacct/exports/test_helpers.py (1)

19-79: Helper tests align with implementation; consider firming up one conditional and quieting lint

  • The tests for format_transaction_date, get_tax_exclusive_amount, get_tax_solution_id_or_none, get_location_id_for_journal_entry, and get_source_entity_id all match the helper semantics from helpers.py and give good coverage of both “found” and “not found” cases.
  • In test_get_tax_solution_id_or_none_with_location_entity, the if line_items: guard means the test becomes a no‑op if fixtures ever change and no BillLineitem exists; you might want to assert that line_items is non‑empty first (or create a fresh bill/line item via a fixture) so the behavior is always exercised.
  • As elsewhere, the db argument is only there to activate the DB fixture; renaming it to _db would silence Ruff’s ARG001 if you care.

Also applies to: 81-132, 188-257

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ed8ee29 and cfc1b6a.

📒 Files selected for processing (16)
  • apps/sage_intacct/connector.py
  • docker-compose-pipeline.yml
  • fyle_intacct_api/tests/settings.py
  • tests/test_sageintacct/conftest.py
  • tests/test_sageintacct/exports/__init__.py
  • tests/test_sageintacct/exports/test_ap_payments.py
  • tests/test_sageintacct/exports/test_bills.py
  • tests/test_sageintacct/exports/test_charge_card_transactions.py
  • tests/test_sageintacct/exports/test_expense_reports.py
  • tests/test_sageintacct/exports/test_helpers.py
  • tests/test_sageintacct/exports/test_journal_entries.py
  • tests/test_sageintacct/exports/test_reimbursements.py
  • tests/test_sageintacct/fixtures.py
  • tests/test_sageintacct/test_connector.py
  • tests/test_sageintacct/test_tasks.py
  • tests/test_workspaces/test_views.py
🧰 Additional context used
🧬 Code graph analysis (8)
tests/test_sageintacct/exports/test_charge_card_transactions.py (3)
apps/workspaces/models.py (1)
  • Configuration (108-169)
apps/sage_intacct/exports/charge_card_transactions.py (2)
  • construct_charge_card_transaction_payload (12-55)
  • construct_charge_card_transaction_line_item_payload (58-136)
tests/test_sageintacct/conftest.py (1)
  • create_charge_card_transaction (95-114)
tests/test_sageintacct/conftest.py (2)
apps/workspaces/models.py (3)
  • Configuration (108-169)
  • Workspace (83-105)
  • IntacctSyncedTimestamp (303-356)
apps/sage_intacct/models.py (1)
  • SageIntacctAttributesCount (2083-2131)
tests/test_sageintacct/exports/test_expense_reports.py (2)
apps/sage_intacct/exports/expense_reports.py (2)
  • construct_expense_report_payload (11-50)
  • construct_expense_report_line_item_payload (53-139)
tests/test_sageintacct/conftest.py (1)
  • create_expense_report (50-62)
tests/test_sageintacct/exports/test_bills.py (3)
apps/workspaces/models.py (1)
  • Configuration (108-169)
apps/sage_intacct/exports/bills.py (2)
  • construct_bill_payload (13-65)
  • construct_bill_line_item_payload (68-145)
tests/test_sageintacct/conftest.py (1)
  • create_bill (35-46)
tests/test_sageintacct/exports/test_helpers.py (1)
apps/sage_intacct/exports/helpers.py (3)
  • format_transaction_date (18-28)
  • get_location_id_for_journal_entry (82-107)
  • get_source_entity_id (144-173)
tests/test_workspaces/test_views.py (2)
apps/workspaces/models.py (3)
  • FeatureConfig (259-300)
  • SageIntacctCredential (172-198)
  • Workspace (83-105)
apps/workspaces/views.py (9)
  • get (74-113)
  • get (164-187)
  • get (306-325)
  • get (598-616)
  • get (626-637)
  • get (647-663)
  • get (686-703)
  • delete (294-304)
  • delete (586-596)
tests/test_sageintacct/exports/test_ap_payments.py (2)
apps/sage_intacct/exports/ap_payments.py (1)
  • construct_ap_payment_payload (9-54)
tests/test_sageintacct/conftest.py (1)
  • create_ap_payment (118-126)
tests/test_sageintacct/exports/test_reimbursements.py (2)
apps/sage_intacct/exports/reimbursements.py (1)
  • construct_reimbursement_payload (10-50)
tests/test_sageintacct/conftest.py (1)
  • create_sage_intacct_reimbursement (83-91)
🪛 Ruff (0.14.10)
tests/test_sageintacct/exports/test_charge_card_transactions.py

9-9: Unused function argument: db

(ARG001)


31-31: Unused function argument: db

(ARG001)


51-51: Unused function argument: db

(ARG001)


71-71: Unused function argument: db

(ARG001)


90-90: Unused function argument: db

(ARG001)


113-113: Unused function argument: db

(ARG001)

tests/test_sageintacct/conftest.py

353-353: Possible hardcoded password assigned to: "access_token"

(S105)


369-369: Unused function argument: db

(ARG001)


395-395: Unused function argument: db

(ARG001)

tests/test_sageintacct/exports/test_expense_reports.py

8-8: Unused function argument: db

(ARG001)


30-30: Unused function argument: db

(ARG001)


49-49: Unused function argument: db

(ARG001)


71-71: Unused function argument: db

(ARG001)


93-93: Unused function argument: db

(ARG001)


115-115: Unused function argument: db

(ARG001)

tests/test_sageintacct/exports/test_journal_entries.py

17-17: Unused function argument: db

(ARG001)


40-40: Unused function argument: db

(ARG001)


64-64: Unused function argument: db

(ARG001)


83-83: Unused function argument: db

(ARG001)


105-105: Unused function argument: db

(ARG001)


128-128: Unused function argument: db

(ARG001)


151-151: Unused function argument: db

(ARG001)


180-180: Unused function argument: db

(ARG001)


204-204: Unused function argument: db

(ARG001)


229-229: Unused function argument: db

(ARG001)


253-253: Unused function argument: db

(ARG001)


276-276: Unused function argument: db

(ARG001)


301-301: Unused function argument: db

(ARG001)


327-327: Unused function argument: db

(ARG001)


352-352: Unused function argument: db

(ARG001)


379-379: Unused function argument: db

(ARG001)

tests/test_sageintacct/test_connector.py

26-26: Unused function argument: db

(ARG001)


39-39: Unused function argument: db

(ARG001)


52-52: Unused function argument: db

(ARG001)


56-56: Unpacked variable mock_rest_sdk_class is never used

Prefix it with an underscore or any other dummy variable pattern

(RUF059)


57-57: Unpacked variable mock_soap_instance is never used

Prefix it with an underscore or any other dummy variable pattern

(RUF059)


67-67: Unused function argument: db

(ARG001)


67-67: Unused function argument: mock_intacct_sdk

(ARG001)


72-72: Possible hardcoded password assigned to: "access_token"

(S105)


78-78: Possible hardcoded password assigned to: "access_token"

(S105)


81-81: Unused function argument: db

(ARG001)


81-81: Unused function argument: create_intacct_synced_timestamp

(ARG001)


81-81: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


99-99: Unused function argument: db

(ARG001)


99-99: Unused function argument: create_intacct_synced_timestamp

(ARG001)


99-99: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


126-126: Unused function argument: db

(ARG001)


126-126: Unused function argument: create_intacct_synced_timestamp

(ARG001)


126-126: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


144-144: Unused function argument: db

(ARG001)


144-144: Unused function argument: create_intacct_synced_timestamp

(ARG001)


144-144: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


168-168: Unused function argument: db

(ARG001)


168-168: Unused function argument: create_intacct_synced_timestamp

(ARG001)


168-168: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


186-186: Unused function argument: db

(ARG001)


186-186: Unused function argument: create_intacct_synced_timestamp

(ARG001)


186-186: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


211-211: Unused function argument: db

(ARG001)


211-211: Unused function argument: create_intacct_synced_timestamp

(ARG001)


211-211: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


236-236: Unused function argument: db

(ARG001)


236-236: Unused function argument: create_intacct_synced_timestamp

(ARG001)


236-236: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


253-253: Unused function argument: db

(ARG001)


253-253: Unused function argument: create_intacct_synced_timestamp

(ARG001)


253-253: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


270-270: Unused function argument: db

(ARG001)


270-270: Unused function argument: create_intacct_synced_timestamp

(ARG001)


270-270: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


287-287: Unused function argument: db

(ARG001)


287-287: Unused function argument: create_intacct_synced_timestamp

(ARG001)


287-287: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


304-304: Unused function argument: db

(ARG001)


304-304: Unused function argument: create_intacct_synced_timestamp

(ARG001)


304-304: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


321-321: Unused function argument: db

(ARG001)


321-321: Unused function argument: create_intacct_synced_timestamp

(ARG001)


321-321: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


338-338: Unused function argument: db

(ARG001)


338-338: Unused function argument: create_intacct_synced_timestamp

(ARG001)


338-338: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


355-355: Unused function argument: db

(ARG001)


355-355: Unused function argument: create_intacct_synced_timestamp

(ARG001)


355-355: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


372-372: Unused function argument: db

(ARG001)


372-372: Unused function argument: create_intacct_synced_timestamp

(ARG001)


372-372: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


393-393: Unused function argument: db

(ARG001)


393-393: Unused function argument: create_intacct_synced_timestamp

(ARG001)


393-393: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


417-417: Unused function argument: db

(ARG001)


433-433: Unused function argument: db

(ARG001)


449-449: Unused function argument: db

(ARG001)


449-449: Unused function argument: create_intacct_synced_timestamp

(ARG001)


449-449: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


474-474: Unused function argument: db

(ARG001)


494-494: Unused function argument: db

(ARG001)


520-520: Unused function argument: db

(ARG001)


542-542: Unused function argument: db

(ARG001)


565-565: Unused function argument: db

(ARG001)


581-581: Unused function argument: db

(ARG001)


599-599: Unused function argument: db

(ARG001)


617-617: Unused function argument: db

(ARG001)


635-635: Unused function argument: db

(ARG001)


653-653: Unused function argument: db

(ARG001)


671-671: Unused function argument: db

(ARG001)


675-675: Unpacked variable mock_rest_sdk_class is never used

Prefix it with an underscore or any other dummy variable pattern

(RUF059)


676-676: Unpacked variable mock_soap_sdk_class is never used

Prefix it with an underscore or any other dummy variable pattern

(RUF059)


690-690: Unused function argument: db

(ARG001)


705-705: Unused function argument: db

(ARG001)


727-727: Unused function argument: db

(ARG001)


744-744: Unused function argument: db

(ARG001)


761-761: Unused function argument: db

(ARG001)


778-778: Unused function argument: db

(ARG001)


795-795: Unused function argument: db

(ARG001)


812-812: Unused function argument: db

(ARG001)


828-828: Unused function argument: db

(ARG001)


844-844: Unused function argument: db

(ARG001)


860-860: Unused function argument: db

(ARG001)


876-876: Unused function argument: db

(ARG001)


876-876: Unused function argument: create_intacct_synced_timestamp

(ARG001)


876-876: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


903-903: Unused function argument: db

(ARG001)


903-903: Unused function argument: create_intacct_synced_timestamp

(ARG001)


903-903: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


927-927: Unused function argument: db

(ARG001)


927-927: Unused function argument: create_intacct_synced_timestamp

(ARG001)


927-927: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


952-952: Unused function argument: db

(ARG001)


952-952: Unused function argument: create_intacct_synced_timestamp

(ARG001)


952-952: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


976-976: Unused function argument: db

(ARG001)


976-976: Unused function argument: create_intacct_synced_timestamp

(ARG001)


976-976: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


1000-1000: Unused function argument: db

(ARG001)


1000-1000: Unused function argument: create_intacct_synced_timestamp

(ARG001)


1000-1000: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


1024-1024: Unused function argument: db

(ARG001)


1024-1024: Unused function argument: create_intacct_synced_timestamp

(ARG001)


1024-1024: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


1048-1048: Unused function argument: db

(ARG001)


1048-1048: Unused function argument: create_intacct_synced_timestamp

(ARG001)


1048-1048: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


1072-1072: Unused function argument: db

(ARG001)


1072-1072: Unused function argument: create_intacct_synced_timestamp

(ARG001)


1072-1072: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


1096-1096: Unused function argument: db

(ARG001)


1096-1096: Unused function argument: create_intacct_synced_timestamp

(ARG001)


1096-1096: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


1120-1120: Unused function argument: db

(ARG001)


1120-1120: Unused function argument: create_intacct_synced_timestamp

(ARG001)


1120-1120: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


1144-1144: Unused function argument: db

(ARG001)


1144-1144: Unused function argument: create_intacct_synced_timestamp

(ARG001)


1144-1144: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


1168-1168: Unused function argument: db

(ARG001)


1168-1168: Unused function argument: create_intacct_synced_timestamp

(ARG001)


1168-1168: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


1192-1192: Unused function argument: db

(ARG001)


1192-1192: Unused function argument: create_intacct_synced_timestamp

(ARG001)


1192-1192: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


1231-1231: Unused function argument: db

(ARG001)


1231-1231: Unused function argument: create_intacct_synced_timestamp

(ARG001)


1231-1231: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


1262-1262: Unused function argument: db

(ARG001)


1262-1262: Unused function argument: create_intacct_synced_timestamp

(ARG001)


1262-1262: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


1289-1289: Unused function argument: db

(ARG001)


1289-1289: Unused function argument: create_intacct_synced_timestamp

(ARG001)


1289-1289: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


1311-1311: Unused function argument: db

(ARG001)


1311-1311: Unused function argument: create_intacct_synced_timestamp

(ARG001)


1311-1311: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


1330-1330: Unused function argument: db

(ARG001)


1330-1330: Unused function argument: create_intacct_synced_timestamp

(ARG001)


1330-1330: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


1352-1352: Unused function argument: db

(ARG001)


1352-1352: Unused function argument: create_intacct_synced_timestamp

(ARG001)


1352-1352: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


1370-1370: Unused function argument: db

(ARG001)


1393-1393: Unused function argument: db

(ARG001)


1425-1425: Unused function argument: db

(ARG001)


1455-1455: Unused function argument: db

(ARG001)


1485-1485: Unused function argument: db

(ARG001)


1515-1515: Unused function argument: db

(ARG001)


1545-1545: Unused function argument: db

(ARG001)


1567-1567: Unused function argument: db

(ARG001)


1591-1591: Unused function argument: db

(ARG001)


1644-1644: Unused function argument: db

(ARG001)


1681-1681: Unused function argument: db

(ARG001)


1718-1718: Unused function argument: db

(ARG001)


1744-1744: Unused function argument: db

(ARG001)


1744-1744: Unused function argument: create_intacct_synced_timestamp

(ARG001)


1744-1744: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


1776-1776: Unused function argument: db

(ARG001)


1776-1776: Unused function argument: create_intacct_synced_timestamp

(ARG001)


1776-1776: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


1801-1801: Unused function argument: db

(ARG001)


1801-1801: Unused function argument: create_intacct_synced_timestamp

(ARG001)


1801-1801: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


1833-1833: Unused function argument: db

(ARG001)


1833-1833: Unused function argument: create_intacct_synced_timestamp

(ARG001)


1833-1833: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


1858-1858: Unused function argument: db

(ARG001)


1858-1858: Unused function argument: create_intacct_synced_timestamp

(ARG001)


1858-1858: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


1882-1882: Unused function argument: db

(ARG001)


1882-1882: Unused function argument: create_intacct_synced_timestamp

(ARG001)


1882-1882: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


1906-1906: Unused function argument: db

(ARG001)


1906-1906: Unused function argument: create_intacct_synced_timestamp

(ARG001)


1906-1906: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


1939-1939: Unused function argument: db

(ARG001)


1962-1962: Unused function argument: db

(ARG001)


1984-1984: Unused function argument: db

(ARG001)


2004-2004: Unused function argument: db

(ARG001)


2041-2041: Unused function argument: db

(ARG001)


2085-2085: Unused function argument: db

(ARG001)


2127-2127: Unused function argument: db

(ARG001)


2174-2174: Unused function argument: db

(ARG001)


2207-2207: Unused function argument: db

(ARG001)


2240-2240: Unused function argument: db

(ARG001)


2273-2273: Unused function argument: db

(ARG001)


2303-2303: Unused function argument: db

(ARG001)


2333-2333: Unused function argument: db

(ARG001)

tests/test_sageintacct/exports/test_bills.py

9-9: Unused function argument: db

(ARG001)


31-31: Unused function argument: db

(ARG001)


54-54: Unused function argument: db

(ARG001)


73-73: Unused function argument: db

(ARG001)


95-95: Unused function argument: db

(ARG001)


117-117: Unused function argument: db

(ARG001)

tests/test_sageintacct/test_tasks.py

2296-2296: Unused function argument: db

(ARG001)


2332-2332: Unused function argument: db

(ARG001)


2362-2362: Unused function argument: db

(ARG001)


2390-2390: Unused function argument: db

(ARG001)


2417-2417: Unused function argument: db

(ARG001)


2446-2446: Unused function argument: db

(ARG001)


2494-2494: Unused function argument: db

(ARG001)


2549-2549: Unused function argument: db

(ARG001)


2609-2609: Unused function argument: db

(ARG001)


2659-2659: Unused function argument: db

(ARG001)


2708-2708: Unused function argument: db

(ARG001)


2757-2757: Unused function argument: db

(ARG001)


2765-2765: Unused lambda argument: args

(ARG005)


2765-2765: Unused lambda argument: kwargs

(ARG005)


2776-2776: Unpacked variable task_log is never used

Prefix it with an underscore or any other dummy variable pattern

(RUF059)


2812-2812: Unused function argument: db

(ARG001)


2827-2827: Unused function argument: db

(ARG001)


2833-2833: Unpacked variable expense_report_lineitems is never used

Prefix it with an underscore or any other dummy variable pattern

(RUF059)


2861-2861: Unused function argument: db

(ARG001)


2876-2876: Unused function argument: db

(ARG001)


2919-2919: Unused function argument: db

(ARG001)


2967-2967: Unused function argument: db

(ARG001)


3005-3005: Unused function argument: db

(ARG001)


3042-3042: Unused function argument: db

(ARG001)


3073-3073: Unused function argument: db

(ARG001)


3093-3093: Unused function argument: db

(ARG001)


3113-3113: Unused function argument: db

(ARG001)


3138-3138: Unused function argument: db

(ARG001)


3163-3163: Unused function argument: db

(ARG001)


3183-3183: Unused function argument: db

(ARG001)

tests/test_sageintacct/exports/test_helpers.py

19-19: Unused function argument: db

(ARG001)


29-29: Unused function argument: db

(ARG001)


39-39: Unused function argument: db

(ARG001)


65-65: Unused function argument: db

(ARG001)


81-81: Unused function argument: db

(ARG001)


101-101: Unused function argument: db

(ARG001)


133-133: Unused function argument: db

(ARG001)


148-148: Unused function argument: db

(ARG001)


171-171: Unused function argument: db

(ARG001)


188-188: Unused function argument: db

(ARG001)


237-237: Unused function argument: db

(ARG001)

tests/test_workspaces/test_views.py

781-781: Possible hardcoded password assigned to: "access_token"

(S105)


806-806: Possible hardcoded password assigned to: "access_token"

(S105)


832-832: Possible hardcoded password assigned to argument: "access_token"

(S106)


838-838: Possible hardcoded password assigned to: "access_token"

(S105)


864-864: Possible hardcoded password assigned to: "access_token"

(S105)

tests/test_sageintacct/exports/test_ap_payments.py

7-7: Unused function argument: db

(ARG001)


33-33: Unused function argument: db

(ARG001)


57-57: Unused function argument: db

(ARG001)


76-76: Unused function argument: db

(ARG001)

tests/test_sageintacct/exports/test_reimbursements.py

7-7: Unused function argument: db

(ARG001)


32-32: Unused function argument: db

(ARG001)


56-56: Unused function argument: db

(ARG001)

🔇 Additional comments (10)
docker-compose-pipeline.yml (1)

31-32: LGTM! Test credentials configured correctly.

The addition of INTACCT_CLIENT_ID and INTACCT_CLIENT_SECRET environment variables aligns with the REST API migration and provides the necessary configuration for integration tests.

fyle_intacct_api/tests/settings.py (1)

289-290: LGTM! Settings properly configured for REST API integration.

The new settings follow the existing pattern for environment-based configuration and align with the docker-compose environment variables.

tests/test_sageintacct/fixtures.py (1)

874-952: LGTM! Comprehensive test fixtures for REST API payloads.

The expected keys fixtures and REST error response fixtures provide thorough test coverage for:

  • All export payload types (bills, expense reports, charge card transactions, journal entries, reimbursements, AP payments)
  • Both detailed and simplified error response structures

This will enable robust validation of payload construction across the codebase.

apps/sage_intacct/connector.py (1)

1957-1957: LGTM! Parameter naming consistency improved.

The parameter name change from charge_card_transaction_lineitems to charge_card_transaction_line_items aligns with the function signature and improves consistency across the codebase.

tests/test_sageintacct/exports/test_charge_card_transactions.py (1)

1-132: LGTM! Comprehensive test coverage for charge card transaction payloads.

The test suite thoroughly validates:

  • Payload structure and required keys
  • Tax code handling (enabled/disabled scenarios)
  • Attachment handling (with/without supdoc_id)
  • Line item payload construction with proper dimensions

Note: The static analysis warnings about unused db parameters are false positives—the db fixture is required by pytest-django to set up the test database, even when not directly referenced in the test code.

tests/test_sageintacct/exports/test_ap_payments.py (1)

1-92: LGTM! Thorough validation of AP payment payload construction.

The test suite effectively validates:

  • Payload structure with required keys
  • Financial entity, currency, vendor, and payment method mappings
  • Details structure with proper bill references
  • Payment date formatting (today's date)
  • Multiple line items handling

Note: The static analysis warnings about unused db parameters are false positives—the db fixture is required by pytest-django for database setup.

tests/test_sageintacct/conftest.py (3)

2-2: LGTM! Enhanced test imports for REST API test fixtures.

The additional imports support the new mock fixtures and test data initialization for Sage Intacct REST API integration testing.

Also applies to: 10-10, 29-31


348-366: LGTM! Well-structured SDK mock fixtures.

The mock fixtures for IntacctRESTSDK and SageIntacctSDK properly isolate external dependencies and provide clean test doubles for integration tests.

Note: The static analysis warning about a "hardcoded password" on line 353 is a false positive—this is a mock access token value used only in tests.


368-405: LGTM! Test data fixtures properly initialized.

The fixtures for IntacctSyncedTimestamp and SageIntacctAttributesCount correctly set up the required test state with sensible defaults.

Note: The static analysis warnings about unused db parameters are false positives—the db fixture is required by pytest-django for database setup.

tests/test_sageintacct/exports/test_expense_reports.py (1)

1-133: LGTM! Comprehensive expense report payload validation.

The test suite thoroughly validates:

  • Complete payload structure with required keys and state mappings
  • Employee and currency field mappings
  • Attachment handling (with/without supdoc_id)
  • Line item payload construction with proper dimensions
  • Mutually exclusive expense_type_id vs. gl_account_number logic
  • Tax code and amount handling

Note: The static analysis warnings about unused db parameters are false positives—the db fixture is required by pytest-django for database setup.

Comment on lines +1393 to +1423
def test_get_or_create_vendor_with_bad_request_error(db, mock_intacct_sdk):
"""
Test get_or_create_vendor handles BadRequestError for duplicate vendor
"""
_, mock_instance = mock_intacct_sdk

error_response = {
'ia::result': {
'ia::error': {
'details': 'Another record with the value already exists'
}
}
}

mock_instance.vendors.post.side_effect = BadRequestError(
msg='Duplicate',
response=str(error_response)
)
mock_instance.vendors.get_all_generator.return_value = iter([[
{'id': 'VND001', 'name': 'Duplicate Vendor', 'status': 'active', 'contacts.default.email1': 'dup@test.com'}
]])

manager = SageIntacctObjectCreationManager(workspace_id=1)
vendor = manager.get_or_create_vendor(
vendor_name='Duplicate Vendor',
email='dup@test.com',
create=True
)

assert vendor is None or vendor is not None

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Tautological assertion in test_get_or_create_vendor_with_bad_request_error

assert vendor is None or vendor is not None is always true, so this test only verifies that no exception is raised. If you want this case to be meaningful, assert something about the actual behavior (e.g., that get_or_create_vendor returns None, or that it logs/handles the BadRequestError in a particular way), or drop the assertion and rename the test to make its intent explicit.

🧰 Tools
🪛 Ruff (0.14.10)

1393-1393: Unused function argument: db

(ARG001)

🤖 Prompt for AI Agents
In tests/test_sageintacct/test_connector.py around lines 1393 to 1423, the
assertion `assert vendor is None or vendor is not None` is tautological; replace
it with a meaningful check that reflects expected behavior — for example, assert
that the manager returns the existing vendor by using `assert vendor is not None
and vendor.get('id') == 'VND001'` (or if the intended behavior is to return
None, assert `vendor is None`), and update the test name if you change the
asserted outcome to keep intent clear.

@github-actions
Copy link

github-actions bot commented Jan 6, 2026

Coverage

Coverage Report
FileStmtsMissCoverMissing
apps
   exceptions.py471177%27, 33, 39–44, 50, 56–61, 67, 73, 79–80
apps/fyle
   actions.py124794%214, 263, 319–323
   constants.py10100% 
   helpers.py2352291%50–57, 66, 146–162, 376, 470, 477–480, 483–484
   models.py3322194%313–315, 319–321, 325–327, 331–333, 337–339, 343–345, 406, 510–531, 554, 571
   queue.py470100% 
   serializers.py410100% 
   signals.py35683%22, 55–56, 69–71
   tasks.py4887385%135–136, 139–140, 143–144, 166–167, 201–211, 223–228, 271–274, 295–299, 309–317, 355–356, 450–497, 781–785
   views.py1721591%84–91, 145, 245–246, 290–291, 316–320, 413–417
apps/internal
   actions.py39295%26–27
   helpers.py361364%18–35
   serializers.py300100% 
   views.py83199%39
apps/internal/services
   e2e_setup.py590100% 
   fixture_factory.py59395%218–220
apps/mappings
   constants.py20100% 
   exceptions.py71692%69–71, 79–81
   helpers.py300100% 
   models.py500100% 
   schedules.py150100% 
   serializers.py100100% 
   signals.py1111487%90–92, 127, 179–184, 190–194, 200–203, 209–210
   tasks.py1732983%117–118, 141–142, 145, 209–226, 254, 257, 260, 266, 269, 275, 314–316, 327, 399
   utils.py340100% 
   views.py46491%34–35, 114–115
apps/sage_intacct
   actions.py29486%21–22, 49–50
   connector.py8052597%133, 309, 321, 327, 403, 1414, 1713, 1840–1841, 1892–1893, 1914–1915, 1944–1945, 1953–1964, 1996–1997, 2017–2018
   dependent_fields.py2744285%320, 356–359, 388–397, 399–400, 402–404, 406–407, 409–410, 412–413, 417–419, 463, 483, 523–525, 571–573, 621–627, 631–632
   enums.py250100% 
   helpers.py56689%38–41, 58, 95
   models.py9396293%69–70, 220, 327, 334, 378, 399–416, 475, 487, 537, 543, 578, 628–630, 644–657, 668, 704, 756–757, 831, 870, 1070, 1164–1167, 1200, 1265, 1366–1386, 1464, 1480, 1590, 1936–1938, 2000
   queue.py1711691%45, 53, 58, 105, 130–133, 173, 187, 205–208, 243, 267–270, 305, 330–333
   serializers.py350100% 
   tasks.py139118587%90, 104, 137, 173–174, 178–181, 183, 186, 236, 270–271, 390–391, 397, 400, 443–444, 485–490, 555, 561, 569, 733–734, 754–755, 818–819, 823, 842, 857, 862, 867, 874, 880, 883–885, 888–891, 894–896, 916, 953–954, 1038–1039, 1043, 1064, 1079, 1085, 1088–1091, 1098, 1101–1103, 1106–1109, 1112–1114, 1133–1137, 1174–1175, 1252–1253, 1255, 1276, 1291, 1297, 1300–1303, 1310, 1313–1315, 1318–1321, 1324–1326, 1346–1350, 1386–1387, 1465–1466, 1469, 1490, 1505, 1511, 1517, 1524, 1530, 1533–1535, 1538–1541, 1544–1546, 1565, 1617–1618, 1679, 1691–1700, 1742, 1745–1750, 1753–1757, 1922–1926, 2022–2023, 2229–2239, 2242, 2251–2256, 2290–2292, 2326–2329, 2397–2401, 2410, 2499–2504, 2517, 2532, 2547
   utils.py8884795%98, 110, 113, 538–539, 716–720, 865, 876, 1182, 1198–1204, 1213–1214, 1692–1702, 1940–1944, 1972–1976, 2004–2008, 2052–2056, 2110–2114, 2135, 2144, 2153, 2162–2163, 2174, 2197–2199
   views.py1453377%127–129, 134–135, 141–142, 185–188, 258–288, 299–314, 327–331
apps/sage_intacct/errors
   errors.py20100% 
   helpers.py47198%80
apps/sage_intacct/exports
   ap_payments.py130100% 
   bills.py280100% 
   charge_card_transactions.py220100% 
   expense_reports.py280100% 
   helpers.py56296%68, 141
   journal_entries.py76889%177–180, 316–319
   reimbursements.py130100% 
apps/tasks
   models.py690100% 
   serializers.py60100% 
   views.py370100% 
apps/users
   helpers.py120100% 
   models.py530100% 
   views.py170100% 
apps/workspaces
   actions.py46980%65, 84–85, 103, 122–133, 147
   enums.py50100% 
   helpers.py80100% 
   models.py1740100% 
   permissions.py34974%33, 59–67
   serializers.py43198%54
   signals.py310100% 
   tasks.py165995%53–59, 187–194, 235, 267–268, 379
   utils.py90100% 
   views.py318997%105–107, 134–137, 657–658
apps/workspaces/apis/advanced_settings
   serializers.py80396%260, 263, 266
   triggers.py100100% 
   views.py110100% 
apps/workspaces/apis/errors
   serializers.py200100% 
   views.py150100% 
apps/workspaces/apis/export_settings
   helpers.py730100% 
   serializers.py103397%267, 270, 273
   triggers.py39295%32–33
   views.py110100% 
apps/workspaces/apis/import_settings
   serializers.py1411887%232–238, 243–249, 257–265, 283, 286, 314, 317–318, 326
   triggers.py47198%31
   views.py330100% 
fyle_integrations_imports
   dataclasses.py310100% 
   models.py230100% 
   queues.py34585%24, 99, 136, 148–149
   signals.py100100% 
   tasks.py1247837%68–105, 114–120, 133–202, 206–221, 246–249, 251, 253, 258
fyle_integrations_imports/modules
   base.py1881095%75, 91–92, 95, 126, 230–231, 237–238, 351
   categories.py1773381%80, 96, 99–100, 103–104, 272–273, 283, 296, 298, 342, 351–355, 364–410
   cost_centers.py961288%132–133, 152–153, 162, 178, 180, 226, 235–239
   expense_custom_fields.py121794%83–88, 247, 263, 265, 294
   merchants.py1062576%80–83, 111–129, 155–162, 179–180, 190, 203, 205, 235, 238–242
   projects.py88990%109–110, 120, 144, 191, 205–209
   tax_groups.py180100% 
   webhook_attributes.py130695%95, 97–99, 210–211
workers
   actions.py210100% 
   helpers.py410100% 
   worker.py56591%44–45, 77–78, 125
TOTAL1028791291% 

Tests Skipped Failures Errors Time
709 0 💤 0 ❌ 0 🔥 54.282s ⏱️

@github-actions
Copy link

github-actions bot commented Jan 6, 2026


Diff Coverage
Diff: origin/master..HEAD, staged and unstaged changes

No lines with coverage information in this diff.

@github-actions
Copy link

github-actions bot commented Jan 6, 2026

Coverage

Coverage Report
FileStmtsMissCoverMissing
apps
   exceptions.py471177%27, 33, 39–44, 50, 56–61, 67, 73, 79–80
apps/fyle
   actions.py124794%214, 263, 319–323
   constants.py10100% 
   helpers.py2352291%50–57, 66, 146–162, 376, 470, 477–480, 483–484
   models.py3322194%313–315, 319–321, 325–327, 331–333, 337–339, 343–345, 406, 510–531, 554, 571
   queue.py470100% 
   serializers.py410100% 
   signals.py35683%22, 55–56, 69–71
   tasks.py4887385%135–136, 139–140, 143–144, 166–167, 201–211, 223–228, 271–274, 295–299, 309–317, 355–356, 450–497, 781–785
   views.py1721591%84–91, 145, 245–246, 290–291, 316–320, 413–417
apps/internal
   actions.py39295%26–27
   helpers.py361364%18–35
   serializers.py300100% 
   views.py83199%39
apps/internal/services
   e2e_setup.py590100% 
   fixture_factory.py59395%218–220
apps/mappings
   constants.py20100% 
   exceptions.py71692%69–71, 79–81
   helpers.py300100% 
   models.py500100% 
   schedules.py150100% 
   serializers.py100100% 
   signals.py1111487%90–92, 127, 179–184, 190–194, 200–203, 209–210
   tasks.py1732983%117–118, 141–142, 145, 209–226, 254, 257, 260, 266, 269, 275, 314–316, 327, 399
   utils.py340100% 
   views.py46491%34–35, 114–115
apps/sage_intacct
   actions.py29486%21–22, 49–50
   connector.py8052597%133, 309, 321, 327, 403, 1414, 1713, 1840–1841, 1892–1893, 1914–1915, 1944–1945, 1953–1964, 1996–1997, 2017–2018
   dependent_fields.py2744285%320, 356–359, 388–397, 399–400, 402–404, 406–407, 409–410, 412–413, 417–419, 463, 483, 523–525, 571–573, 621–627, 631–632
   enums.py250100% 
   helpers.py56689%38–41, 58, 95
   models.py9396293%69–70, 220, 327, 334, 378, 399–416, 475, 487, 537, 543, 578, 628–630, 644–657, 668, 704, 756–757, 831, 870, 1070, 1164–1167, 1200, 1265, 1366–1386, 1464, 1480, 1590, 1936–1938, 2000
   queue.py1711691%45, 53, 58, 105, 130–133, 173, 187, 205–208, 243, 267–270, 305, 330–333
   serializers.py350100% 
   tasks.py139118587%90, 104, 137, 173–174, 178–181, 183, 186, 236, 270–271, 390–391, 397, 400, 443–444, 485–490, 555, 561, 569, 733–734, 754–755, 818–819, 823, 842, 857, 862, 867, 874, 880, 883–885, 888–891, 894–896, 916, 953–954, 1038–1039, 1043, 1064, 1079, 1085, 1088–1091, 1098, 1101–1103, 1106–1109, 1112–1114, 1133–1137, 1174–1175, 1252–1253, 1255, 1276, 1291, 1297, 1300–1303, 1310, 1313–1315, 1318–1321, 1324–1326, 1346–1350, 1386–1387, 1465–1466, 1469, 1490, 1505, 1511, 1517, 1524, 1530, 1533–1535, 1538–1541, 1544–1546, 1565, 1617–1618, 1679, 1691–1700, 1742, 1745–1750, 1753–1757, 1922–1926, 2022–2023, 2229–2239, 2242, 2251–2256, 2290–2292, 2326–2329, 2397–2401, 2410, 2499–2504, 2517, 2532, 2547
   utils.py8884795%98, 110, 113, 538–539, 716–720, 865, 876, 1182, 1198–1204, 1213–1214, 1692–1702, 1940–1944, 1972–1976, 2004–2008, 2052–2056, 2110–2114, 2135, 2144, 2153, 2162–2163, 2174, 2197–2199
   views.py1453377%127–129, 134–135, 141–142, 185–188, 258–288, 299–314, 327–331
apps/sage_intacct/errors
   errors.py20100% 
   helpers.py47198%80
apps/sage_intacct/exports
   ap_payments.py130100% 
   bills.py280100% 
   charge_card_transactions.py220100% 
   expense_reports.py280100% 
   helpers.py56296%68, 141
   journal_entries.py76889%177–180, 316–319
   reimbursements.py130100% 
apps/tasks
   models.py690100% 
   serializers.py60100% 
   views.py370100% 
apps/users
   helpers.py120100% 
   models.py530100% 
   views.py170100% 
apps/workspaces
   actions.py46980%65, 84–85, 103, 122–133, 147
   enums.py50100% 
   helpers.py80100% 
   models.py1740100% 
   permissions.py34974%33, 59–67
   serializers.py43198%54
   signals.py310100% 
   tasks.py165995%53–59, 187–194, 235, 267–268, 379
   utils.py90100% 
   views.py318997%105–107, 134–137, 657–658
apps/workspaces/apis/advanced_settings
   serializers.py80396%260, 263, 266
   triggers.py100100% 
   views.py110100% 
apps/workspaces/apis/errors
   serializers.py200100% 
   views.py150100% 
apps/workspaces/apis/export_settings
   helpers.py730100% 
   serializers.py103397%267, 270, 273
   triggers.py39295%32–33
   views.py110100% 
apps/workspaces/apis/import_settings
   serializers.py1411887%232–238, 243–249, 257–265, 283, 286, 314, 317–318, 326
   triggers.py47198%31
   views.py330100% 
fyle_integrations_imports
   dataclasses.py310100% 
   models.py230100% 
   queues.py34585%24, 99, 136, 148–149
   signals.py100100% 
   tasks.py1247837%68–105, 114–120, 133–202, 206–221, 246–249, 251, 253, 258
fyle_integrations_imports/modules
   base.py1881095%75, 91–92, 95, 126, 230–231, 237–238, 351
   categories.py1773381%80, 96, 99–100, 103–104, 272–273, 283, 296, 298, 342, 351–355, 364–410
   cost_centers.py961288%132–133, 152–153, 162, 178, 180, 226, 235–239
   expense_custom_fields.py121794%83–88, 247, 263, 265, 294
   merchants.py1062576%80–83, 111–129, 155–162, 179–180, 190, 203, 205, 235, 238–242
   projects.py88990%109–110, 120, 144, 191, 205–209
   tax_groups.py180100% 
   webhook_attributes.py130695%95, 97–99, 210–211
workers
   actions.py210100% 
   helpers.py410100% 
   worker.py56591%44–45, 77–78, 125
TOTAL1028791291% 

Tests Skipped Failures Errors Time
709 0 💤 0 ❌ 0 🔥 51.356s ⏱️

@github-actions
Copy link

github-actions bot commented Jan 6, 2026


Diff Coverage
Diff: origin/master..HEAD, staged and unstaged changes

No lines with coverage information in this diff.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI Agents
In @tests/test_sageintacct/test_connector.py:
- Around line 1399-1428: The test's final assertion is tautological; replace
`assert vendor is None or vendor is not None` with a concrete expectation: if
get_or_create_vendor should return None on a BadRequestError, assert `vendor is
None`; otherwise assert that `vendor` equals the existing vendor record (e.g.,
has id 'VND001' and email 'dup@test.com') and rename the test function
(`test_get_or_create_vendor_returns_none_on_bad_request` or
`test_get_or_create_vendor_returns_existing_on_bad_request`) to reflect the
chosen behavior; reference SageIntacctObjectCreationManager.get_or_create_vendor
and the test function name to locate where to change the assertion and the test
name.
🧹 Nitpick comments (2)
tests/test_sageintacct/test_connector.py (2)

52-64: Prefix unused unpacked variables with underscore.

The unpacked variables mock_rest_sdk_class (line 56) and mock_soap_instance (line 57) are never used in this test. Following Python convention, prefix them with underscore to indicate they're intentionally unused.

🔎 Suggested refactor
-    mock_rest_sdk_class, mock_rest_instance = mock_intacct_sdk
-    mock_soap_sdk_class, mock_soap_instance = mock_sage_intacct_sdk
+    _, mock_rest_instance = mock_intacct_sdk
+    mock_soap_sdk_class, _ = mock_sage_intacct_sdk

674-691: Prefix unused unpacked variables with underscore.

Similar to the earlier test, the unpacked variables mock_rest_sdk_class (line 678) and mock_soap_sdk_class (line 679) are never used. Prefix them with underscore for clarity.

🔎 Suggested refactor
-    mock_rest_sdk_class, mock_rest_instance = mock_intacct_sdk
-    mock_soap_sdk_class, mock_soap_instance = mock_sage_intacct_sdk
+    _, mock_rest_instance = mock_intacct_sdk
+    _, mock_soap_instance = mock_sage_intacct_sdk
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between adf785b and 69a9cb1.

📒 Files selected for processing (4)
  • tests/test_sageintacct/conftest.py
  • tests/test_sageintacct/exports/test_helpers.py
  • tests/test_sageintacct/exports/test_journal_entries.py
  • tests/test_sageintacct/test_connector.py
🧰 Additional context used
🧬 Code graph analysis (3)
tests/test_sageintacct/test_connector.py (1)
apps/sage_intacct/connector.py (39)
  • SageIntacctRestConnector (73-201)
  • SageIntacctDimensionSyncManager (204-1354)
  • SageIntacctObjectCreationManager (1357-2209)
  • get_session_id (181-185)
  • get_soap_connection (187-201)
  • sync_accounts (418-467)
  • sync_departments (469-510)
  • sync_expense_types (512-568)
  • sync_vendors (1074-1118)
  • sync_employees (902-946)
  • sync_projects (720-770)
  • sync_locations (819-859)
  • sync_items (772-817)
  • sync_expense_payment_types (861-900)
  • sync_user_defined_dimensions (1120-1178)
  • sync_allocations (1180-1247)
  • get_bills (1309-1330)
  • get_expense_reports (1332-1354)
  • sync_location_entities (1274-1307)
  • create_vendor (1520-1558)
  • create_contact (1560-1592)
  • get_or_create_vendor (1684-1759)
  • search_and_create_vendors (1761-1811)
  • post_bill (1865-1915)
  • post_expense_report (1813-1863)
  • post_charge_card_transaction (1917-1967)
  • post_journal_entry (1969-2018)
  • post_ap_payment (2020-2033)
  • post_sage_intacct_reimbursement (2035-2055)
  • get_or_create_attachments_folder (2057-2077)
  • post_attachments (2079-2117)
  • get_journal_entry (2156-2166)
  • get_charge_card_transaction (2169-2183)
  • get_bill (2186-2196)
  • get_expense_report (2199-2209)
  • sync_cost_types (648-687)
  • sync_cost_codes (689-718)
  • create_employee (1594-1663)
  • get_or_create_employee (1665-1682)
tests/test_sageintacct/conftest.py (2)
apps/workspaces/models.py (2)
  • Workspace (83-105)
  • IntacctSyncedTimestamp (303-356)
apps/sage_intacct/models.py (2)
  • CostType (1818-1969)
  • SageIntacctAttributesCount (2083-2131)
tests/test_sageintacct/exports/test_journal_entries.py (3)
apps/workspaces/models.py (1)
  • Configuration (108-169)
apps/mappings/models.py (1)
  • GeneralMapping (24-75)
tests/test_sageintacct/conftest.py (2)
  • create_journal_entry (66-79)
  • create_allocation_attribute (462-478)
🪛 Ruff (0.14.10)
tests/test_sageintacct/test_connector.py

26-26: Unused function argument: db

(ARG001)


39-39: Unused function argument: db

(ARG001)


52-52: Unused function argument: db

(ARG001)


56-56: Unpacked variable mock_rest_sdk_class is never used

Prefix it with an underscore or any other dummy variable pattern

(RUF059)


57-57: Unpacked variable mock_soap_instance is never used

Prefix it with an underscore or any other dummy variable pattern

(RUF059)


67-67: Unused function argument: db

(ARG001)


67-67: Unused function argument: mock_intacct_sdk

(ARG001)


72-72: Possible hardcoded password assigned to: "access_token"

(S105)


78-78: Possible hardcoded password assigned to: "access_token"

(S105)


81-81: Unused function argument: db

(ARG001)


81-81: Unused function argument: create_intacct_synced_timestamp

(ARG001)


81-81: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


99-99: Unused function argument: db

(ARG001)


99-99: Unused function argument: create_intacct_synced_timestamp

(ARG001)


99-99: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


126-126: Unused function argument: db

(ARG001)


126-126: Unused function argument: create_intacct_synced_timestamp

(ARG001)


126-126: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


144-144: Unused function argument: db

(ARG001)


144-144: Unused function argument: create_intacct_synced_timestamp

(ARG001)


144-144: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


168-168: Unused function argument: db

(ARG001)


168-168: Unused function argument: create_intacct_synced_timestamp

(ARG001)


168-168: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


186-186: Unused function argument: db

(ARG001)


186-186: Unused function argument: create_intacct_synced_timestamp

(ARG001)


186-186: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


212-212: Unused function argument: db

(ARG001)


212-212: Unused function argument: create_intacct_synced_timestamp

(ARG001)


212-212: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


238-238: Unused function argument: db

(ARG001)


238-238: Unused function argument: create_intacct_synced_timestamp

(ARG001)


238-238: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


256-256: Unused function argument: db

(ARG001)


256-256: Unused function argument: create_intacct_synced_timestamp

(ARG001)


256-256: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


274-274: Unused function argument: db

(ARG001)


274-274: Unused function argument: create_intacct_synced_timestamp

(ARG001)


274-274: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


292-292: Unused function argument: db

(ARG001)


292-292: Unused function argument: create_intacct_synced_timestamp

(ARG001)


292-292: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


310-310: Unused function argument: db

(ARG001)


310-310: Unused function argument: create_intacct_synced_timestamp

(ARG001)


310-310: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


328-328: Unused function argument: db

(ARG001)


328-328: Unused function argument: create_intacct_synced_timestamp

(ARG001)


328-328: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


346-346: Unused function argument: db

(ARG001)


346-346: Unused function argument: create_intacct_synced_timestamp

(ARG001)


346-346: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


364-364: Unused function argument: db

(ARG001)


364-364: Unused function argument: create_intacct_synced_timestamp

(ARG001)


364-364: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


382-382: Unused function argument: db

(ARG001)


382-382: Unused function argument: create_intacct_synced_timestamp

(ARG001)


382-382: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


404-404: Unused function argument: db

(ARG001)


404-404: Unused function argument: create_intacct_synced_timestamp

(ARG001)


404-404: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


429-429: Unused function argument: db

(ARG001)


445-445: Unused function argument: db

(ARG001)


461-461: Unused function argument: db

(ARG001)


461-461: Unused function argument: create_intacct_synced_timestamp

(ARG001)


461-461: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


486-486: Unused function argument: db

(ARG001)


506-506: Unused function argument: db

(ARG001)


532-532: Unused function argument: db

(ARG001)


532-532: Unused function argument: create_existing_vendor_attribute

(ARG001)


545-545: Unused function argument: db

(ARG001)


568-568: Unused function argument: db

(ARG001)


584-584: Unused function argument: db

(ARG001)


602-602: Unused function argument: db

(ARG001)


620-620: Unused function argument: db

(ARG001)


638-638: Unused function argument: db

(ARG001)


656-656: Unused function argument: db

(ARG001)


674-674: Unused function argument: db

(ARG001)


678-678: Unpacked variable mock_rest_sdk_class is never used

Prefix it with an underscore or any other dummy variable pattern

(RUF059)


679-679: Unpacked variable mock_soap_sdk_class is never used

Prefix it with an underscore or any other dummy variable pattern

(RUF059)


693-693: Unused function argument: db

(ARG001)


709-709: Unused function argument: db

(ARG001)


731-731: Unused function argument: db

(ARG001)


748-748: Unused function argument: db

(ARG001)


765-765: Unused function argument: db

(ARG001)


782-782: Unused function argument: db

(ARG001)


799-799: Unused function argument: db

(ARG001)


816-816: Unused function argument: db

(ARG001)


832-832: Unused function argument: db

(ARG001)


848-848: Unused function argument: db

(ARG001)


864-864: Unused function argument: db

(ARG001)


880-880: Unused function argument: db

(ARG001)


880-880: Unused function argument: create_intacct_synced_timestamp

(ARG001)


880-880: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


907-907: Unused function argument: db

(ARG001)


907-907: Unused function argument: create_intacct_synced_timestamp

(ARG001)


907-907: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


931-931: Unused function argument: db

(ARG001)


931-931: Unused function argument: create_intacct_synced_timestamp

(ARG001)


931-931: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


956-956: Unused function argument: db

(ARG001)


956-956: Unused function argument: create_intacct_synced_timestamp

(ARG001)


956-956: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


980-980: Unused function argument: db

(ARG001)


980-980: Unused function argument: create_intacct_synced_timestamp

(ARG001)


980-980: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


1004-1004: Unused function argument: db

(ARG001)


1004-1004: Unused function argument: create_intacct_synced_timestamp

(ARG001)


1004-1004: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


1028-1028: Unused function argument: db

(ARG001)


1028-1028: Unused function argument: create_intacct_synced_timestamp

(ARG001)


1028-1028: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


1052-1052: Unused function argument: db

(ARG001)


1052-1052: Unused function argument: create_intacct_synced_timestamp

(ARG001)


1052-1052: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


1076-1076: Unused function argument: db

(ARG001)


1076-1076: Unused function argument: create_intacct_synced_timestamp

(ARG001)


1076-1076: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


1100-1100: Unused function argument: db

(ARG001)


1100-1100: Unused function argument: create_intacct_synced_timestamp

(ARG001)


1100-1100: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


1124-1124: Unused function argument: db

(ARG001)


1124-1124: Unused function argument: create_intacct_synced_timestamp

(ARG001)


1124-1124: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


1148-1148: Unused function argument: db

(ARG001)


1148-1148: Unused function argument: create_intacct_synced_timestamp

(ARG001)


1148-1148: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


1172-1172: Unused function argument: db

(ARG001)


1172-1172: Unused function argument: create_intacct_synced_timestamp

(ARG001)


1172-1172: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


1196-1196: Unused function argument: db

(ARG001)


1196-1196: Unused function argument: create_intacct_synced_timestamp

(ARG001)


1196-1196: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


1235-1235: Unused function argument: db

(ARG001)


1235-1235: Unused function argument: create_intacct_synced_timestamp

(ARG001)


1235-1235: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


1266-1266: Unused function argument: db

(ARG001)


1266-1266: Unused function argument: create_intacct_synced_timestamp

(ARG001)


1266-1266: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


1293-1293: Unused function argument: db

(ARG001)


1293-1293: Unused function argument: create_intacct_synced_timestamp

(ARG001)


1293-1293: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


1315-1315: Unused function argument: db

(ARG001)


1315-1315: Unused function argument: create_intacct_synced_timestamp

(ARG001)


1315-1315: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


1334-1334: Unused function argument: db

(ARG001)


1334-1334: Unused function argument: create_intacct_synced_timestamp

(ARG001)


1334-1334: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


1356-1356: Unused function argument: db

(ARG001)


1356-1356: Unused function argument: create_intacct_synced_timestamp

(ARG001)


1356-1356: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


1376-1376: Unused function argument: db

(ARG001)


1399-1399: Unused function argument: db

(ARG001)


1431-1431: Unused function argument: db

(ARG001)


1461-1461: Unused function argument: db

(ARG001)


1491-1491: Unused function argument: db

(ARG001)


1521-1521: Unused function argument: db

(ARG001)


1551-1551: Unused function argument: db

(ARG001)


1573-1573: Unused function argument: db

(ARG001)


1597-1597: Unused function argument: db

(ARG001)


1650-1650: Unused function argument: db

(ARG001)


1687-1687: Unused function argument: db

(ARG001)


1724-1724: Unused function argument: db

(ARG001)


1750-1750: Unused function argument: db

(ARG001)


1750-1750: Unused function argument: create_intacct_synced_timestamp

(ARG001)


1750-1750: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


1782-1782: Unused function argument: db

(ARG001)


1782-1782: Unused function argument: create_intacct_synced_timestamp

(ARG001)


1782-1782: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


1807-1807: Unused function argument: db

(ARG001)


1807-1807: Unused function argument: create_intacct_synced_timestamp

(ARG001)


1807-1807: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


1839-1839: Unused function argument: db

(ARG001)


1839-1839: Unused function argument: create_intacct_synced_timestamp

(ARG001)


1839-1839: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


1864-1864: Unused function argument: db

(ARG001)


1864-1864: Unused function argument: create_intacct_synced_timestamp

(ARG001)


1864-1864: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


1888-1888: Unused function argument: db

(ARG001)


1888-1888: Unused function argument: create_intacct_synced_timestamp

(ARG001)


1888-1888: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


1912-1912: Unused function argument: db

(ARG001)


1912-1912: Unused function argument: create_intacct_synced_timestamp

(ARG001)


1912-1912: Unused function argument: create_sage_intacct_attributes_count

(ARG001)


1945-1945: Unused function argument: db

(ARG001)


1968-1968: Unused function argument: db

(ARG001)


1990-1990: Unused function argument: db

(ARG001)


2010-2010: Unused function argument: db

(ARG001)


2047-2047: Unused function argument: db

(ARG001)


2091-2091: Unused function argument: db

(ARG001)


2133-2133: Unused function argument: db

(ARG001)


2180-2180: Unused function argument: db

(ARG001)


2213-2213: Unused function argument: db

(ARG001)


2246-2246: Unused function argument: db

(ARG001)


2279-2279: Unused function argument: db

(ARG001)


2309-2309: Unused function argument: db

(ARG001)


2339-2339: Unused function argument: db

(ARG001)

tests/test_sageintacct/conftest.py

353-353: Possible hardcoded password assigned to: "access_token"

(S105)


369-369: Unused function argument: db

(ARG001)


395-395: Unused function argument: db

(ARG001)


409-409: Unused function argument: db

(ARG001)


422-422: Unused function argument: db

(ARG001)


442-442: Unused function argument: db

(ARG001)


462-462: Unused function argument: db

(ARG001)

tests/test_sageintacct/exports/test_helpers.py

17-17: Unused function argument: db

(ARG001)


27-27: Unused function argument: db

(ARG001)


37-37: Unused function argument: db

(ARG001)


37-37: Unused function argument: create_tax_detail_attribute

(ARG001)


53-53: Unused function argument: db

(ARG001)


69-69: Unused function argument: db

(ARG001)


89-89: Unused function argument: db

(ARG001)


89-89: Unused function argument: create_tax_detail_with_solution_id

(ARG001)


111-111: Unused function argument: db

(ARG001)


126-126: Unused function argument: db

(ARG001)


149-149: Unused function argument: db

(ARG001)


166-166: Unused function argument: db

(ARG001)


215-215: Unused function argument: db

(ARG001)

tests/test_sageintacct/exports/test_journal_entries.py

15-15: Unused function argument: db

(ARG001)


38-38: Unused function argument: db

(ARG001)


62-62: Unused function argument: db

(ARG001)


81-81: Unused function argument: db

(ARG001)


103-103: Unused function argument: db

(ARG001)


126-126: Unused function argument: db

(ARG001)


149-149: Unused function argument: db

(ARG001)


149-149: Unused function argument: create_allocation_attribute

(ARG001)


168-168: Unused function argument: db

(ARG001)


192-192: Unused function argument: db

(ARG001)


217-217: Unused function argument: db

(ARG001)


241-241: Unused function argument: db

(ARG001)


264-264: Unused function argument: db

(ARG001)


289-289: Unused function argument: db

(ARG001)


315-315: Unused function argument: db

(ARG001)


340-340: Unused function argument: db

(ARG001)


367-367: Unused function argument: db

(ARG001)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: pytest
🔇 Additional comments (4)
tests/test_sageintacct/conftest.py (1)

348-477: LGTM! Comprehensive test fixtures added.

The new fixtures provide excellent coverage for testing Sage Intacct integrations:

  • SDK mocks (mock_intacct_sdk, mock_sage_intacct_sdk) enable isolated testing
  • State fixtures (create_intacct_synced_timestamp, create_sage_intacct_attributes_count) support sync testing
  • Attribute fixtures create necessary test data for various export scenarios

The implementation follows pytest conventions correctly.

tests/test_sageintacct/test_connector.py (1)

26-2366: Excellent comprehensive test coverage for Sage Intacct connector.

This test suite provides thorough coverage of:

  • REST and SOAP connection initialization and session management
  • Dimension synchronization with limit enforcement for new/old workspaces
  • CRUD operations for vendors, contacts, employees
  • Export operations (bills, expense reports, charge card transactions, journal entries, AP payments, reimbursements)
  • Error handling including closed period errors and BadRequestErrors
  • Attachment management
  • Edge cases and boundary conditions

The tests are well-structured, use appropriate mocks, and validate key behaviors across the Sage Intacct integration surface.

tests/test_sageintacct/exports/test_helpers.py (1)

17-235: LGTM! Well-structured helper function tests.

The tests provide good coverage for helper functions used in Sage Intacct exports:

  • format_transaction_date tested with both string and datetime inputs
  • get_tax_exclusive_amount covers tax attribute present/absent cases
  • get_tax_solution_id_or_none validates location entity and tax code lookup scenarios
  • get_location_id_for_journal_entry tests general mapping, location entity mapping, and no-mapping cases
  • get_source_entity_id verifies complex conditional logic with multiple configuration combinations

Each test has clear intent and validates expected behavior.

tests/test_sageintacct/exports/test_journal_entries.py (1)

15-391: LGTM! Comprehensive journal entry payload tests.

The tests thoroughly validate journal entry payload construction across multiple scenarios:

  • Base payload structure with different brand IDs (fyle, em)
  • Tax import configurations
  • Supdoc attachment handling
  • Debit line creation with standard/negative amounts and allocations
  • Credit line creation for single vs. multiple line configurations
  • Billable line handling
  • Fund source variations (CCC, PERSONAL)
  • Edge cases like zero amounts and refunds

Each test validates specific payload keys and field values using fixtures, ensuring consistent payload structure.

Comment on lines +1399 to +1428
def test_get_or_create_vendor_with_bad_request_error(db, mock_intacct_sdk):
"""
Test get_or_create_vendor handles BadRequestError for duplicate vendor
"""
_, mock_instance = mock_intacct_sdk

error_response = {
'ia::result': {
'ia::error': {
'details': 'Another record with the value already exists'
}
}
}

mock_instance.vendors.post.side_effect = BadRequestError(
msg='Duplicate',
response=str(error_response)
)
mock_instance.vendors.get_all_generator.return_value = iter([[
{'id': 'VND001', 'name': 'Duplicate Vendor', 'status': 'active', 'contacts.default.email1': 'dup@test.com'}
]])

manager = SageIntacctObjectCreationManager(workspace_id=1)
vendor = manager.get_or_create_vendor(
vendor_name='Duplicate Vendor',
email='dup@test.com',
create=True
)

assert vendor is None or vendor is not None
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Replace tautological assertion with meaningful check.

The assertion assert vendor is None or vendor is not None on line 1428 is always true and provides no validation. Replace it with a specific assertion that reflects the expected behavior when get_or_create_vendor encounters a BadRequestError for a duplicate vendor.

🔎 Suggested fix

If the expected behavior is to return None on error:

-    assert vendor is None or vendor is not None
+    assert vendor is None

Or if the expected behavior is to return the existing vendor:

-    assert vendor is None or vendor is not None
+    assert vendor is not None
+    assert vendor.destination_id == 'VND001'

Update the test name accordingly to reflect the asserted outcome.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
def test_get_or_create_vendor_with_bad_request_error(db, mock_intacct_sdk):
"""
Test get_or_create_vendor handles BadRequestError for duplicate vendor
"""
_, mock_instance = mock_intacct_sdk
error_response = {
'ia::result': {
'ia::error': {
'details': 'Another record with the value already exists'
}
}
}
mock_instance.vendors.post.side_effect = BadRequestError(
msg='Duplicate',
response=str(error_response)
)
mock_instance.vendors.get_all_generator.return_value = iter([[
{'id': 'VND001', 'name': 'Duplicate Vendor', 'status': 'active', 'contacts.default.email1': 'dup@test.com'}
]])
manager = SageIntacctObjectCreationManager(workspace_id=1)
vendor = manager.get_or_create_vendor(
vendor_name='Duplicate Vendor',
email='dup@test.com',
create=True
)
assert vendor is None or vendor is not None
def test_get_or_create_vendor_with_bad_request_error(db, mock_intacct_sdk):
"""
Test get_or_create_vendor handles BadRequestError for duplicate vendor
"""
_, mock_instance = mock_intacct_sdk
error_response = {
'ia::result': {
'ia::error': {
'details': 'Another record with the value already exists'
}
}
}
mock_instance.vendors.post.side_effect = BadRequestError(
msg='Duplicate',
response=str(error_response)
)
mock_instance.vendors.get_all_generator.return_value = iter([[
{'id': 'VND001', 'name': 'Duplicate Vendor', 'status': 'active', 'contacts.default.email1': 'dup@test.com'}
]])
manager = SageIntacctObjectCreationManager(workspace_id=1)
vendor = manager.get_or_create_vendor(
vendor_name='Duplicate Vendor',
email='dup@test.com',
create=True
)
assert vendor is not None
assert vendor.destination_id == 'VND001'
🧰 Tools
🪛 Ruff (0.14.10)

1399-1399: Unused function argument: db

(ARG001)

🤖 Prompt for AI Agents
In @tests/test_sageintacct/test_connector.py around lines 1399-1428, The test's
final assertion is tautological; replace `assert vendor is None or vendor is not
None` with a concrete expectation: if get_or_create_vendor should return None on
a BadRequestError, assert `vendor is None`; otherwise assert that `vendor`
equals the existing vendor record (e.g., has id 'VND001' and email
'dup@test.com') and rename the test function
(`test_get_or_create_vendor_returns_none_on_bad_request` or
`test_get_or_create_vendor_returns_existing_on_bad_request`) to reflect the
chosen behavior; reference SageIntacctObjectCreationManager.get_or_create_vendor
and the test function name to locate where to change the assertion and the test
name.

@Hrishabh17 Hrishabh17 merged commit db09c2d into master Jan 6, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/XL Extra Large PR

Development

Successfully merging this pull request may close these issues.

2 participants