Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Standardize model __repr__ functions #1140

Merged
merged 12 commits into from
Jan 2, 2025
4 changes: 0 additions & 4 deletions OpenOversight/app/main/views.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import os
import re
import sys
from datetime import datetime
Expand Down Expand Up @@ -124,9 +123,6 @@
)


# Ensure the file is read/write by the creator only
SAVED_UMASK = os.umask(0o077)

sitemap_endpoints = []


Expand Down
45 changes: 30 additions & 15 deletions OpenOversight/app/models/database.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ class Department(BaseModel, TrackUpdates):
__table_args__ = (UniqueConstraint("name", "state", name="departments_name_state"),)

def __repr__(self):
return f"<Department ID {self.id}: {self.name} {self.state}>"
return f"<Department ID: {self.id} : {self.name} : {self.state}>"

def to_custom_dict(self):
return {
Expand Down Expand Up @@ -198,7 +198,7 @@ class Job(BaseModel, TrackUpdates):
)

def __repr__(self):
return f"<Job ID {self.id}: {self.job_title}>"
return f"<Job ID: {self.id} : {self.job_title}>"

def __str__(self):
return self.job_title
Expand All @@ -212,6 +212,9 @@ class Note(BaseModel, TrackUpdates):
officer_id = db.Column(db.Integer, db.ForeignKey("officers.id", ondelete="CASCADE"))
officer = db.relationship("Officer", back_populates="notes")

def __repr__(self):
return f"<Note ID: {self.id} : {self.text_contents}>"


class Description(BaseModel, TrackUpdates):
__tablename__ = "descriptions"
Expand All @@ -221,6 +224,9 @@ class Description(BaseModel, TrackUpdates):
text_contents = db.Column(db.Text())
officer_id = db.Column(db.Integer, db.ForeignKey("officers.id", ondelete="CASCADE"))

def __repr__(self):
return f"<Description ID: {self.id} : {self.text_contents}>"


class Officer(BaseModel, TrackUpdates):
__tablename__ = "officers"
Expand Down Expand Up @@ -279,6 +285,14 @@ class Officer(BaseModel, TrackUpdates):
CheckConstraint("gender in ('M', 'F', 'Other')", name="gender_options"),
)

def __repr__(self):
if self.unique_internal_identifier:
return (
f"<Officer ID: {self.id} : {self.full_name()} "
f"({self.unique_internal_identifier})>"
)
return f"<Officer ID: {self.id} : {self.full_name()}>"

def full_name(self):
if self.middle_initial:
middle_initial = (
Expand Down Expand Up @@ -339,14 +353,6 @@ def currently_on_force(self):
return "Yes" if most_recent.resign_date is None else "No"
return "Uncertain"

def __repr__(self):
if self.unique_internal_identifier:
return (
f"<Officer ID {self.id}: {self.full_name()} "
f"({self.unique_internal_identifier})>"
)
return f"<Officer ID {self.id}: {self.full_name()}>"


class Salary(BaseModel, TrackUpdates):
__tablename__ = "salaries"
Expand All @@ -365,7 +371,7 @@ class Salary(BaseModel, TrackUpdates):
is_fiscal_year = db.Column(db.Boolean, index=False, unique=False, nullable=False)

def __repr__(self):
return f"<Salary: ID {self.officer_id} : {self.salary}"
return f"<Salary ID: {self.officer_id} : {self.salary}>"

@property
def total_pay(self) -> float:
Expand Down Expand Up @@ -406,7 +412,7 @@ class Assignment(BaseModel, TrackUpdates):
resign_date = db.Column(db.Date, index=True, unique=False, nullable=True)

def __repr__(self):
return f"<Assignment: ID {self.officer_id} : {self.star_no}>"
return f"<Assignment ID: {self.officer_id} : {self.star_no}>"

@property
def start_date_or_min(self):
Expand All @@ -433,7 +439,7 @@ class Unit(BaseModel, TrackUpdates):
)

def __repr__(self):
return f"Unit: {self.description}"
return f"<Unit ID: {self.id} : {self.description}>"


class Face(BaseModel, TrackUpdates):
Expand Down Expand Up @@ -485,7 +491,7 @@ class Face(BaseModel, TrackUpdates):
__table_args__ = (UniqueConstraint("officer_id", "img_id", name="unique_faces"),)

def __repr__(self):
return f"<Tag ID {self.id}: {self.officer_id} - {self.img_id}>"
return f"<Tag ID: {self.id} : {self.officer_id} : {self.img_id}>"


class Image(BaseModel, TrackUpdates):
Expand All @@ -512,7 +518,7 @@ class Image(BaseModel, TrackUpdates):
)

def __repr__(self):
return f"<Image ID {self.id}: {self.filepath}>"
return f"<Image ID: {self.id} : {self.filepath}>"


incident_links = db.Table(
Expand Down Expand Up @@ -644,6 +650,9 @@ class LicensePlate(BaseModel, TrackUpdates):
def validate_state(self, key, state):
return state_validator(state)

def __repr__(self):
return f"<LicensePlate ID: {self.id} : {self.state} : {self.number}>"


class Link(BaseModel, TrackUpdates):
__tablename__ = "links"
Expand All @@ -660,6 +669,9 @@ class Link(BaseModel, TrackUpdates):
def validate_url(self, key, url):
return url_validator(url)

def __repr__(self):
return f"<Link ID: {self.id} : {self.title}>"


class Incident(BaseModel, TrackUpdates):
__tablename__ = "incidents"
Expand Down Expand Up @@ -704,6 +716,9 @@ class Incident(BaseModel, TrackUpdates):
"Department", backref=db.backref("incidents", cascade_backrefs=False), lazy=True
)

