Skip to content

Commit

Permalink
Merge pull request #1161 from tkdchen/remove-django320-from-testenv
Browse files Browse the repository at this point in the history
Remove django320 from testenv
  • Loading branch information
tkdchen committed May 4, 2024
2 parents cc8e3bf + 63f3985 commit eba0e5c
Show file tree
Hide file tree
Showing 25 changed files with 83 additions and 113 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/linter.yaml
Expand Up @@ -36,17 +36,17 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
django-version: [django320]
django-version: [django420]
steps:
- run: |
sudo apt update
sudo apt-get install gcc python3-dev libkrb5-dev libmariadb-dev libcrypt-dev
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: 3.9
python-version: 3.11
- name: Install tox
run: |
python3 -m pip install --upgrade pip
python3 -m pip install 'tox<4.0'
python3 -m pip install tox
- run: tox -e mypy-${{ matrix.django-version }}
11 changes: 1 addition & 10 deletions .github/workflows/unittests.yaml
Expand Up @@ -17,18 +17,9 @@ jobs:
max-parallel: 7
matrix:
python-version: [3.9, '3.10', '3.11']
django-version: [django320, django420]
django-version: [django420]
db: [sqlite]
include:
- python-version: '3.11'
django-version: django320
db: mysql
- python-version: '3.11'
django-version: django320
db: mariadb
- python-version: '3.11'
django-version: django320
db: postgres
- python-version: '3.11'
django-version: django420
db: mysql
Expand Down
39 changes: 15 additions & 24 deletions src/tcms/core/ajax.py
Expand Up @@ -328,9 +328,7 @@ def _record_log_actions(log_actions_info: list[LogActionInfo]) -> None:
params["who"],
)

