Parental controls: approvals lift bedtime, bedtime follows the child's clock, urgent push + banner + reminders for requests, reward cap raised to 60
build-container / build (push) Successful in 4m3s
build-container / build (push) Successful in 4m3s
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
d0e4e82e0a
commit
0a33119807
11 files changed
+59
-19
No files matched your search
@@ -15,6 +15,8 @@ assert.equal(kid.lockedFor(users.get(sam.id), '/api/kid/status'), null, 'except
|
||||
assert.throws(() => kid.give(pat.id, 15), /not a child/); st = kid.give(sam.id, 20); assert.equal(st.locked, null, 'more time unlocks it'); assert.equal(st.limit, 35);
|
||||
// bedtime
|
||||
users.update(sam.id, { kid: { on: true, limitMin: 0, bedtime: { on: true, from: '00:00', to: '23:59' } } }); assert.equal(kid.status(users.get(sam.id)).locked, 'bedtime'); users.update(sam.id, { kid: { on: true, limitMin: 0, bedtime: { on: false } } }); assert.equal(kid.status(users.get(sam.id)).locked, null, 'no limit, no bedtime: never locked'); assert.equal(kid.status(users.get(sam.id)).left, null);
|
||||
// a yes at bedtime opens the app for the minutes given, then it locks again (and the lift survives a change of day)
|
||||
users.update(sam.id, { kid: { on: true, limitMin: 0, bedtime: { on: true, from: '00:00', to: '23:59' } } }); st = kid.give(sam.id, 15, true); assert.equal(st.locked, null, 'a yes at bedtime lets them in'); t += 14 * 60e3; assert.equal(kid.status(users.get(sam.id)).locked, null, 'still open inside the 15 minutes'); t += 2 * 60e3; assert.equal(kid.status(users.get(sam.id)).locked, 'bedtime', 'locked again afterwards'); assert.equal(kid.give(sam.id, 15).locked, 'bedtime', 'extra minutes alone do not lift bedtime (only a parent\'s yes does)');
|
||||
Date.now = real;
|
||||
// over HTTP: who may do what, and asking a parent
|
||||
const hub = http.createServer((req, res) => { const who = { sam, ann, pat }[req.headers['x-user'] || 'sam']; users.runAs(users.get(who.id), () => kid.handle(req, res, users.get(who.id), { askParents: chat.askParents })); }).listen(0, async () => {
|
||||
@@ -23,8 +25,7 @@ const hub = http.createServer((req, res) => { const who = { sam, ann, pat }[req.
|
||||
assert.equal((await j(await call('/status'))).on, true); assert.equal((await post('/ping', {})).status, 200); assert.equal((await post('/extra', { user: sam.id, minutes: 10 }, 'sam')).status, 403, 'a child cannot give themselves time'); assert.equal((await post('/extra', { user: sam.id, minutes: 10 }, 'ann')).status, 200);
|
||||
assert.equal((await call('/usage?user=' + sam.id, {}, 'sam')).status, 403); assert.equal((await j(await call('/usage?user=' + sam.id, {}, 'ann'))).on, true);
|
||||
assert.equal((await post('/ask', { text: 'More time please?' }, 'pat')).status, 400, 'only child accounts ask'); const r = await j(await post('/ask', { text: 'Can I have 15 more minutes? I am nearly done.' })); assert.equal(r.told, 1, 'the one admin is told');
|
||||
const dm = 'd:' + [sam.id, ann.id].sort().join(':'); const conv = await asAdmin(users.get(ann.id), async () => { const out = {}; await chat.handle({ url: '/api/chat/conv/' + encodeURIComponent(dm), method: 'GET', headers: {} }, { writeHead() {}, end(b) { out.j = JSON.parse(b); }, headersSent: false }); return out.j; });
|
||||
assert.equal(conv.msgs[0].text, 'Can I have 15 more minutes? I am nearly done.'); assert.equal(conv.msgs[0].name, 'Sam', 'it arrives as a chat message from the child');
|
||||
const open = JSON.parse(fs.readFileSync(path.join(process.env.DATA_DIR, 'kid-requests.json'), 'utf8')).filter(q => q.time && q.status === 'open'); assert.equal(open.length, 1, 'the ask is one open request for the parents (and one urgent notification, not a chat message too)'); assert.equal(open[0].text, 'Can I have 15 more minutes? I am nearly done.');
|
||||
console.log('kidlimits ok');
|
||||
} catch (e) { console.error(e); process.exitCode = 1; }
|
||||
hub.close(); setTimeout(() => process.exit(process.exitCode || 0), 50);
|
||||
|
||||
Reference in new issue
Block a user