def __repr__(self):
return f"<Incident ID: {self.id} : {self.report_number}>"


class User(UserMixin, BaseModel):
__tablename__ = "users"
Expand Down
4 changes: 0 additions & 4 deletions OpenOversight/app/utils/constants.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
import os


# Cache Key Constants
KEY_DEPT_ALL_ASSIGNMENTS = "all_department_assignments"
KEY_DEPT_ALL_INCIDENTS = "all_department_incidents"
Expand Down Expand Up @@ -44,7 +41,6 @@
ENCODING_UTF_8 = "utf-8"
FILE_TYPE_HTML = "html"
FILE_TYPE_PLAIN = "plain"
SAVED_UMASK = os.umask(0o077) # Ensure the file is read/write by the creator only

# File Name Constants
SERVICE_ACCOUNT_FILE = "service_account_key.json"
Expand Down
53 changes: 43 additions & 10 deletions OpenOversight/tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@
from OpenOversight.app.models.database import (
Assignment,
Department,
Description,
Face,
Image,
Incident,
Job,
LicensePlate,
Link,
Location,
Note,
Officer,
Salary,
Unit,
Expand All @@ -30,7 +32,7 @@ def test_department_repr(mockdata):
department = Department.query.first()
assert (
repr(department)
== f"<Department ID {department.id}: {department.name} {department.state}>"
== f"<Department ID: {department.id} : {department.name} : {department.state}>"
)


Expand Down Expand Up @@ -93,7 +95,7 @@ def test_officer_repr(session):
).first()

assert (
repr(officer_uii) == f"<Officer ID {officer_uii.id}: "
repr(officer_uii) == f"<Officer ID: {officer_uii.id} : "
f"{officer_uii.first_name} {officer_uii.middle_initial}. {officer_uii.last_name} "
f"({officer_uii.unique_internal_identifier})>"
)
Expand All @@ -107,7 +109,7 @@ def test_officer_repr(session):
).first()

assert (
repr(officer_no_uii) == f"<Officer ID {officer_no_uii.id}: "
repr(officer_no_uii) == f"<Officer ID: {officer_no_uii.id} : "
f"{officer_no_uii.first_name} {officer_no_uii.middle_initial}. "
f"{officer_no_uii.last_name} {officer_no_uii.suffix}>"
)
Expand All @@ -118,7 +120,7 @@ def test_officer_repr(session):

assert (
repr(officer_no_mi)
== f"<Officer ID {officer_no_mi.id}: {officer_no_mi.first_name} "
== f"<Officer ID: {officer_no_mi.id} : {officer_no_mi.first_name} "
f"{officer_no_mi.last_name} {officer_no_mi.suffix} "
f"({officer_no_mi.unique_internal_identifier})>"
)
Expand All @@ -137,28 +139,33 @@ def test_assignment_repr(mockdata):
assignment = Assignment.query.first()
assert (
repr(assignment)
== f"<Assignment: ID {assignment.base_officer.id} : {assignment.star_no}>"
== f"<Assignment ID: {assignment.base_officer.id} : {assignment.star_no}>"
)


def test_incident_repr(mockdata):
incident = Incident.query.first()
assert repr(incident) == f"<Incident ID: {incident.id} : {incident.report_number}>"


def test_job_repr(mockdata):
job = Job.query.first()
assert repr(job) == f"<Job ID {job.id}: {job.job_title}>"
assert repr(job) == f"<Job ID: {job.id} : {job.job_title}>"


def test_image_repr(mockdata):
image = Image.query.first()
assert repr(image) == f"<Image ID {image.id}: {image.filepath}>"
assert repr(image) == f"<Image ID: {image.id} : {image.filepath}>"


def test_face_repr(mockdata):
face = Face.query.first()
assert repr(face) == f"<Tag ID {face.id}: {face.officer_id} - {face.img_id}>"
assert repr(face) == f"<Tag ID: {face.id} : {face.officer_id} : {face.img_id}>"


def test_unit_repr(mockdata):
unit = Unit.query.first()
assert repr(unit) == f"Unit: {unit.description}"
assert repr(unit) == f"<Unit ID: {unit.id} : {unit.description}>"


def test_user_repr(mockdata):
Expand All @@ -168,7 +175,33 @@ def test_user_repr(mockdata):

def test_salary_repr(mockdata):
salary = Salary.query.first()
assert repr(salary) == f"<Salary: ID {salary.officer_id} : {salary.salary}"
assert repr(salary) == f"<Salary ID: {salary.officer_id} : {salary.salary}>"


def test_link_repr(mockdata):
link = Link.query.first()
assert repr(link) == f"<Link ID: {link.id} : {link.title}>"


def test_note_repr(mockdata):
note = Note.query.first()
assert repr(note) == f"<Note ID: {note.id} : {note.text_contents}>"


def test_description_repr(mockdata):
description = Description.query.first()
assert (
repr(description)
== f"<Description ID: {description.id} : {description.text_contents}>"
)


def test_license_plate_repr(mockdata):
license_plate = LicensePlate.query.first()
assert (
repr(license_plate)
== f"<LicensePlate ID: {license_plate.id} : {license_plate.state} : {license_plate.number}>"
)


def test_password_not_printed(mockdata):
Expand Down
2 changes: 1 addition & 1 deletion OpenOversight/tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ def test_user_cannot_submit_invalid_file_extension(mockdata):

def test_unit_choices(mockdata):
unit_choices_result = [str(x) for x in unit_choices()]
assert "Unit: Bureau of Organized Crime" in unit_choices_result
assert "<Unit ID: 4 : Bureau of Organized Crime>" in unit_choices_result


@upload_s3_patch
Expand Down
Loading