From a24c15bd5720e6d9eaf1f7c431ab2cde649016d8 Mon Sep 17 00:00:00 2001 From: lchen-2101 <73617864+lchen-2101@users.noreply.github.com> Date: Tue, 12 Sep 2023 10:25:57 -0400 Subject: [PATCH] feat: initial gh actions --- .github/workflows/coverage.yml | 31 ++++++++++++ .github/workflows/linters.yml | 15 ++++++ .github/workflows/tests.yml | 47 +++++++++++++++++++ pyproject.toml | 14 +++++- tests/entities/conftest.py | 18 +++++-- .../entities/repos/test_institutions_repo.py | 46 +++++++++--------- 6 files changed, 142 insertions(+), 29 deletions(-) create mode 100644 .github/workflows/coverage.yml create mode 100644 .github/workflows/linters.yml create mode 100644 .github/workflows/tests.yml diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml new file mode 100644 index 0000000..fd60e93 --- /dev/null +++ b/.github/workflows/coverage.yml @@ -0,0 +1,31 @@ +name: Coverage + +on: + workflow_run: + workflows: ["Tests"] + types: + - completed + +jobs: + coverage: + name: Run tests & display coverage + runs-on: ubuntu-latest + if: github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.conclusion == 'success' + permissions: + # Gives the action the necessary permissions for publishing new + # comments in pull requests. + pull-requests: write + # Gives the action the necessary permissions for editing existing + # comments (to avoid publishing multiple comments in the same PR) + contents: write + # Gives the action the necessary permissions for looking up the + # workflow that launched this workflow, and download the related + # artifact that contains the comment to be published + actions: read + steps: + - name: Post comment + uses: py-cov-action/python-coverage-comment-action@v3 + with: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_PR_RUN_ID: ${{ github.event.workflow_run.id }} + verbose: true \ No newline at end of file diff --git a/.github/workflows/linters.yml b/.github/workflows/linters.yml new file mode 100644 index 0000000..2f24298 --- /dev/null +++ b/.github/workflows/linters.yml @@ -0,0 +1,15 @@ +name: Linters + +on: [push] + +jobs: + black: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: psf/black@stable + ruff: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: chartboost/ruff-action@v1 \ No newline at end of file diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 0000000..6ebb2cd --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,47 @@ +name: Tests + +on: + pull_request: + push: + branches: + - "main" + +jobs: + unit-tests: + runs-on: ubuntu-latest + permissions: + # Gives the action the necessary permissions for publishing new + # comments in pull requests. + pull-requests: write + # Gives the action the necessary permissions for pushing data to the + # python-coverage-comment-action branch, and for editing existing + # comments (to avoid publishing multiple comments in the same PR) + contents: write + steps: + - uses: actions/checkout@v3 + - name: Set up Python 3.11 + uses: actions/setup-python@v4 + with: + python-version: 3.11 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install poetry + poetry config virtualenvs.create false + poetry install --no-root + - name: Launch tests & generate report + run: poetry run pytest + - name: Coverage comment + id: coverage_comment + uses: py-cov-action/python-coverage-comment-action@v3 + with: + GITHUB_TOKEN: ${{ github.token }} + verbose: true + - name: Store Pull Request comment to be posted + uses: actions/upload-artifact@v3 + if: steps.coverage_comment.outputs.COMMENT_FILE_WRITTEN == 'true' + with: + # If you use a different name, update COMMENT_ARTIFACT_NAME accordingly + name: python-coverage-comment-action + # If you use a different name, update COMMENT_FILENAME accordingly + path: python-coverage-comment-action.txt diff --git a/pyproject.toml b/pyproject.toml index 70ee33c..150992c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -33,7 +33,19 @@ asyncio_mode = "auto" pythonpath = [ "src" ] - +addopts = [ + "--cov-report=term-missing", + "--cov-branch", + "--cov-report=xml", + "--cov-report=term", + "--cov=src", + "-vv", + "--strict-markers", + "-rfE", +] +testpaths = [ + "tests", +] [build-system] requires = ["poetry-core"] diff --git a/tests/entities/conftest.py b/tests/entities/conftest.py index d22d248..6a5298a 100644 --- a/tests/entities/conftest.py +++ b/tests/entities/conftest.py @@ -45,9 +45,17 @@ async def td(): @pytest.fixture(scope="function") -async def session(engine: AsyncEngine): - Session = async_scoped_session( - async_sessionmaker(engine, expire_on_commit=False), current_task - ) - async with Session() as session: +async def transaction_session(session_generator: async_scoped_session): + async with session_generator() as session: + yield session + +@pytest.fixture(scope="function") +async def query_session(session_generator: async_scoped_session): + async with session_generator() as session: yield session + +@pytest.fixture(scope="function") +def session_generator(engine: AsyncEngine): + return async_scoped_session( + async_sessionmaker(engine, expire_on_commit=False), current_task + ) \ No newline at end of file diff --git a/tests/entities/repos/test_institutions_repo.py b/tests/entities/repos/test_institutions_repo.py index 1ac7f50..fda8885 100644 --- a/tests/entities/repos/test_institutions_repo.py +++ b/tests/entities/repos/test_institutions_repo.py @@ -14,7 +14,7 @@ class TestInstitutionsRepo: @pytest.fixture(scope="function", autouse=True) async def setup( self, - session: AsyncSession, + transaction_session: AsyncSession, ): fi_dao = FinancialInstitutionDao( name="Test Bank 123", @@ -23,48 +23,48 @@ async def setup( FinancialInstitutionDomainDao(domain="test.bank", lei="TESTBANK123") ], ) - session.add(fi_dao) - await session.commit() + transaction_session.add(fi_dao) + await transaction_session.commit() - async def test_get_institutions(self, session: AsyncSession): - res = await repo.get_institutions(session) + async def test_get_institutions(self, query_session: AsyncSession): + res = await repo.get_institutions(query_session) assert len(res) == 1 - async def test_get_institutions_by_domain(self, session: AsyncSession): - res = await repo.get_institutions(session, domain="test.bank") + async def test_get_institutions_by_domain(self, query_session: AsyncSession): + res = await repo.get_institutions(query_session, domain="test.bank") assert len(res) == 1 - async def test_get_institutions_by_domain_not_existing(self, session: AsyncSession): - res = await repo.get_institutions(session, domain="testing.bank") + async def test_get_institutions_by_domain_not_existing(self, query_session: AsyncSession): + res = await repo.get_institutions(query_session, domain="testing.bank") assert len(res) == 0 - async def test_add_institution(self, session: AsyncSession): + async def test_add_institution(self, transaction_session: AsyncSession): await repo.upsert_institution( - session, FinancialInstitutionDao(name="New Bank 123", lei="NEWBANK123") + transaction_session, FinancialInstitutionDao(name="New Bank 123", lei="NEWBANK123") ) - res = await repo.get_institutions(session) + res = await repo.get_institutions(transaction_session) assert len(res) == 2 - async def test_update_institution(self, session: AsyncSession): + async def test_update_institution(self, transaction_session: AsyncSession): await repo.upsert_institution( - session, FinancialInstitutionDao(name="Test Bank 234", lei="TESTBANK123") + transaction_session, FinancialInstitutionDao(name="Test Bank 234", lei="TESTBANK123") ) - res = await repo.get_institutions(session) + res = await repo.get_institutions(transaction_session) assert len(res) == 1 assert res[0].name == "Test Bank 234" - async def test_add_domains(self, session: AsyncSession): + async def test_add_domains(self, transaction_session: AsyncSession, query_session: AsyncSession): await repo.add_domains( - session, + transaction_session, "TESTBANK123", [FinancialInsitutionDomainCreate(domain="bank.test")], ) - fi = await repo.get_institution(session, "TESTBANK123") + fi = await repo.get_institution(query_session, "TESTBANK123") assert len(fi.domains) == 2 - async def test_domain_allowed(self, session: AsyncSession): + async def test_domain_allowed(self, transaction_session: AsyncSession): denied_domain = DeniedDomainDao(domain="yahoo.com") - session.add(denied_domain) - await session.commit() - assert await repo.is_email_domain_allowed(session, "test@yahoo.com") is False - assert await repo.is_email_domain_allowed(session, "test@gmail.com") is True + transaction_session.add(denied_domain) + await transaction_session.commit() + assert await repo.is_email_domain_allowed(transaction_session, "test@yahoo.com") is False + assert await repo.is_email_domain_allowed(transaction_session, "test@gmail.com") is True