def _simple_update(
self, models: Union[QuerySet, list[TCMSActionModel]], new_value: Any
) -> None:
def _simple_update(self, models, new_value: Any) -> None:
"""A simple update method for most cases to update property of a set of cases
In the most of the cases, the property update requires two steps, one is to update the
Expand All @@ -355,19 +353,13 @@ def _simple_update(
if original_value == str(new_value):
continue

log_actions_info.append(
(
model,
[
{
"who": self.request.user,
"field": self.target_field,
"original_value": original_value,
"new_value": str(new_value),
}
],
)
)
params = {
"who": self.request.user,
"field": self.target_field,
"original_value": original_value,
"new_value": str(new_value),
}
log_actions_info.append((model, [params]))

setattr(model, self.target_field, new_value)
changed.append(model)
Expand Down Expand Up @@ -451,7 +443,7 @@ def __init__(self, *args, **kwargs):
f.queryset = TestCaseRun.objects.select_related("case", "assignee").only(
"case", "assignee__username"
)
f: forms.ModelChoiceField = self.fields["new_value"]
f = self.fields["new_value"]
new_assignee_pk = self.data.get("new_value")
f.error_messages["invalid_choice"] = f"No user with id {new_assignee_pk} exists."

Expand Down Expand Up @@ -488,7 +480,7 @@ def __init__(self, *args, **kwargs):
f.queryset = TestCaseRun.objects.select_related("case_run_status", "tested_by").only(
"close_date", "tested_by__username", "case_run_status__name"
)
f: forms.ModelChoiceField = self.fields["new_value"]
f = self.fields["new_value"]
new_status = self.data.get("new_value")
f.error_messages[
"invalid_choice"
Expand Down Expand Up @@ -517,15 +509,14 @@ def _update_case_run_status(self):
if not f.is_valid():
return JsonResponseBadRequest({"message": form_error_messages_to_list(f)})

request_user: User = self.request.user
request_user = self.request.user
new_status = f.cleaned_data["new_value"]
update_time = datetime.datetime.now()

log_actions_info = []
changed: list[TestCaseRun] = []
changed = []
tested_by_changed = False

case_run: TestCaseRun
for case_run in f.cleaned_data["case_run"]:
if case_run.case_run_status == new_status:
continue
Expand Down Expand Up @@ -618,7 +609,7 @@ def __init__(self, *args, **kwargs):
f.queryset = TestCase.objects.select_related("default_tester").only(
"default_tester__username"
)
f: forms.ModelChoiceField = self.fields["new_value"]
f = self.fields["new_value"]
f.error_messages["invalid_choice"] = (
f"{self.data['new_value']} cannot be set as a default tester, "
f"since this user does not exist."
Expand Down Expand Up @@ -654,7 +645,7 @@ def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
f = self.fields["case"]
f.queryset = TestCase.objects.select_related("reviewer").only("reviewer__username")
f: forms.ModelChoiceField = self.fields["new_value"]
f = self.fields["new_value"]
f.error_messages["invalid_choice"] = f"Reviewer {self.data['new_value']} is not found"


Expand All @@ -680,7 +671,7 @@ class PatchTestCaseSortKeyForm(PatchTestCaseBaseForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields["case"].queryset = TestCase.objects.only("pk")
f: forms.ModelChoiceField = self.fields["plan"]
f = self.fields["plan"]
f.error_messages["invalid_choice"] = f"No plan with id {self.data['plan']} exists."


Expand Down
2 changes: 1 addition & 1 deletion src/tcms/core/files.py
Expand Up @@ -64,7 +64,7 @@ def post(self, request):
if not upload_file:
return HttpResponseRedirect(redirect_url)

upload_file: UploadedFile = request.FILES["upload_file"]
upload_file = request.FILES["upload_file"]

if upload_file.size > settings.MAX_UPLOAD_SIZE:
return prompt.alert(
Expand Down
6 changes: 4 additions & 2 deletions src/tcms/core/views/prompt.py
@@ -1,22 +1,24 @@
# -*- coding: utf-8 -*-
# FIXME: Use exception to replace the feature

from typing import Optional

from django.http import HttpRequest
from django.shortcuts import render

PROMPT_ALERT = "alert"
PROMPT_INFO = "info"


def alert(request: HttpRequest, content: str, next_: str = None):
def alert(request: HttpRequest, content: str, next_: Optional[str] = None):
return render(
request,
"prompt.html",
context={"type": PROMPT_ALERT, "info": content, "next": next_},
)


def info(request: HttpRequest, content: str, next_: str = None):
def info(request: HttpRequest, content: str, next_: Optional[str] = None):
return render(
request,
"prompt.html",
Expand Down
5 changes: 2 additions & 3 deletions src/tcms/management/models.py
Expand Up @@ -251,8 +251,7 @@ def to_xmlrpc(cls, query=None):
return s.serialize_queryset()

@classmethod
def search(cls, query):
val: Any
def search(cls, query: dict[str, Any]):
criteria: dict[str, Any] = {}

if val := query.get("build_id"):
Expand Down Expand Up @@ -536,7 +535,7 @@ def get_active(cls):


# FIXME: plugins_support is no longer available, this is dead code.
if register_model:
if register_model: # type: ignore
register_model(Classification)
register_model(Product)
register_model(Priority)
Expand Down
6 changes: 3 additions & 3 deletions src/tcms/testcases/models.py
Expand Up @@ -2,7 +2,7 @@

import logging
from datetime import datetime
from typing import Any, Optional, Union
from typing import Any, Dict, Optional, Union

from django.conf import settings
from django.contrib.contenttypes.fields import GenericRelation
Expand Down Expand Up @@ -235,7 +235,7 @@ def update(cls, case_ids, values):
return tcs

@classmethod
def search(cls, query, plan=None):
def search(cls, query: Dict[str, Any], plan: Optional[int] = None) -> QuerySet["TestCase"]:
"""List the cases with request"""
from django.db.models import Q

Expand Down Expand Up @@ -1052,7 +1052,7 @@ def _listen():
if settings.LISTENING_MODEL_SIGNAL:
_listen()

if register_model:
if register_model: # type: ignore
register_model(TestCase)
register_model(TestCaseText)
register_model(TestCasePlan)
Expand Down
3 changes: 1 addition & 2 deletions src/tcms/testcases/views.py
Expand Up @@ -763,7 +763,7 @@ def get_context_data(self, **kwargs):
this_cls = TestCaseCaseRunDetailPanelView
data = super(this_cls, self).get_context_data(**kwargs)

case: TestCase = get_object_or_404(TestCase.objects.only("pk"), pk=self.case_id)
case = get_object_or_404(TestCase.objects.only("pk"), pk=self.case_id)
case_run = get_object_or_404(TestCaseRun, pk=self.case_run_id, case=case)

# Data of TestCase
Expand Down Expand Up @@ -1250,7 +1250,6 @@ def clone(request, template_name="case/clone.html"):
src_plan = plan_from_request_or_none(request)
dest_case = None

src_cases: TestCase
for src_case in src_cases:
author = None if keep_orig_author else request.user
default_tester = None if keep_orig_default_tester else request.user
Expand Down
4 changes: 2 additions & 2 deletions src/tcms/testplans/models.py
Expand Up @@ -80,7 +80,7 @@ class TestPlan(TCMSActionModel):
)
env_group = models.ManyToManyField(
"management.TCMSEnvGroup", related_name="plans", through="TCMSEnvPlanMap"
)
) # type: ignore
tag = models.ManyToManyField("management.TestTag", through="testplans.TestPlanTag")

class Meta:
Expand Down Expand Up @@ -634,7 +634,7 @@ def set_email_settings_to_new_plan(sender, **kwargs):
TestPlanEmailSettings.objects.create(plan=kwargs["instance"])


if register_model:
if register_model: # type: ignore
register_model(TestPlan)
register_model(TestPlanText)
register_model(TestPlanType)
Expand Down
8 changes: 4 additions & 4 deletions src/tcms/testplans/views.py
Expand Up @@ -994,7 +994,7 @@ def handle_no_permission(self):
)

def patch(self, request, *args, **kwargs):
plan: TestPlan = TestPlan.objects.filter(pk=self.kwargs["plan_id"]).only("pk").first()
plan = TestPlan.objects.filter(pk=self.kwargs["plan_id"]).only("pk").first()
if plan is None:
return JsonResponseNotFound(
{
Expand All @@ -1004,7 +1004,7 @@ def patch(self, request, *args, **kwargs):
)

data = json.loads(request.body)
user_input: Optional[str] = data.get("parent")
user_input = data.get("parent")
if user_input is None:
return JsonResponseBadRequest({"message": "Missing parent plan id."})
if not isinstance(user_input, int):
Expand Down Expand Up @@ -1049,10 +1049,10 @@ class SetPlanActiveView(PermissionRequiredMixin, View):

def patch(self, request, *args, **kwargs):
plan_id = self.kwargs["plan_id"]
plan: TestPlan = TestPlan.objects.filter(pk=plan_id).only("is_active").first()
plan = TestPlan.objects.filter(pk=plan_id).only("is_active").first()
if not plan:
return JsonResponseNotFound({"message": f"Plan id {plan_id} does not exist."})
original_value: str = str(plan.is_active)
original_value = str(plan.is_active)
plan.is_active = self.enable
plan.save(update_fields=["is_active"])
plan.log_action(
Expand Down
3 changes: 1 addition & 2 deletions src/tcms/testruns/helpers/serializer.py
Expand Up @@ -5,7 +5,6 @@

import csv

from django.template import Template
from django.template.loader import get_template

# TODO: rewrite export module to export TestCaseRuns, TestPlans and other
Expand Down Expand Up @@ -84,5 +83,5 @@ def write_to_xml(self, output):
.. versionchanged:: 4.2
Element ``bugs`` is renamed to ``issues``.
"""
xml_template: Template = get_template("run/export-to.xml")
xml_template = get_template("run/export-to.xml")
output.write(xml_template.render({"case_runs": self.tcrs}))
4 changes: 2 additions & 2 deletions src/tcms/testruns/models.py
Expand Up @@ -229,7 +229,7 @@ def add_cc(self, user):
def add_env_value(self, env_value: TCMSEnvValue):
return TCMSEnvRunValueMap.objects.get_or_create(run=self, value=env_value)

