housekeep: TU rename - Table/Column names, scripts

TU_VoteInfo -> VoteInfo
TU_Votes -> Votes
TU_VoteInfo.ActiveTUs -> VoteInfo.ActiveUsers

script: tuvotereminder -> votereminder
Signed-off-by: moson <moson@archlinux.org>
This commit is contained in:
moson 2023-09-10 11:19:56 +02:00
parent 3ee15bfc24
commit 6d92bdee8a
No known key found for this signature in database
GPG key ID: 4A4760AB4EE15296
23 changed files with 234 additions and 192 deletions

View file

@ -120,7 +120,7 @@ interval:
*/2 * * * * bash -c 'poetry run aurweb-pkgmaint'
*/2 * * * * bash -c 'poetry run aurweb-usermaint'
*/2 * * * * bash -c 'poetry run aurweb-popupdate'
*/12 * * * * bash -c 'poetry run aurweb-tuvotereminder'
*/12 * * * * bash -c 'poetry run aurweb-votereminder'
7) Create a new database and a user and import the aurweb SQL schema:

View file

@ -118,9 +118,9 @@ def to_qs(query: dict[str, Any]) -> str:
@register_filter("get_vote")
def get_vote(voteinfo, request: fastapi.Request):
from aurweb.models import TUVote
from aurweb.models import Vote
return voteinfo.tu_votes.filter(TUVote.User == request.user).first()
return voteinfo.votes.filter(Vote.User == request.user).first()
@register_filter("number_format")

View file

@ -26,6 +26,6 @@ from .request_type import RequestType # noqa: F401
from .session import Session # noqa: F401
from .ssh_pub_key import SSHPubKey # noqa: F401
from .term import Term # noqa: F401
from .tu_vote import TUVote # noqa: F401
from .tu_voteinfo import TUVoteInfo # noqa: F401
from .user import User # noqa: F401
from .vote import Vote # noqa: F401
from .voteinfo import VoteInfo # noqa: F401

View file

@ -3,24 +3,24 @@ from sqlalchemy.orm import backref, relationship
from aurweb import schema
from aurweb.models.declarative import Base
from aurweb.models.tu_voteinfo import TUVoteInfo as _TUVoteInfo
from aurweb.models.user import User as _User
from aurweb.models.voteinfo import VoteInfo as _VoteInfo
class TUVote(Base):
__table__ = schema.TU_Votes
class Vote(Base):
__table__ = schema.Votes
__tablename__ = __table__.name
__mapper_args__ = {"primary_key": [__table__.c.VoteID, __table__.c.UserID]}
VoteInfo = relationship(
_TUVoteInfo,
backref=backref("tu_votes", lazy="dynamic"),
_VoteInfo,
backref=backref("votes", lazy="dynamic"),
foreign_keys=[__table__.c.VoteID],
)
User = relationship(
_User,
backref=backref("tu_votes", lazy="dynamic"),
backref=backref("votes", lazy="dynamic"),
foreign_keys=[__table__.c.UserID],
)
@ -30,13 +30,13 @@ class TUVote(Base):
if not self.VoteInfo and not self.VoteID:
raise IntegrityError(
statement="Foreign key VoteID cannot be null.",
orig="TU_Votes.VoteID",
orig="Votes.VoteID",
params=("NULL"),
)
if not self.User and not self.UserID:
raise IntegrityError(
statement="Foreign key UserID cannot be null.",
orig="TU_Votes.UserID",
orig="Votes.UserID",
params=("NULL"),
)

View file

@ -8,14 +8,14 @@ from aurweb.models.declarative import Base
from aurweb.models.user import User as _User
class TUVoteInfo(Base):
__table__ = schema.TU_VoteInfo
class VoteInfo(Base):
__table__ = schema.VoteInfo
__tablename__ = __table__.name
__mapper_args__ = {"primary_key": [__table__.c.ID]}
Submitter = relationship(
_User,
backref=backref("tu_voteinfo_set", lazy="dynamic"),
backref=backref("voteinfo_set", lazy="dynamic"),
foreign_keys=[__table__.c.SubmitterID],
)
@ -30,35 +30,35 @@ class TUVoteInfo(Base):
if self.Agenda is None:
raise IntegrityError(
statement="Column Agenda cannot be null.",
orig="TU_VoteInfo.Agenda",
orig="VoteInfo.Agenda",
params=("NULL"),
)
if self.User is None:
raise IntegrityError(
statement="Column User cannot be null.",
orig="TU_VoteInfo.User",
orig="VoteInfo.User",
params=("NULL"),
)
if self.Submitted is None:
raise IntegrityError(
statement="Column Submitted cannot be null.",
orig="TU_VoteInfo.Submitted",
orig="VoteInfo.Submitted",
params=("NULL"),
)
if self.End is None:
raise IntegrityError(
statement="Column End cannot be null.",
orig="TU_VoteInfo.End",
orig="VoteInfo.End",
params=("NULL"),
)
if not self.Submitter:
raise IntegrityError(
statement="Foreign key SubmitterID cannot be null.",
orig="TU_VoteInfo.SubmitterID",
orig="VoteInfo.SubmitterID",
params=("NULL"),
)

View file

