Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: Tests

on:
push:
branches: [master]
pull_request:

jobs:
test:
runs-on: ubuntu-latest

strategy:
fail-fast: false
matrix:
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]

steps:
- name: Check out repository
uses: actions/checkout@v6

- name: Install uv
uses: astral-sh/setup-uv@v7
with:
python-version: ${{ matrix.python-version }}
enable-cache: true

- name: Sync dependencies
run: uv sync --locked --all-extras --dev

- name: Run tests
run: uv run pytest
1 change: 1 addition & 0 deletions .python-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3.13
8 changes: 0 additions & 8 deletions .travis.yml

This file was deleted.

3 changes: 0 additions & 3 deletions markusapi/__init__.py

This file was deleted.

Empty file removed markusapi/tests/__init__.py
Empty file.
40 changes: 40 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
[project]
name = "markusapi"
version = "0.3.0"
authors = [
{ name="Sam Maldonado" },
{ name="Alessio Di Sandro" },
{ name="Misha Schwartz" },
]
maintainers = [
{ name="David Liu", email="david@cs.toronto.edu" },
]
description = "Python API client for MarkUs"
readme = "README.md"
requires-python = ">=3.9"
classifiers = [
"License :: OSI Approved :: MIT License",
"Programming Language :: Python :: 3",
"Operating System :: OS Independent",
]
license = "MIT"
license-files = ["LICEN[CS]E*"]
dependencies = [
"requests~=2.32.5",
]

[project.urls]
Homepage = "https://github.com/MarkUsProject/markus-api"
Issues = "https://github.com/MarkUsProject/markus-api/issues"

[build-system]
requires = ["uv_build >= 0.9.17, <0.10.0"]
build-backend = "uv_build"

[dependency-groups]
dev = ["pytest"]

[tool.uv.workspace]
members = [
"markusapi",
]
5 changes: 0 additions & 5 deletions setup.cfg

This file was deleted.

24 changes: 0 additions & 24 deletions setup.py

This file was deleted.

3 changes: 3 additions & 0 deletions src/markusapi/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
name = "markusapi"

from .markusapi import Markus
File renamed without changes.
File renamed without changes.
29 changes: 13 additions & 16 deletions markusapi/tests/test_markusapi.py → tests/test_markusapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,17 @@ def api():


class AbstractTestClass(abc.ABC):
@classmethod
@pytest.fixture
def response_mock(cls):
with patch(f"requests.{cls.request_verb}") as mock:
def response_mock(self, request):
with patch(f"requests.{request.cls.request_verb}") as mock:
type(mock.return_value).ok = PropertyMock(return_value=True)
mock.return_value.content = "content"
mock.return_value.text = "text"
mock.return_value.json.return_value = "json"
yield mock

@classmethod
@pytest.fixture
def bad_response_mock(cls, response_mock):
def bad_response_mock(self, response_mock):
type(response_mock.return_value).ok = PropertyMock(return_value=False)
yield response_mock

Expand Down Expand Up @@ -266,7 +264,7 @@ def test_called_with_basic_params(self, api, response_mock):
"grade_entry_items": None,
}
_, kwargs = response_mock.call_args
assert kwargs["params"] == params
assert kwargs["json"] == params

def test_called_with_is_hidden(self, api, response_mock):
now = datetime.datetime.now()
Expand All @@ -280,7 +278,7 @@ def test_called_with_is_hidden(self, api, response_mock):
"grade_entry_items": None,
}
_, kwargs = response_mock.call_args
assert kwargs["params"] == params
assert kwargs["json"] == params

def test_called_with_is_show_total(self, api, response_mock):
now = datetime.datetime.now()
Expand All @@ -294,7 +292,7 @@ def test_called_with_is_show_total(self, api, response_mock):
"grade_entry_items": None,
}
_, kwargs = response_mock.call_args
assert kwargs["params"] == params
assert kwargs["json"] == params

def test_called_with_is_show_grade_entry_items(self, api, response_mock):
now = datetime.datetime.now()
Expand All @@ -309,7 +307,7 @@ def test_called_with_is_show_grade_entry_items(self, api, response_mock):
"grade_entry_items": ge_items,
}
_, kwargs = response_mock.call_args
assert kwargs["params"] == params
assert kwargs["json"] == params


class TestUpdateMarksSpreadsheet(AbstractTestClass):
Expand All @@ -327,21 +325,21 @@ def test_called_with_basic_params(self, api, response_mock):
api.update_marks_spreadsheet(1, 1, "test", "description", now)
params = {"course_id": 1, "short_identifier": "test", "description": "description", "date": now}
_, kwargs = response_mock.call_args
assert kwargs["params"] == params
assert kwargs["json"] == params

def test_called_with_is_hidden(self, api, response_mock):
now = datetime.datetime.now()
api.update_marks_spreadsheet(1, 1, "test", "description", now, is_hidden=False)
params = {"course_id": 1, "short_identifier": "test", "description": "description", "date": now, "is_hidden": False}
_, kwargs = response_mock.call_args
assert kwargs["params"] == params
assert kwargs["json"] == params

def test_called_with_is_show_total(self, api, response_mock):
now = datetime.datetime.now()
api.update_marks_spreadsheet(1, 1, "test", "description", now, show_total=False)
params = {"course_id": 1, "short_identifier": "test", "description": "description", "date": now, "show_total": False}
_, kwargs = response_mock.call_args
assert kwargs["params"] == params
assert kwargs["json"] == params

def test_called_with_is_show_grade_entry_items(self, api, response_mock):
now = datetime.datetime.now()
Expand All @@ -355,7 +353,7 @@ def test_called_with_is_show_grade_entry_items(self, api, response_mock):
"grade_entry_items": ge_items,
}
_, kwargs = response_mock.call_args
assert kwargs["params"] == params
assert kwargs["json"] == params


class TestUpdateMarksSpreadsheetGrades(AbstractTestClass):
Expand Down Expand Up @@ -465,10 +463,9 @@ class TestUploadAnnotations(AbstractTestClass):
}
]

@classmethod
@pytest.fixture
def basic_call(cls, api):
yield api.upload_annotations(1, 1, 1, cls.annotations)
def basic_call(self, request, api):
yield api.upload_annotations(1, 1, 1, request.cls.annotations)

def test_called_with_basic_params(self, api, response_mock):
api.upload_annotations(1, 1, 1, self.annotations)
Expand Down
Loading