A small helpdesk system: an office Pixel running a patched GrapheneOS Dialer answers technician calls, records both call legs as separate channels, and a Ruby backend transcribes them through Whisper and files an AI summary against the caller. Squashed to a single commit for sharing. No credentials are included; secrets live outside the repo in /etc/helpdesk/env on the server or a gitignored .claude/env.local locally. See .claude/env.local.example for the shape. Start at README.md, then docs/architecture.md.
60 lines
2.8 KiB
Java
60 lines
2.8 KiB
Java
package com.android.dialer.helpdesk.util;
|
|
|
|
import java.io.BufferedReader;
|
|
import java.io.InputStreamReader;
|
|
import java.util.Arrays;
|
|
|
|
/**
|
|
* Standalone off-device test for {@link BusinessHours}. Two modes:
|
|
* - default: assertion suite (boundaries + known holidays).
|
|
* - "xcheck": read {@code yyyy-MM-ddTHH:mm} lines from stdin, print "open"/"closed" — the harness
|
|
* diffs this against the real backend Helpdesk::BusinessHours over a full-year sweep.
|
|
*/
|
|
public class BusinessHoursTest {
|
|
static int pass = 0, fail = 0;
|
|
static void t(boolean got, boolean want, String d) {
|
|
if (got == want) { pass++; System.out.println(" ok " + d); }
|
|
else { fail++; System.out.println(" FAIL " + d + " (got: " + got + ")"); }
|
|
}
|
|
|
|
/** Parse yyyy-MM-ddTHH:mm into {year, month, day, hour}. */
|
|
static int[] parse(String s) {
|
|
int y = Integer.parseInt(s.substring(0, 4));
|
|
int mo = Integer.parseInt(s.substring(5, 7));
|
|
int d = Integer.parseInt(s.substring(8, 10));
|
|
int h = Integer.parseInt(s.substring(11, 13));
|
|
return new int[] {y, mo, d, h};
|
|
}
|
|
static boolean open(String s) { int[] p = parse(s); return BusinessHours.isOpen(p[0], p[1], p[2], p[3]); }
|
|
|
|
public static void main(String[] args) throws Exception {
|
|
if (args.length > 0 && args[0].equals("xcheck")) {
|
|
BufferedReader r = new BufferedReader(new InputStreamReader(System.in));
|
|
String line;
|
|
while ((line = r.readLine()) != null) {
|
|
if (line.isEmpty()) continue;
|
|
System.out.println(open(line) ? "open" : "closed");
|
|
}
|
|
return;
|
|
}
|
|
// 2026-07-08 is a Wednesday (normal working day)
|
|
t(open("2026-07-08T10:00"), true, "Wed 10:00 open");
|
|
t(open("2026-07-08T07:59"), false, "07:59 closed (before open)");
|
|
t(open("2026-07-08T08:00"), true, "08:00 open (inclusive)");
|
|
t(open("2026-07-08T15:59"), true, "15:59 open");
|
|
t(open("2026-07-08T16:00"), false, "16:00 closed (exclusive)");
|
|
t(open("2026-07-11T10:00"), false, "Saturday closed");
|
|
t(open("2026-07-12T10:00"), false, "Sunday closed");
|
|
t(open("2026-07-06T10:00"), false, "Jul 6 (Jan Hus) holiday closed");
|
|
t(open("2026-01-01T10:00"), false, "New Year holiday closed");
|
|
t(open("2026-12-25T10:00"), false, "Christmas holiday closed");
|
|
// Easter 2026 = Apr 5 -> Good Friday Apr 3, Easter Monday Apr 6
|
|
t(Arrays.equals(BusinessHours.easter(2026), new int[] {4, 5}), true, "Easter 2026 = Apr 5");
|
|
t(open("2026-04-03T10:00"), false, "Good Friday closed");
|
|
t(open("2026-04-06T10:00"), false, "Easter Monday closed");
|
|
// boundary: Easter early enough that Good Friday is in March (2027 Easter = Mar 28 -> GF Mar 26)
|
|
t(Arrays.equals(BusinessHours.easter(2027), new int[] {3, 28}), true, "Easter 2027 = Mar 28 (month rollover check)");
|
|
System.out.println("\n" + pass + " passed, " + fail + " failed");
|
|
System.exit(fail == 0 ? 0 : 1);
|
|
}
|
|
}
|