summaryrefslogtreecommitdiff
path: root/jimbrella
diff options
context:
space:
mode:
authorFrederick Yin <fkfd@fkfd.me>2021-10-22 22:06:45 +0800
committerFrederick Yin <fkfd@fkfd.me>2021-10-22 22:10:13 +0800
commit3044005c2e45b6b5513b45a7e229ccdad3d8068c (patch)
tree3811a132e0c6a15de5bb415f07366e48e335725c /jimbrella
parent3b16f04f4f3c6085ffef2ac058fca0a17fcb49ca (diff)
Tests: jForm mock data generator and routine tests
Diffstat (limited to 'jimbrella')
-rw-r--r--jimbrella/test/__init__.py0
-rw-r--r--jimbrella/test/jform_data.py116
-rw-r--r--jimbrella/test/test_routine.py58
3 files changed, 174 insertions, 0 deletions
diff --git a/jimbrella/test/__init__.py b/jimbrella/test/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/jimbrella/test/__init__.py
diff --git a/jimbrella/test/jform_data.py b/jimbrella/test/jform_data.py
new file mode 100644
index 0000000..358da8a
--- /dev/null
+++ b/jimbrella/test/jform_data.py
@@ -0,0 +1,116 @@
+import json
+from datetime import datetime, timedelta
+from ..database import Database
+from ..config import *
+
+TENANT_NAMES = ["Alice", "Bob", "Carol", "Dave", "Eve", "Frank"]
+TENANT_IDS = ["01", "02", "03", "04", "05", "06"]
+TENANT_PHONES = ["0001", "0002", "0003", "0004", "0005", "0006"]
+TENANTS = [
+ (TENANT_NAMES[i], TENANT_IDS[i], TENANT_PHONES[i]) for i in range(len(TENANT_NAMES))
+]
+ALICE, BOB, CAROL, DAVE, EVE, FRANK = tuple(TENANTS)
+
+
+def mock_answer_sheet(
+ tenant_name: str,
+ tenant_id: str,
+ tenant_phone: str,
+ key_no: int,
+ sheet_id: int,
+ time: datetime,
+) -> dict:
+ return {
+ "answers": [
+ {"answer": tenant_name, "question": {"id": 9957460, "title": "1. 姓名Name"}},
+ {
+ "answer": tenant_id,
+ "question": {"id": 9957461, "title": "2. 学工号Student/Faculty number"},
+ },
+ {
+ "answer": tenant_phone,
+ "question": {"id": 9957462, "title": "3. 联系方式Phone"},
+ },
+ {
+ "answer": key_no,
+ "question": {"id": 9957463, "title": "4. 钥匙编号Key's Number"},
+ },
+ ],
+ "id": sheet_id,
+ "ip_address": "127.0.0.1",
+ "status": 0,
+ "submitted_at": time.isoformat(timespec="milliseconds") + "+08:00",
+ "tags": [],
+ "user": {"name": tenant_name, "organization": "密西根学院"},
+ }
+
+
+def mock_jform_data() -> tuple:
+ """Generate mock, serialized jForm data for tests.
+
+ Result should describe this flow (- is borrow, + is return):
+ - Alice borrowed umbrella #1 7 days ago
+ - Bob borrowed umbrella #2 6 days ago
+ + Alice returned umbrella #1 5 days ago
+ - Carol borrowed umbrella #1 1 hour after Alice returned it
+ + Carol returned umbrella #1 4 days ago
+ - Dave borrowed umbrella #3 4 days ago, but would not return it
+ - Eve borrowed umbrella #4 3 days and 1 hour ago
+ - Eve attempted to borrow #4 again, 1 minute later
+ - Frank borrowed umbrella #5 yesterday
+ + Bob (finally) returned umbrella #2 today
+
+ At this stage:
+ - Umbrella #1 and #2 are available
+ - Umbrella #3 is overdue in the hands of Dave
+ - Umbrella #4 is overdue in the hands of Eve
+ - Umbrella #5 is lent to Frank
+
+ Value is returned as:
+ (
+ <jForm API response body for takeaway questionnaire>,
+ <jForm API response body for giveback questionnaire>
+ )
+ """
+ takeaway = {
+ "success": True,
+ "message": "ok",
+ "data": {
+ "rows": [],
+ "total": 0,
+ },
+ "code": 0,
+ }
+ giveback = {
+ "success": True,
+ "message": "ok",
+ "data": {
+ "rows": [],
+ "total": 0,
+ },
+ "code": 0,
+ }
+
+ db = Database(DATABASE_PATH)
+ umbrellas = db.read()
+ key_numbers = [umb["serial"] for umb in umbrellas]
+ now = datetime.now()
+ takeaway_rows = [
+ mock_answer_sheet(*ALICE, 1, 1, now - timedelta(days=7)),
+ mock_answer_sheet(*BOB, 2, 2, now - timedelta(days=6)),
+ mock_answer_sheet(*CAROL, 1, 4, now - timedelta(days=4, hours=23)),
+ mock_answer_sheet(*DAVE, 3, 6, now - timedelta(days=4)),
+ mock_answer_sheet(*EVE, 4, 7, now - timedelta(days=3, hours=1)),
+ mock_answer_sheet(*EVE, 4, 8, now - timedelta(days=3, minutes=59)),
+ mock_answer_sheet(*FRANK, 5, 9, now - timedelta(days=1)),
+ ]
+ giveback_rows = [
+ mock_answer_sheet(*ALICE, 1, 3, now - timedelta(days=5)),
+ mock_answer_sheet(*CAROL, 1, 5, now - timedelta(days=4)),
+ mock_answer_sheet(*BOB, 2, 10, now - timedelta(hours=1)),
+ ]
+ takeaway["data"]["rows"] = takeaway_rows
+ takeaway["data"]["total"] = len(takeaway_rows)
+ giveback["data"]["rows"] = giveback_rows
+ giveback["data"]["total"] = len(giveback_rows)
+ return (json.dumps(takeaway), json.dumps(giveback))
diff --git a/jimbrella/test/test_routine.py b/jimbrella/test/test_routine.py
new file mode 100644
index 0000000..a3a5675
--- /dev/null
+++ b/jimbrella/test/test_routine.py
@@ -0,0 +1,58 @@
+from flask import Flask, Response, request
+from threading import Thread
+import json
+import os
+import shutil
+from .jform_data import mock_jform_data
+from ..routine import sync_database
+from ..database import Database
+from ..jform import JForm
+from ..config import *
+
+"""Spin up a simple Flask app to mimic jForm."""
+jform = Flask(__name__)
+
+takeaway, giveback = mock_jform_data()
+
+EMPTY_RESPONSE = Response(
+ json.dumps(
+ {
+ "success": True,
+ "message": "ok",
+ "data": {
+ "rows": [],
+ "total": 0,
+ },
+ "code": 0,
+ },
+ ),
+ content_type="application/json",
+)
+
+
+@jform.route("/<endpoint>")
+def api(endpoint):
+ params = request.args.get("params")
+ if (
+ params
+ and "current" in json.loads(params)
+ and json.loads(params)["current"] != 1
+ ):
+ return EMPTY_RESPONSE
+ if endpoint == "takeaway":
+ return Response(takeaway, content_type="application/json")
+ elif endpoint == "giveback":
+ return Response(giveback, content_type="application/json")
+
+
+Thread(target=jform.run, kwargs={"port": 5001}).start()
+
+"""Initialize Database and JForm."""
+TEST_DATABASE_PATH = "/tmp/jimbrella.test.db.csv"
+shutil.copyfile(DATABASE_PATH, TEST_DATABASE_PATH)
+db = Database(TEST_DATABASE_PATH)
+takeaway_jform = JForm("takeaway", "http://localhost:5001/takeaway", "/tmp")
+giveback_jform = JForm("giveback", "http://localhost:5001/giveback", "/tmp")
+sync_database(takeaway_jform, giveback_jform, db)
+os.remove(takeaway_jform._bookmark_fp)
+os.remove(giveback_jform._bookmark_fp)