52 lines
3.3 KiB
Python
52 lines
3.3 KiB
Python
"""Exercise production admin TTS dispatch; native transport/rendering are separate."""
|
|
import re
|
|
from policy_harness import ROOT, body, run
|
|
p = ROOT / 'addons/core/Scripts/Game/ERR/00_Core/ERR_SpeechMenu.c'
|
|
src = p.read_text()
|
|
layout = (ROOT / 'addons/core/UI/layouts/ERR/AdminMenu.layout').read_text()
|
|
menu = ROOT / 'addons/core/Scripts/Game/ERR/00_Core/ERR_AdminMenuPages.c'
|
|
for name in ('OpenTTS', 'TTSPage', 'TTSEndpoint', 'TTSToken', 'TTSTest', 'TTSDisable', 'TTSPasteEndpoint', 'TTSPasteToken', 'TTSStatus', 'TTSTokenStatus', 'TTSSelectionState', 'RecordingsOn', 'RecordingsOff', 'RecordingsLabel'):
|
|
assert f'Name "{name}"' in layout, name
|
|
assert '"TTSPage"' in body(menu, 'static array<string> Pages(')
|
|
assert '"OpenTTS"' in body(menu, 'static array<string> Navigation(')
|
|
assert 'SetObfuscationChar("*")' in src
|
|
assert 'ToLower' not in src
|
|
assert 'RplRcver.Server' in src and 'RplRcver.Owner' in src
|
|
assert 'm_ERRChatClient.Accept(token)' in body(p, 'protected void ERR_AdminSpeechResponse(')
|
|
assert 'ERR_ServerSession(token)' in body(p, 'protected void ERR_AdminSpeechRequest(')
|
|
assert 'token.SetValue("")' in body(p, 'protected void OnSpeechButton(')
|
|
for method in ('void SpeechReply(', 'void SpeechPreview('):
|
|
assert 'if (!Authorize()) return;' in body(p, method)
|
|
speech = body(p, 'void Speech(').replace('GetGame().GetWorld().GetWorldTime()', 'clockNow')
|
|
speech = speech.replace('ERR_SpeechService service = m_Mode.ERR_Speech();', 'ERR_SpeechService* service = serviceValue;').replace('service.', 'service->')
|
|
run(r'''
|
|
#include <cassert>
|
|
#include <string>
|
|
struct string:std::string {using std::string::string;int Length(){return size();}};
|
|
float clockNow=1000;
|
|
struct ERR_SpeechService {int tests=0,disables=0,recordingChanges=0;bool recordings=true;string endpoint,secret;
|
|
void TestAndEnable(void*,string e,string s){tests++;endpoint=e;secret=s;}
|
|
void Disable(void*){disables++;}
|
|
void SetRecordings(void*,bool value){recordingChanges++;recordings=value;}
|
|
};
|
|
struct Session {bool authorized=true;int replies=0;float m_LastRequest=0;ERR_SpeechService* serviceValue;
|
|
bool Authorize(){return authorized;}void SpeechReply(string){replies++;}
|
|
''' + speech + r'''
|
|
};
|
|
int main(){
|
|
ERR_SpeechService service;Session session;session.serviceValue=&service;
|
|
session.authorized=false;session.Speech(0,"https://host/","MixedCaseTOKEN");assert(!service.tests);
|
|
session.authorized=true;session.Speech(0,"https://host/",string(257,'x'));assert(!service.tests);
|
|
session.Speech(0,string(513,'x'),"token");assert(!service.tests);
|
|
session.Speech(0,"https://host/","MixedCaseTOKEN");assert(service.tests==1&&service.secret=="MixedCaseTOKEN");
|
|
session.Speech(1,"","");assert(!service.disables);
|
|
clockNow+=250;session.Speech(1,"","");assert(service.disables==1);
|
|
clockNow+=250;session.Speech(8,"","");assert(service.tests==1&&service.disables==1);
|
|
clockNow+=250;session.authorized=false;session.Speech(3,"","");assert(service.recordings&&!service.recordingChanges);
|
|
session.authorized=true;session.Speech(3,"","");assert(!service.recordings&&service.recordingChanges==1);
|
|
clockNow+=250;session.Speech(2,"","");assert(service.recordings&&service.recordingChanges==2);
|
|
clockNow+=250;session.serviceValue=nullptr;session.Speech(0,"","");assert(session.replies==1);
|
|
}
|
|
''')
|
|
print('PASS: TTS admin authorization, limits, case preservation and menu control contract')
|