@ -87,9 +87,9 @@ async def package_maintainer(
context["past_by"] = past_by
current_votes = (
db.query(models.TUVoteInfo)
.filter(models.TUVoteInfo.End > ts)
.order_by(models.TUVoteInfo.Submitted.desc())
db.query(models.VoteInfo)
.filter(models.VoteInfo.End > ts)
.order_by(models.VoteInfo.Submitted.desc())
)
context["current_votes_count"] = current_votes.count()
current_votes = current_votes.limit(pp).offset(current_off)
@ -99,9 +99,9 @@ async def package_maintainer(
context["current_off"] = current_off
past_votes = (
db.query(models.TUVoteInfo)
.filter(models.TUVoteInfo.End <= ts)
.order_by(models.TUVoteInfo.Submitted.desc())
db.query(models.VoteInfo)
.filter(models.VoteInfo.End <= ts)
.order_by(models.VoteInfo.Submitted.desc())
)
context["past_votes_count"] = past_votes.count()
past_votes = past_votes.limit(pp).offset(past_off)
@ -110,21 +110,21 @@ async def package_maintainer(
)
context["past_off"] = past_off
last_vote = func.max(models.TUVote.VoteID).label("LastVote")
last_vote = func.max(models.Vote.VoteID).label("LastVote")
last_votes_by_pm = (
db.query(models.TUVote)
db.query(models.Vote)
.join(models.User)
.join(models.TUVoteInfo, models.TUVoteInfo.ID == models.TUVote.VoteID)
.join(models.VoteInfo, models.VoteInfo.ID == models.Vote.VoteID)
.filter(
and_(
models.TUVote.VoteID == models.TUVoteInfo.ID,
models.User.ID == models.TUVote.UserID,
models.TUVoteInfo.End < ts,
models.Vote.VoteID == models.VoteInfo.ID,
models.User.ID == models.Vote.UserID,
models.VoteInfo.End < ts,
or_(models.User.AccountTypeID == 2, models.User.AccountTypeID == 4),
)
)
.with_entities(models.TUVote.UserID, last_vote, models.User.Username)
.group_by(models.TUVote.UserID)
.with_entities(models.Vote.UserID, last_vote, models.User.Username)
.group_by(models.Vote.UserID)
.order_by(last_vote.desc(), models.User.Username.asc())
)
context["last_votes_by_pm"] = last_votes_by_pm.all()
@ -148,9 +148,9 @@ def render_proposal(
request: Request,
context: dict,
proposal: int,
voteinfo: models.TUVoteInfo,
voteinfo: models.VoteInfo,
voters: typing.Iterable[models.User],
vote: models.TUVote,
vote: models.Vote,
status_code: HTTPStatus = HTTPStatus.OK,
):
"""Render a single PM proposal."""
@ -159,15 +159,15 @@ def render_proposal(
context["voters"] = voters.all()
total = voteinfo.total_votes()
participation = (total / voteinfo.ActiveTUs) if voteinfo.ActiveTUs else 0
participation = (total / voteinfo.ActiveUsers) if voteinfo.ActiveUsers else 0
context["participation"] = participation
accepted = (voteinfo.Yes > voteinfo.ActiveTUs / 2) or (
accepted = (voteinfo.Yes > voteinfo.ActiveUsers / 2) or (
participation > voteinfo.Quorum and voteinfo.Yes > voteinfo.No
)
context["accepted"] = accepted
can_vote = voters.filter(models.TUVote.User == request.user).first() is None
can_vote = voters.filter(models.Vote.User == request.user).first() is None
context["can_vote"] = can_vote
if not voteinfo.is_running():
@ -190,23 +190,21 @@ async def package_maintainer_proposal(request: Request, proposal: int):
context = await make_variable_context(request, "Package Maintainer")
proposal = int(proposal)
voteinfo = (
db.query(models.TUVoteInfo).filter(models.TUVoteInfo.ID == proposal).first()
)
voteinfo = db.query(models.VoteInfo).filter(models.VoteInfo.ID == proposal).first()
if not voteinfo:
raise HTTPException(status_code=HTTPStatus.NOT_FOUND)
voters = (
db.query(models.User)
.join(models.TUVote)
.filter(models.TUVote.VoteID == voteinfo.ID)
.join(models.Vote)
.filter(models.Vote.VoteID == voteinfo.ID)
)
vote = (
db.query(models.TUVote)
db.query(models.Vote)
.filter(
and_(
models.TUVote.UserID == request.user.ID,
models.TUVote.VoteID == voteinfo.ID,
models.Vote.UserID == request.user.ID,
models.Vote.VoteID == voteinfo.ID,
)
)
.first()
@ -235,23 +233,21 @@ async def package_maintainer_proposal_post(
context = await make_variable_context(request, "Package Maintainer")
proposal = int(proposal) # Make sure it's an int.
voteinfo = (
db.query(models.TUVoteInfo).filter(models.TUVoteInfo.ID == proposal).first()
)
voteinfo = db.query(models.VoteInfo).filter(models.VoteInfo.ID == proposal).first()
if not voteinfo:
raise HTTPException(status_code=HTTPStatus.NOT_FOUND)
voters = (
db.query(models.User)
.join(models.TUVote)
.filter(models.TUVote.VoteID == voteinfo.ID)
.join(models.Vote)
.filter(models.Vote.VoteID == voteinfo.ID)
)
vote = (
db.query(models.TUVote)
db.query(models.Vote)
.filter(
and_(
models.TUVote.UserID == request.user.ID,
models.TUVote.VoteID == voteinfo.ID,
models.Vote.UserID == request.user.ID,
models.Vote.VoteID == voteinfo.ID,
)
)
.first()
@ -282,7 +278,7 @@ async def package_maintainer_proposal_post(
"Invalid 'decision' value.", status_code=HTTPStatus.BAD_REQUEST
)
vote = db.create(models.TUVote, User=request.user, VoteInfo=voteinfo)
vote = db.create(models.Vote, User=request.user, VoteInfo=voteinfo)
context["error"] = "You've already voted for this proposal."
return render_proposal(request, context, proposal, voteinfo, voters, vote)
@ -342,10 +338,8 @@ async def package_maintainer_addvote_post(
utcnow = time.utcnow()
voteinfo = (
db.query(models.TUVoteInfo)
.filter(
and_(models.TUVoteInfo.User == user, models.TUVoteInfo.End > utcnow)
)
db.query(models.VoteInfo)
.filter(and_(models.VoteInfo.User == user, models.VoteInfo.End > utcnow))
.count()
)
if voteinfo:
@ -371,7 +365,7 @@ async def package_maintainer_addvote_post(
# Active PM types we filter for.
types = {PACKAGE_MAINTAINER_ID, PACKAGE_MAINTAINER_AND_DEV_ID}
# Create a new TUVoteInfo (proposal)!
# Create a new VoteInfo (proposal)!
with db.begin():
active_pms = (
db.query(User)
@ -385,13 +379,13 @@ async def package_maintainer_addvote_post(
.count()
)
voteinfo = db.create(
models.TUVoteInfo,
models.VoteInfo,
User=user,
Agenda=html.escape(agenda),
Submitted=timestamp,
End=(timestamp + duration),
Quorum=quorum,
ActiveTUs=active_pms,
ActiveUsers=active_pms,
Submitter=request.user,
)

View file

@ -526,8 +526,8 @@ PackageRequests = Table(
# Vote information
TU_VoteInfo = Table(
"TU_VoteInfo",
VoteInfo = Table(
"VoteInfo",
metadata,
Column("ID", INTEGER(unsigned=True), primary_key=True),
Column("Agenda", Text, nullable=False),
@ -546,7 +546,10 @@ TU_VoteInfo = Table(
"Abstain", INTEGER(unsigned=True), nullable=False, server_default=text("'0'")
),
Column(
"ActiveTUs", INTEGER(unsigned=True), nullable=False, server_default=text("'0'")
"ActiveUsers",
INTEGER(unsigned=True),
nullable=False,
server_default=text("'0'"),
),
mysql_engine="InnoDB",
mysql_charset="utf8mb4",
@ -555,10 +558,10 @@ TU_VoteInfo = Table(
# Individual vote records
TU_Votes = Table(
"TU_Votes",
Votes = Table(
"Votes",
metadata,
Column("VoteID", ForeignKey("TU_VoteInfo.ID", ondelete="CASCADE"), nullable=False),
Column("VoteID", ForeignKey("VoteInfo.ID", ondelete="CASCADE"), nullable=False),
Column("UserID", ForeignKey("Users.ID", ondelete="CASCADE"), nullable=False),
mysql_engine="InnoDB",
)

View file

@ -20,7 +20,7 @@ from aurweb.models.package_comment import PackageComment
from aurweb.models.package_notification import PackageNotification
from aurweb.models.package_request import PackageRequest
from aurweb.models.request_type import RequestType
from aurweb.models.tu_vote import TUVote
from aurweb.models.vote import Vote
logger = aur_logging.get_logger(__name__)
@ -744,11 +744,11 @@ class RequestCloseNotification(Notification):
return headers
class TUVoteReminderNotification(Notification):
class VoteReminderNotification(Notification):
def __init__(self, vote_id):
self._vote_id = int(vote_id)
subquery = db.query(TUVote.UserID).filter(TUVote.VoteID == vote_id)
subquery = db.query(Vote.UserID).filter(Vote.VoteID == vote_id)
query = (
db.query(User)
.filter(
@ -799,7 +799,7 @@ def main():
"delete": DeleteNotification,
"request-open": RequestOpenNotification,
"request-close": RequestCloseNotification,
"tu-vote-reminder": TUVoteReminderNotification,
"vote-reminder": VoteReminderNotification,
}
with db.begin():

View file

@ -4,7 +4,7 @@ from sqlalchemy import and_
import aurweb.config
from aurweb import db, time
from aurweb.models import TUVoteInfo
from aurweb.models import VoteInfo
from aurweb.scripts import notify
notify_cmd = aurweb.config.get("notifications", "notify-cmd")
@ -15,17 +15,17 @@ def main():
now = time.utcnow()
start = aurweb.config.getint("tuvotereminder", "range_start")
start = aurweb.config.getint("votereminder", "range_start")
filter_from = now + start
end = aurweb.config.getint("tuvotereminder", "range_end")
end = aurweb.config.getint("votereminder", "range_end")
filter_to = now + end
query = db.query(TUVoteInfo.ID).filter(
and_(TUVoteInfo.End >= filter_from, TUVoteInfo.End <= filter_to)
query = db.query(VoteInfo.ID).filter(
and_(VoteInfo.End >= filter_from, VoteInfo.End <= filter_to)
)
for voteinfo in query:
notif = notify.TUVoteReminderNotification(voteinfo.ID)
notif = notify.VoteReminderNotification(voteinfo.ID)
notif.send()

View file

@ -51,8 +51,8 @@ def setup_test_db(*args):
models.Session.__tablename__,
models.SSHPubKey.__tablename__,
models.Term.__tablename__,
models.TUVote.__tablename__,
models.TUVoteInfo.__tablename__,
models.Vote.__tablename__,
models.VoteInfo.__tablename__,
models.User.__tablename__,
]

View file

@ -158,7 +158,7 @@ commit_url = https://gitlab.archlinux.org/archlinux/aurweb/-/commits/%s
; sed -r "s/^;?(commit_hash) =.*$/\1 = $(git rev-parse HEAD)/" config
;commit_hash = 1234567
[tuvotereminder]
[votereminder]
; Offsets used to determine when Package Maintainers should be reminded about
; votes that they should make.
; Reminders will be sent out for all votes that a Package Maintainer has not yet

View file

@ -62,7 +62,7 @@ computations and clean up the database:
the official repositories. It is also used to prevent users from uploading
packages that are in the official repositories already.
* aurweb-tuvotereminder sends out reminders to TUs if the voting period for a
* aurweb-votereminder sends out reminders if the voting period for a
Package Maintainer proposal ends soon.
* aurweb-popupdate is used to recompute the popularity score of packages.
@ -107,7 +107,7 @@ usually scheduled using Cron. The current setup is:
2 */2 * * * poetry run aurweb-aurblup
3 */2 * * * poetry run aurweb-pkgmaint
4 */2 * * * poetry run aurweb-usermaint
5 */12 * * * poetry run aurweb-tuvotereminder
5 */12 * * * poetry run aurweb-votereminder
----
Advanced Administrative Features

View file

@ -4,4 +4,4 @@ AUR_CONFIG='/aurweb/conf/config'
*/2 * * * * bash -c 'aurweb-pkgmaint'
*/2 * * * * bash -c 'aurweb-usermaint'
*/2 * * * * bash -c 'aurweb-popupdate'
*/12 * * * * bash -c 'aurweb-tuvotereminder'
*/12 * * * * bash -c 'aurweb-votereminder'

View file

@ -0,0 +1,47 @@
"""Rename TU tables/columns
Revision ID: 7d65d35fae45
Revises: 6a64dd126029
Create Date: 2023-09-10 10:21:33.092342
"""
from alembic import op
from sqlalchemy.dialects.mysql import INTEGER
# revision identifiers, used by Alembic.
revision = "7d65d35fae45"
down_revision = "6a64dd126029"
branch_labels = None
depends_on = None
# TU_VoteInfo -> VoteInfo
# TU_VoteInfo.ActiveTUs -> VoteInfo.ActiveUsers
# TU_Votes -> Votes
def upgrade():
# Tables
op.rename_table("TU_VoteInfo", "VoteInfo")
op.rename_table("TU_Votes", "Votes")
# Columns
op.alter_column(
"VoteInfo",
"ActiveTUs",
existing_type=INTEGER(unsigned=True),
new_column_name="ActiveUsers",
)
def downgrade():
# Tables
op.rename_table("VoteInfo", "TU_VoteInfo")
op.rename_table("Votes", "TU_Votes")
# Columns
op.alter_column(
"TU_VoteInfo",
"ActiveUsers",
existing_type=INTEGER(unsigned=True),
new_column_name="ActiveTUs",
)

View file

@ -116,7 +116,7 @@ aurweb-notify = "aurweb.scripts.notify:main"
aurweb-pkgmaint = "aurweb.scripts.pkgmaint:main"
aurweb-popupdate = "aurweb.scripts.popupdate:main"
aurweb-rendercomment = "aurweb.scripts.rendercomment:main"
aurweb-tuvotereminder = "aurweb.scripts.tuvotereminder:main"
aurweb-votereminder = "aurweb.scripts.votereminder:main"
aurweb-usermaint = "aurweb.scripts.usermaint:main"
aurweb-config = "aurweb.scripts.config:main"
aurweb-adduser = "aurweb.scripts.adduser:main"

View file

@ -357,7 +357,7 @@ for t in range(0, OPEN_PROPOSALS + CLOSE_PROPOSALS):
user = user_keys[random.randrange(0, len(user_keys))]
suid = packagemaintainers[random.randrange(0, len(packagemaintainers))]
s = (
"INSERT INTO TU_VoteInfo (Agenda, User, Submitted, End,"
"INSERT INTO VoteInfo (Agenda, User, Submitted, End,"
" Quorum, SubmitterID) VALUES ('%s', '%s', %d, %d, 0.0, %d);\n"
)
s = s % (genFortune(), user, start, end, suid)

View file

@ -23,7 +23,7 @@
<div class="field">
{{ "Active" | tr }} {{ "Package Maintainers" | tr }} {{ "assigned" | tr }}:
{{ voteinfo.ActiveTUs }}
{{ voteinfo.ActiveUsers }}
</div>
{% set submitter = voteinfo.Submitter.Username %}
@ -47,7 +47,7 @@
{% if not voteinfo.is_running() %}
<div class="field result">
{{ "Result" | tr }}:
{% if not voteinfo.ActiveTUs %}
{% if not voteinfo.ActiveUsers %}
<span>{{ "unknown" | tr }}</span>
{% elif accepted %}
<span style="color: green; font-weight: bold">
@ -102,7 +102,7 @@
{% endif %}
</td>
<td>
{% if voteinfo.ActiveTUs %}
{% if voteinfo.ActiveUsers %}
{{ (participation * 100) | number_format(2) }}%
{% else %}
{{ "unknown" | tr }}

View file

@ -11,7 +11,7 @@ GIT_AUTH="$TOPLEVEL/aurweb/git/auth.py"
GIT_SERVE="$TOPLEVEL/aurweb/git/serve.py"
GIT_UPDATE="$TOPLEVEL/aurweb/git/update.py"
MKPKGLISTS="$TOPLEVEL/aurweb/scripts/mkpkglists.py"
TUVOTEREMINDER="$TOPLEVEL/aurweb/scripts/tuvotereminder.py"
VOTEREMINDER="$TOPLEVEL/aurweb/scripts/votereminder.py"
PKGMAINT="$TOPLEVEL/aurweb/scripts/pkgmaint.py"
USERMAINT="$TOPLEVEL/aurweb/scripts/usermaint.py"
AURBLUP="$TOPLEVEL/aurweb/scripts/aurblup.py"

View file

@ -544,11 +544,11 @@ This is a test closure comment.
assert email.body == expected
def test_pm_vote_reminders(user: User):
def test_vote_reminders(user: User):
set_tu([user])
vote_id = 1
notif = notify.TUVoteReminderNotification(vote_id)
notif = notify.VoteReminderNotification(vote_id)
notif.send()
assert Email.count() == 1
@ -571,7 +571,7 @@ def test_notify_main(user: User):
set_tu([user])
vote_id = 1
args = ["aurweb-notify", "tu-vote-reminder", str(vote_id)]
args = ["aurweb-notify", "vote-reminder", str(vote_id)]
with mock.patch("sys.argv", args):
notify.main()

View file

@ -9,9 +9,9 @@ from fastapi.testclient import TestClient
from aurweb import config, db, filters, time
from aurweb.models.account_type import DEVELOPER_ID, PACKAGE_MAINTAINER_ID, AccountType
from aurweb.models.tu_vote import TUVote
from aurweb.models.tu_voteinfo import TUVoteInfo
from aurweb.models.user import User
from aurweb.models.vote import Vote
from aurweb.models.voteinfo import VoteInfo
from aurweb.testing.requests import Request
DATETIME_REGEX = r"^[0-9]{4}-[0-9]{2}-[0-9]{2} \(.+\)$"
@ -143,7 +143,7 @@ def proposal(user, pm_user):
with db.begin():
voteinfo = db.create(
TUVoteInfo,
VoteInfo,
Agenda=agenda,
Quorum=0.0,
User=user.Username,
@ -210,7 +210,7 @@ def test_pm_index(client, pm_user):
agenda, start, end = vote
vote_records.append(
db.create(
TUVoteInfo,
VoteInfo,
Agenda=agenda,
User=pm_user.Username,
Submitted=start,
@ -224,8 +224,8 @@ def test_pm_index(client, pm_user):
# Vote on an ended proposal.
vote_record = vote_records[1]
vote_record.Yes += 1
vote_record.ActiveTUs += 1
db.create(TUVote, VoteInfo=vote_record, User=pm_user)
vote_record.ActiveUsers += 1
db.create(Vote, VoteInfo=vote_record, User=pm_user)
cookies = {"AURSID": pm_user.login(Request(), "testPassword")}
with client as request:
@ -347,7 +347,7 @@ def test_pm_index_table_paging(client, pm_user):
for i in range(25):
# Create 25 current votes.
db.create(
TUVoteInfo,
VoteInfo,
Agenda=f"Agenda #{i}",
User=pm_user.Username,
Submitted=(ts - 5),
@ -359,7 +359,7 @@ def test_pm_index_table_paging(client, pm_user):
for i in range(25):
# Create 25 past votes.
db.create(
TUVoteInfo,
VoteInfo,
Agenda=f"Agenda #{25 + i}",
User=pm_user.Username,
Submitted=(ts - 1000),
@ -462,7 +462,7 @@ def test_pm_index_sorting(client, pm_user):
for i in range(2):
# Create 'Agenda #1' and 'Agenda #2'.
db.create(
TUVoteInfo,
VoteInfo,
Agenda=f"Agenda #{i + 1}",
User=pm_user.Username,
Submitted=(ts + 5),
@ -540,21 +540,21 @@ def test_pm_index_last_votes(
with db.begin():
# Create a proposal which has ended.
voteinfo = db.create(
TUVoteInfo,
VoteInfo,
Agenda="Test agenda",
User=user.Username,
Submitted=(ts - 1000),
End=(ts - 5),
Yes=1,
No=1,
ActiveTUs=1,
ActiveUsers=1,
Quorum=0.0,
Submitter=pm_user,
)
# Create a vote on it from pm_user.
db.create(TUVote, VoteInfo=voteinfo, User=pm_user)
db.create(TUVote, VoteInfo=voteinfo, User=pm_user2)
db.create(Vote, VoteInfo=voteinfo, User=pm_user)
db.create(Vote, VoteInfo=voteinfo, User=pm_user2)
# Now, check that pm_user got populated in the .last-votes table.
cookies = {"AURSID": pm_user.login(Request(), "testPassword")}
@ -590,7 +590,7 @@ def test_pm_proposal_not_found(client, pm_user):
def test_pm_proposal_unauthorized(
client: TestClient, user: User, proposal: Tuple[User, User, TUVoteInfo]
client: TestClient, user: User, proposal: Tuple[User, User, VoteInfo]
):
cookies = {"AURSID": user.login(Request(), "testPassword")}
endpoint = f"/package-maintainer/{proposal[2].ID}"
@ -607,12 +607,10 @@ def test_pm_proposal_unauthorized(
assert response.headers.get("location") == "/package-maintainer"
def test_pm_running_proposal(
client: TestClient, proposal: Tuple[User, User, TUVoteInfo]
):
def test_pm_running_proposal(client: TestClient, proposal: Tuple[User, User, VoteInfo]):
pm_user, user, voteinfo = proposal
with db.begin():
voteinfo.ActiveTUs = 1
voteinfo.ActiveUsers = 1
# Initiate an authenticated GET request to /package-maintainer/{proposal_id}.
proposal_id = voteinfo.ID
@ -683,8 +681,8 @@ def test_pm_running_proposal(
# Create a vote.
with db.begin():
db.create(TUVote, VoteInfo=voteinfo, User=pm_user)
voteinfo.ActiveTUs += 1
db.create(Vote, VoteInfo=voteinfo, User=pm_user)
voteinfo.ActiveUsers += 1
voteinfo.Yes += 1
# Make another request now that we've voted.
@ -772,8 +770,8 @@ def test_pm_proposal_vote(client, proposal):
# Check that the proposal record got updated.
assert voteinfo.Yes == yes + 1
# Check that the new TUVote exists.
vote = db.query(TUVote, TUVote.VoteInfo == voteinfo, TUVote.User == pm_user).first()
# Check that the new PMVote exists.
vote = db.query(Vote, Vote.VoteInfo == voteinfo, Vote.User == pm_user).first()
assert vote is not None
root = parse_root(response.text)
@ -784,7 +782,7 @@ def test_pm_proposal_vote(client, proposal):
def test_pm_proposal_vote_unauthorized(
client: TestClient, proposal: Tuple[User, User, TUVoteInfo]
client: TestClient, proposal: Tuple[User, User, VoteInfo]
):
pm_user, user, voteinfo = proposal
@ -846,9 +844,9 @@ def test_pm_proposal_vote_already_voted(client, proposal):
pm_user, user, voteinfo = proposal
with db.begin():
db.create(TUVote, VoteInfo=voteinfo, User=pm_user)
db.create(Vote, VoteInfo=voteinfo, User=pm_user)
voteinfo.Yes += 1
voteinfo.ActiveTUs += 1
voteinfo.ActiveUsers += 1
cookies = {"AURSID": pm_user.login(Request(), "testPassword")}
with client as request:
@ -893,7 +891,7 @@ def test_pm_addvote(client: TestClient, pm_user: User):
def test_pm_addvote_unauthorized(
client: TestClient, user: User, proposal: Tuple[User, User, TUVoteInfo]
client: TestClient, user: User, proposal: Tuple[User, User, VoteInfo]
):
cookies = {"AURSID": user.login(Request(), "testPassword")}
with client as request:
@ -931,7 +929,7 @@ def test_pm_addvote_post(client: TestClient, pm_user: User, user: User):
response = request.post("/addvote", data=data)
assert response.status_code == int(HTTPStatus.SEE_OTHER)
voteinfo = db.query(TUVoteInfo, TUVoteInfo.Agenda == "Blah").first()
voteinfo = db.query(VoteInfo, VoteInfo.Agenda == "Blah").first()
assert voteinfo is not None
@ -947,7 +945,7 @@ def test_pm_addvote_post_cant_duplicate_username(
response = request.post("/addvote", data=data)
assert response.status_code == int(HTTPStatus.SEE_OTHER)
voteinfo = db.query(TUVoteInfo, TUVoteInfo.Agenda == "Blah").first()
voteinfo = db.query(VoteInfo, VoteInfo.Agenda == "Blah").first()
assert voteinfo is not None
with client as request:

View file

@ -3,9 +3,9 @@ from sqlalchemy.exc import IntegrityError
from aurweb import db, time
from aurweb.models.account_type import PACKAGE_MAINTAINER_ID
from aurweb.models.tu_vote import TUVote
from aurweb.models.tu_voteinfo import TUVoteInfo
from aurweb.models.user import User
from aurweb.models.vote import Vote
from aurweb.models.voteinfo import VoteInfo
@pytest.fixture(autouse=True)
@ -28,11 +28,11 @@ def user() -> User:
@pytest.fixture
def pm_voteinfo(user: User) -> TUVoteInfo:
def voteinfo(user: User) -> VoteInfo:
ts = time.utcnow()
with db.begin():
pm_voteinfo = db.create(
TUVoteInfo,
voteinfo = db.create(
VoteInfo,
Agenda="Blah blah.",
User=user.Username,
Submitted=ts,
@ -40,24 +40,24 @@ def pm_voteinfo(user: User) -> TUVoteInfo:
Quorum=0.5,
Submitter=user,
)
yield pm_voteinfo
yield voteinfo
def test_pm_vote_creation(user: User, pm_voteinfo: TUVoteInfo):
def test_vote_creation(user: User, voteinfo: VoteInfo):
with db.begin():
pm_vote = db.create(TUVote, User=user, VoteInfo=pm_voteinfo)
vote = db.create(Vote, User=user, VoteInfo=voteinfo)
assert pm_vote.VoteInfo == pm_voteinfo
assert pm_vote.User == user
assert pm_vote in user.tu_votes
assert pm_vote in pm_voteinfo.tu_votes
assert vote.VoteInfo == voteinfo
assert vote.User == user
assert vote in user.votes
assert vote in voteinfo.votes
def test_pm_vote_null_user_raises_exception(pm_voteinfo: TUVoteInfo):
def test_vote_null_user_raises_exception(voteinfo: VoteInfo):
with pytest.raises(IntegrityError):
TUVote(VoteInfo=pm_voteinfo)
Vote(VoteInfo=voteinfo)
def test_pm_vote_null_voteinfo_raises_exception(user: User):
def test_vote_null_voteinfo_raises_exception(user: User):
with pytest.raises(IntegrityError):
TUVote(User=user)
Vote(User=user)

View file

@ -4,8 +4,8 @@ from sqlalchemy.exc import IntegrityError
from aurweb import db, time
from aurweb.db import create, rollback
from aurweb.models.account_type import PACKAGE_MAINTAINER_ID
from aurweb.models.tu_voteinfo import TUVoteInfo
from aurweb.models.user import User
from aurweb.models.voteinfo import VoteInfo
@pytest.fixture(autouse=True)
@ -27,11 +27,11 @@ def user() -> User:
yield user
def test_pm_voteinfo_creation(user: User):
def test_voteinfo_creation(user: User):
ts = time.utcnow()
with db.begin():
pm_voteinfo = create(
TUVoteInfo,
voteinfo = create(
VoteInfo,
Agenda="Blah blah.",
User=user.Username,
Submitted=ts,
@ -39,26 +39,26 @@ def test_pm_voteinfo_creation(user: User):
Quorum=0.5,
Submitter=user,
)
assert bool(pm_voteinfo.ID)
assert pm_voteinfo.Agenda == "Blah blah."
assert pm_voteinfo.User == user.Username
assert pm_voteinfo.Submitted == ts
assert pm_voteinfo.End == ts + 5
assert pm_voteinfo.Quorum == 0.5
assert pm_voteinfo.Submitter == user
assert pm_voteinfo.Yes == 0
assert pm_voteinfo.No == 0
assert pm_voteinfo.Abstain == 0
assert pm_voteinfo.ActiveTUs == 0
assert bool(voteinfo.ID)
assert voteinfo.Agenda == "Blah blah."
assert voteinfo.User == user.Username
assert voteinfo.Submitted == ts
assert voteinfo.End == ts + 5
assert voteinfo.Quorum == 0.5
assert voteinfo.Submitter == user
assert voteinfo.Yes == 0
assert voteinfo.No == 0
assert voteinfo.Abstain == 0
assert voteinfo.ActiveUsers == 0
assert pm_voteinfo in user.tu_voteinfo_set
assert voteinfo in user.voteinfo_set
def test_pm_voteinfo_is_running(user: User):
def test_voteinfo_is_running(user: User):
ts = time.utcnow()
with db.begin():
pm_voteinfo = create(
TUVoteInfo,
voteinfo = create(
VoteInfo,
Agenda="Blah blah.",
User=user.Username,
Submitted=ts,
@ -66,18 +66,18 @@ def test_pm_voteinfo_is_running(user: User):
Quorum=0.5,
Submitter=user,
)
assert pm_voteinfo.is_running() is True
assert voteinfo.is_running() is True
with db.begin():
pm_voteinfo.End = ts - 5
assert pm_voteinfo.is_running() is False
voteinfo.End = ts - 5
assert voteinfo.is_running() is False
def test_pm_voteinfo_total_votes(user: User):
def test_voteinfo_total_votes(user: User):
ts = time.utcnow()
with db.begin():
pm_voteinfo = create(
TUVoteInfo,
voteinfo = create(
VoteInfo,
Agenda="Blah blah.",
User=user.Username,
Submitted=ts,
@ -86,19 +86,19 @@ def test_pm_voteinfo_total_votes(user: User):
Submitter=user,
)
pm_voteinfo.Yes = 1
pm_voteinfo.No = 3
pm_voteinfo.Abstain = 5
voteinfo.Yes = 1
voteinfo.No = 3
voteinfo.Abstain = 5
# total_votes() should be the sum of Yes, No and Abstain: 1 + 3 + 5 = 9.
assert pm_voteinfo.total_votes() == 9
assert voteinfo.total_votes() == 9
def test_pm_voteinfo_null_submitter_raises(user: User):
def test_voteinfo_null_submitter_raises(user: User):
with pytest.raises(IntegrityError):
with db.begin():
create(
TUVoteInfo,
VoteInfo,
Agenda="Blah blah.",
User=user.Username,
Submitted=0,
@ -108,11 +108,11 @@ def test_pm_voteinfo_null_submitter_raises(user: User):
rollback()
def test_pm_voteinfo_null_agenda_raises(user: User):
def test_voteinfo_null_agenda_raises(user: User):
with pytest.raises(IntegrityError):
with db.begin():
create(
TUVoteInfo,
VoteInfo,
User=user.Username,
Submitted=0,
End=0,
@ -122,11 +122,11 @@ def test_pm_voteinfo_null_agenda_raises(user: User):
rollback()
def test_pm_voteinfo_null_user_raises(user: User):
def test_voteinfo_null_user_raises(user: User):
with pytest.raises(IntegrityError):
with db.begin():
create(
TUVoteInfo,
VoteInfo,
Agenda="Blah blah.",
Submitted=0,
End=0,
@ -136,11 +136,11 @@ def test_pm_voteinfo_null_user_raises(user: User):
rollback()
def test_pm_voteinfo_null_submitted_raises(user: User):
def test_voteinfo_null_submitted_raises(user: User):
with pytest.raises(IntegrityError):
with db.begin():
create(
TUVoteInfo,
VoteInfo,
Agenda="Blah blah.",
User=user.Username,
End=0,
@ -150,11 +150,11 @@ def test_pm_voteinfo_null_submitted_raises(user: User):
rollback()
def test_pm_voteinfo_null_end_raises(user: User):
def test_voteinfo_null_end_raises(user: User):
with pytest.raises(IntegrityError):
with db.begin():
create(
TUVoteInfo,
VoteInfo,
Agenda="Blah blah.",
User=user.Username,
Submitted=0,
@ -164,10 +164,10 @@ def test_pm_voteinfo_null_end_raises(user: User):
rollback()
def test_pm_voteinfo_null_quorum_default(user: User):
def test_voteinfo_null_quorum_default(user: User):
with db.begin():
vi = create(
TUVoteInfo,
VoteInfo,
Agenda="Blah blah.",
User=user.Username,
Submitted=0,

View file

@ -3,17 +3,17 @@ from typing import Tuple
import pytest
from aurweb import config, db, time
from aurweb.models import TUVote, TUVoteInfo, User
from aurweb.models import User, Vote, VoteInfo
from aurweb.models.account_type import PACKAGE_MAINTAINER_ID
from aurweb.scripts import tuvotereminder as reminder
from aurweb.scripts import votereminder as reminder
from aurweb.testing.email import Email
aur_location = config.get("options", "aur_location")
def create_vote(user: User, voteinfo: TUVoteInfo) -> TUVote:
def create_vote(user: User, voteinfo: VoteInfo) -> Vote:
with db.begin():
vote = db.create(TUVote, User=user, VoteID=voteinfo.ID)
vote = db.create(Vote, User=user, VoteID=voteinfo.ID)
return vote
@ -29,11 +29,11 @@ def create_user(username: str, type_id: int):
return user
def email_pieces(voteinfo: TUVoteInfo) -> Tuple[str, str]:
def email_pieces(voteinfo: VoteInfo) -> Tuple[str, str]:
"""
Return a (subject, content) tuple based on voteinfo.ID
:param voteinfo: TUVoteInfo instance
:param voteinfo: VoteInfo instance
:return: tuple(subject, content)
"""
subject = f"Package Maintainer Vote Reminder: Proposal {voteinfo.ID}"
@ -61,12 +61,12 @@ def user3() -> User:
@pytest.fixture
def voteinfo(user: User) -> TUVoteInfo:
def voteinfo(user: User) -> VoteInfo:
now = time.utcnow()
start = config.getint("tuvotereminder", "range_start")
start = config.getint("votereminder", "range_start")
with db.begin():
voteinfo = db.create(
TUVoteInfo,
VoteInfo,
Agenda="Lorem ipsum.",
User=user.Username,
End=(now + start + 1),
@ -77,7 +77,7 @@ def voteinfo(user: User) -> TUVoteInfo:
yield voteinfo
def test_pm_vote_reminders(user: User, user2: User, user3: User, voteinfo: TUVoteInfo):
def test_vote_reminders(user: User, user2: User, user3: User, voteinfo: VoteInfo):
reminder.main()
assert Email.count() == 3
@ -96,8 +96,8 @@ def test_pm_vote_reminders(user: User, user2: User, user3: User, voteinfo: TUVot
assert emails[i].body == content
def test_pm_vote_reminders_only_unvoted(
user: User, user2: User, user3: User, voteinfo: TUVoteInfo
def test_vote_reminders_only_unvoted(
user: User, user2: User, user3: User, voteinfo: VoteInfo
):
# Vote with user2 and user3; leaving only user to be notified.
create_vote(user2, voteinfo)