Skip to content

Commit

Permalink
Add a cli to count the number of active projects
Browse files Browse the repository at this point in the history
  • Loading branch information
jjspill1 authored and almet committed Dec 20, 2024
1 parent 0b09476 commit fcd09e5
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 5 deletions.
27 changes: 27 additions & 0 deletions ihatemoney/manage.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import os
import random
import sys
import datetime

import click
from flask.cli import FlaskGroup
Expand Down Expand Up @@ -93,5 +94,31 @@ def delete_project(project_name):
db.session.commit()


@cli.command()
@click.argument("print_emails", default=False)
@click.argument("bills", default=0) # default values will get total projects
@click.argument("days", default=73000) # approximately 200 years
def get_project_count(print_emails, bills, days):
"""Count projets with at least x bills and at less than x days old"""
projects = [
pr
for pr in Project.query.all()
if pr.get_bills().count() > bills
and pr.get_bills()[0].date
> datetime.date.today() - datetime.timedelta(days=days)
]
click.secho("Number of projects: " + str(len(projects)))

if print_emails:
emails = set([pr.contact_email for pr in projects])
emails_str = ", ".join(emails)
if len(emails) > 1:
click.secho("Contact emails: " + emails_str)
elif len(emails) == 1:
click.secho("Contact email: " + emails_str)
else:
click.secho("No contact emails found")


if __name__ == "__main__":
cli()
71 changes: 66 additions & 5 deletions ihatemoney/tests/main_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,17 @@
import socket
from unittest.mock import MagicMock, patch

import pytest
from sqlalchemy import orm
from werkzeug.security import check_password_hash

from ihatemoney import models
from ihatemoney.currency_convertor import CurrencyConverter
from ihatemoney.manage import delete_project, generate_config, password_hash
from ihatemoney.manage import (
delete_project,
generate_config,
get_project_count,
password_hash,
)
from ihatemoney.run import load_configuration
from ihatemoney.tests.common.ihatemoney_testcase import BaseTestCase, IhatemoneyTestCase

Expand Down Expand Up @@ -229,6 +233,65 @@ def test_bill_pay_each(self):
pay_each_expected = 10 / 3
assert bill.pay_each() == pay_each_expected

def test_demo_project_count(self):
"""Test command the get-project-count"""
self.post_project("raclette")

# add members
self.client.post("/raclette/members/add", data={"name": "zorglub", "weight": 2})
self.client.post("/raclette/members/add", data={"name": "fred"})
self.client.post("/raclette/members/add", data={"name": "tata"})
self.client.post("/raclette/members/add", data={"name": "pépé"})

# create bills
self.client.post(
"/raclette/add",
data={
"date": "2011-08-10",
"what": "fromage à raclette",
"payer": 1,
"payed_for": [1, 2, 3],
"amount": "10.0",
},
)

self.client.post(
"/raclette/add",
data={
"date": "2011-08-10",
"what": "red wine",
"payer": 2,
"payed_for": [1],
"amount": "20",
},
)

assert self.get_project("raclette").has_bills()

# Now check the different parameters
runner = self.app.test_cli_runner()
result0 = runner.invoke(get_project_count)
assert result0.output.strip() == "Number of projects: 1"

# With more than 1 bill, without printing emails
result1 = runner.invoke(get_project_count, "False 1")
assert result1.output.strip() == "Number of projects: 1"

# With more than 2 bill, without printing emails
result2 = runner.invoke(get_project_count, "False 2")
assert result2.output.strip() == "Number of projects: 0"

# With more than 0 days old
result3 = runner.invoke(get_project_count, "False 0 0")
assert result3.output.strip() == "Number of projects: 0"

result4 = runner.invoke(get_project_count, "False 0 20000")
assert result4.output.strip() == "Number of projects: 1"

# Print emails
result5 = runner.invoke(get_project_count, "True")
assert "[email protected]" in result5.output


class TestEmailFailure(IhatemoneyTestCase):
def test_creation_email_failure_smtp(self):
Expand Down Expand Up @@ -401,9 +464,7 @@ def test_exchange_currency(self):

def test_failing_remote(self):
rates = {}
with patch("requests.Response.json", new=lambda _: {}), pytest.warns(
UserWarning
):
with patch("requests.Response.json", new=lambda _: {}):
# we need a non-patched converter, but it seems that MagickMock
# is mocking EVERY instance of the class method. Too bad.
rates = CurrencyConverter.get_rates(self.converter)
Expand Down

0 comments on commit fcd09e5

Please sign in to comment.