def remove_tag(self, tag):
def remove_tag(self, tag: TestTag) -> None:
cursor = connection.writer_cursor
cursor.execute(
"DELETE from test_run_tags WHERE run_id = %s AND tag_id = %s",
Expand Down Expand Up @@ -617,7 +617,7 @@ def _run_listen():
if settings.LISTENING_MODEL_SIGNAL:
_run_listen()

if register_model:
if register_model: # type: ignore
register_model(TestRun)
register_model(TestCaseRun)
register_model(TestRunTag)
7 changes: 3 additions & 4 deletions src/tcms/testruns/views.py
Expand Up @@ -610,7 +610,7 @@ class RunStatisticsView(TemplateView):
def get_context_data(self, **kwargs):
data = super().get_context_data()
run_id = self.kwargs["run_id"]
run: TestRun = get_object_or_404(TestRun.objects.only("pk"), pk=run_id)
run = get_object_or_404(TestRun.objects.only("pk"), pk=run_id)
data.update(
{
"test_run": run,
Expand All @@ -628,7 +628,7 @@ def get(request, run_id, template_name="run/get.html"):
SUB_MODULE_NAME = "runs"

# Get the test run
tr: TestRun = get_object_or_404(TestRun.objects.select_related(), pk=run_id)
tr = get_object_or_404(TestRun.objects.select_related(), pk=run_id)

# Get the test case runs belong to the run
# 2. get test run's all case runs
Expand Down Expand Up @@ -695,7 +695,7 @@ def edit(request, run_id, template_name="run/edit.html"):
SUB_MODULE_NAME = "runs"

try:
tr: TestRun = TestRun.objects.select_related().get(run_id=run_id)
tr = TestRun.objects.select_related().get(run_id=run_id)
except ObjectDoesNotExist:
raise Http404

Expand Down Expand Up @@ -821,7 +821,6 @@ def get_context_data(self, **kwargs):
automated_count = 0
manual_automated_count = 0

case_run: TestCaseRun
for case_run in case_runs:
case_run.display_issues = issues_by_case_run.get(case_run.pk, ())
user_comments = comments.get(case_run.pk, [])
Expand Down
4 changes: 1 addition & 3 deletions src/tcms/xmlrpc/api/testrun.py
Expand Up @@ -132,11 +132,10 @@ def add_tag(request, run_ids, tags):
TestPlan.add_tag('1, 2', 'foo, bar')
"""
trs = TestRun.objects.filter(pk__in=pre_process_ids(value=run_ids))
tags: list[str] = TestTag.string_to_list(tags)
tags = TestTag.string_to_list(tags)

for tag in tags:
t, _ = TestTag.objects.get_or_create(name=tag)
tr: TestRun
for tr in trs.iterator():
tr.add_tag(tag=t)

Expand Down Expand Up @@ -533,7 +532,6 @@ def remove_tag(request, run_ids, tags):
trs = TestRun.objects.filter(run_id__in=pre_process_ids(value=run_ids))
tgs = TestTag.objects.filter(name__in=TestTag.string_to_list(tags))

tr: TestRun
for tr in trs.iterator():
for tg in tgs.iterator():
tr.remove_tag(tag=tg)
Expand Down
4 changes: 4 additions & 0 deletions tests/__init__.py
Expand Up @@ -5,6 +5,7 @@
import re
from functools import partial
from http import HTTPStatus
from typing import ClassVar
from urllib.parse import parse_qs, urlparse

from django import test
Expand Down Expand Up @@ -230,6 +231,9 @@ def get_max_plan_id(self):
class BasePlanCase(AuthMixin, HelperAssertions, NitrateTestCase):
"""Base test case by providing essential Plan and Case objects used in tests"""

case_1: ClassVar
case_3: ClassVar

@classmethod
def setUpTestData(cls):
super().setUpTestData()
Expand Down

0 comments on commit eba0e5c

Please sign in to comment.