diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index 4b99260..54731c9 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -8,9 +8,25 @@ on: jobs: build_and_release: runs-on: ubuntu-latest + strategy: + matrix: + python-version: [ "3.9" ] steps: - uses: actions/checkout@v3 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install pytest + if [ -f requirements.txt ]; then pip install -r requirements.txt; fi + - name: Test with pytest + run: | + python -m pytest + - name: Setup QEMU uses: docker/setup-qemu-action@v2 diff --git a/models/match.py b/models/match.py index 9e41420..55d50d2 100644 --- a/models/match.py +++ b/models/match.py @@ -2,11 +2,7 @@ first level class """ import enum -from email.policy import default import json -from random import choices - -from numpy import require from database.db import db, CustomQuerySet @@ -27,29 +23,29 @@ class Match(db.Document): player_dist1 = db.ListField(db.IntField()) player_dist2 = db.ListField(db.IntField()) # allies or axis - side1 = db.StringField(choices=('Axis', 'Allies')) - side2 = db.StringField(choices=('Axis', 'Allies')) + side1 = db.StringField(choices=('Axis', 'Allies')) + side2 = db.StringField(choices=('Axis', 'Allies')) # strong points hold at the end of the game - caps1 = db.IntField(required=True, choices=(0, 1, 2, 3, 4, 5)) - caps2 = db.IntField(required=True, choices=(0, 1, 2, 3, 4, 5)) + caps1 = db.IntField(required=True, choices=(0, 1, 2, 3, 4, 5)) + caps2 = db.IntField(required=True, choices=(0, 1, 2, 3, 4, 5)) # number of players on each side (assuming both teams had the same number of players) - players = db.IntField() - map = db.StringField(required=True) + players = db.IntField() + map = db.StringField(required=True) strongpoints = db.ListField(db.StringField(), max_length=5) - date = db.DateTimeField(required=True) + date = db.DateTimeField(required=True) # how long the game lasted, max is 90 min - duration = db.IntField() + duration = db.IntField() # competitive factor, see HeLO calculations - factor = db.FloatField(default=1.0) + factor = db.FloatField(default=1.0) # name of the tournament, of just a training match - event = db.StringField() + event = db.StringField() # confirmation, very important # match must be confirmed from both sides (representatives) in order to # take the match into account # user id of the user who confirmed the match for clan1 - conf1 = db.StringField() + conf1 = db.StringField() # user id of the user who confirmed the match for clan2 - conf2 = db.StringField() + conf2 = db.StringField() # flag to check whether corresponding score objects to the match exist or not score_posted = db.BooleanField() # reserved for admins, necessary to start a recalculate process for this match @@ -96,4 +92,5 @@ def can_be_deleted(self, user_id: str, user_clans: list[str]) -> bool: if r in self.clans2_ids: is_clan2_member = True - return not self.score_posted and (is_clan1_member or is_clan2_member or self.conf1 == user_id and self.conf2 == user_id) + return not self.score_posted and ( + is_clan1_member or is_clan2_member or self.conf1 == user_id or self.conf2 == user_id) diff --git a/models/test_match.py b/models/test_match.py new file mode 100644 index 0000000..5d4737d --- /dev/null +++ b/models/test_match.py @@ -0,0 +1,64 @@ +import pytest + +from match import Match + + +class TestNeedsConfirmation: + @pytest.fixture + def a_match(self) -> Match: + return Match() + + def test_no_confirm_if_both_set(self, a_match: Match): + a_match.conf1 = "A_USER" + a_match.conf2 = "ANOTHER_USER" + + assert not a_match.needs_confirmations() + + def test_needs_confirm_if_first_not_set(self, a_match: Match): + a_match.conf1 = "" + a_match.conf2 = "ANOTHER_USER" + + assert a_match.needs_confirmations() + + def test_needs_confirm_if_second_not_set(self, a_match: Match): + a_match.conf2 = "" + a_match.conf1 = "A_USER" + + assert a_match.needs_confirmations() + + +class TestCanBeDeleted: + @pytest.fixture + def sig(self) -> [Match, str, list[str]]: + m = Match() + m.score_posted = False + m.clans1_ids = ["FIRST_CLAN", "SECOND_CLAN"] + m.clans2_ids = ["SECOND_CLAN"] + return [m, "A_USER_ID"] + + def test_member_of_first_clans(self, sig: [Match, str]): + m, user_id = sig + + assert m.can_be_deleted(user_id, m.clans1_ids) + + def test_member_of_second_clans(self, sig: [Match, str]): + m, user_id = sig + + assert m.can_be_deleted(user_id, m.clans2_ids) + + def test_confirmer_of_first_clan(self, sig: [Match, str]): + m, user_id = sig + m.conf1 = user_id + + assert m.can_be_deleted(user_id, []) + + def test_confirmer_of_second_clan(self, sig: [Match, str]): + m, user_id = sig + m.conf2 = user_id + + assert m.can_be_deleted(user_id, []) + + def test_no_permission_to_delete(self, sig: [Match, str]): + m, user_id = sig + + assert not m.can_be_deleted(user_id, []) diff --git a/requirements.txt b/requirements.txt index 773f0f8..140e6d2 100644 --- a/requirements.txt +++ b/requirements.txt @@ -43,3 +43,4 @@ virtualenv==20.16.5 Werkzeug==2.0.2 WTForms==3.0.0 Flask-Discord==0.1.69 +pytest==7.2.0