Merge pull request 'tests-menu-traversal' (#16) from tests-menu-traversal into master

Reviewed-on: #16
This commit is contained in:
lash 2025-02-13 10:00:42 +01:00
commit 0089d6f125
6 changed files with 316 additions and 19 deletions

View File

@ -1,5 +1,67 @@
{
"groups": [
{
"name": "main_my_vouchers_select_voucher_using_index",
"steps": [
{
"input": "",
"expectedContent": "{balance}\n\n1:Send\n2:My Vouchers\n3:My Account\n4:Help\n9:Quit"
},
{
"input": "2",
"expectedContent": "My vouchers\n1:Select voucher\n2:Voucher details\n0:Back"
},
{
"input": "1",
"expectedContent": "Select number or symbol from your vouchers:\n1SRF\n0:Back\n99:Quit"
},
{
"input": "",
"expectedContent": "Select number or symbol from your vouchers:\n1SRF\n0:Back\n99:Quit"
},
{
"input": "1",
"expectedContent": "Enter PIN to confirm selection:\nSymbol: SRF\nBalance: 2.745987\n0:Back\n9:Quit"
},
{
"input": "1234",
"expectedContent": "Success! SRF is now your active voucher.\n0:Back\n9:Quit"
},
{
"input": "0",
"expectedContent": "{balance}\n\n1:Send\n2:My Vouchers\n3:My Account\n4:Help\n9:Quit"
}
]
},
{
"name": "main_my_vouchers_select_voucher_using_symbol",
"steps": [
{
"input": "",
"expectedContent": "{balance}\n\n1:Send\n2:My Vouchers\n3:My Account\n4:Help\n9:Quit"
},
{
"input": "2",
"expectedContent": "My vouchers\n1:Select voucher\n2:Voucher details\n0:Back"
},
{
"input": "1",
"expectedContent": "Select number or symbol from your vouchers:\n1SRF\n0:Back\n99:Quit"
},
{
"input": "SRF",
"expectedContent": "Enter PIN to confirm selection:\nSymbol: SRF\nBalance: 2.745987\n0:Back\n9:Quit"
},
{
"input": "1234",
"expectedContent": "Success! SRF is now your active voucher.\n0:Back\n9:Quit"
},
{
"input": "0",
"expectedContent": "{balance}\n\n1:Send\n2:My Vouchers\n3:My Account\n4:Help\n9:Quit"
}
]
},
{
"name": "my_account_change_pin",
"steps": [
@ -48,13 +110,17 @@
"input": "3",
"expectedContent": "My Account\n1:Profile\n2:Change language\n3:Check balances\n4:Check statement\n5:PIN options\n6:My Address\n0:Back"
},
{
"input": "",
"expectedContent": "My Account\n1:Profile\n2:Change language\n3:Check balances\n4:Check statement\n5:PIN options\n6:My Address\n0:Back"
},
{
"input": "2",
"expectedContent": "Please enter your PIN:"
},
{
"input": "1235",
"expectedContent": "Incorrect PIN. You have: 2 remaining attempt(s).\n1:Retry\n9:Quit"
"expectedContent": "Incorrect PIN. You have: {attempts} remaining attempt(s).\n1:Retry\n9:Quit"
},
{
"input": "1",
@ -74,6 +140,121 @@
}
]
},
{
"name": "menu_my_account_reset_others_pin_with_unregistered_number",
"steps": [
{
"input": "",
"expectedContent": "{balance}\n\n1:Send\n2:My Vouchers\n3:My Account\n4:Help\n9:Quit"
},
{
"input": "3",
"expectedContent": "My Account\n1:Profile\n2:Change language\n3:Check balances\n4:Check statement\n5:PIN options\n6:My Address\n0:Back"
},
{
"input": "5",
"expectedContent": "PIN Management\n1:Change PIN\n2:Reset other's PIN\n0:Back"
},
{
"input": "2",
"expectedContent": "Enter other's phone number:\n0:Back"
},
{
"input": "0700000001",
"expectedContent": "The number you have entered is either not registered with Sarafu or is invalid.\n1:Retry\n9:Quit"
},
{
"input": "1",
"expectedContent": "Enter other's phone number:\n0:Back"
},
{
"input": "0",
"expectedContent": "PIN Management\n1:Change PIN\n2:Reset other's PIN\n0:Back"
},
{
"input": "0",
"expectedContent": "My Account\n1:Profile\n2:Change language\n3:Check balances\n4:Check statement\n5:PIN options\n6:My Address\n0:Back"
},
{
"input": "0",
"expectedContent": "{balance}\n\n1:Send\n2:My Vouchers\n3:My Account\n4:Help\n9:Quit"
}
]
},
{
"name": "menu_my_account_reset_others_pin_with_registered_number",
"steps": [
{
"input": "",
"expectedContent": "{balance}\n\n1:Send\n2:My Vouchers\n3:My Account\n4:Help\n9:Quit"
},
{
"input": "3",
"expectedContent": "My Account\n1:Profile\n2:Change language\n3:Check balances\n4:Check statement\n5:PIN options\n6:My Address\n0:Back"
},
{
"input": "5",
"expectedContent": "PIN Management\n1:Change PIN\n2:Reset other's PIN\n0:Back"
},
{
"input": "2",
"expectedContent": "Enter other's phone number:\n0:Back"
},
{
"input": "0700000000",
"expectedContent": "Please enter new PIN for: {secondary_session_id}\n0:Back"
},
{
"input": "11111",
"expectedContent": "The PIN you have entered is invalid.Please try a 4 digit number instead.\n1:Retry\n9:Quit"
},
{
"input": "1",
"expectedContent": "Please enter new PIN for: {secondary_session_id}\n0:Back"
},
{
"input": "1111",
"expectedContent": "Please confirm new PIN for: {secondary_session_id}\n0:Back"
},
{
"input": "1111",
"expectedContent": "Please enter your PIN:"
},
{
"input": "1234",
"expectedContent": "PIN reset request for {secondary_session_id} was successful\n0:Back\n9:Quit"
},
{
"input": "0",
"expectedContent": "{balance}\n\n1:Send\n2:My Vouchers\n3:My Account\n4:Help\n9:Quit"
}
]
},
{
"name": "menu_my_account_reset_others_pin_with_no_privileges",
"steps": [
{
"input": "",
"expectedContent": "{balance}\n\n1:Send\n2:My Vouchers\n3:My Account\n4:Help\n9:Quit"
},
{
"input": "3",
"expectedContent": "My Account\n1:Profile\n2:Change language\n3:Check balances\n4:Check statement\n5:PIN options\n6:My Address\n0:Back"
},
{
"input": "5",
"expectedContent": "PIN Management\n1:Change PIN\n2:Reset other's PIN\n0:Back"
},
{
"input": "2",
"expectedContent": "You do not have privileges to perform this action\n\n9:Quit\n0:Back"
},
{
"input": "0",
"expectedContent": "{balance}\n\n1:Send\n2:My Vouchers\n3:My Account\n4:Help\n9:Quit"
}
]
},
{
"name": "menu_my_account_check_my_balance",
"steps": [
@ -95,7 +276,7 @@
},
{
"input": "1235",
"expectedContent": "Incorrect PIN. You have: 2 remaining attempt(s).\n1:Retry\n9:Quit"
"expectedContent": "Incorrect PIN. You have: {attempts} remaining attempt(s).\n1:Retry\n9:Quit"
},
{
"input": "1",
@ -140,7 +321,7 @@
},
{
"input": "1235",
"expectedContent": "Incorrect PIN. You have: 2 remaining attempt(s).\n1:Retry\n9:Quit"
"expectedContent": "Incorrect PIN. You have: {attempts} remaining attempt(s).\n1:Retry\n9:Quit"
},
{
"input": "1",
@ -277,6 +458,10 @@
"input": "3",
"expectedContent": "Select gender: \n1:Male\n2:Female\n3:Unspecified\n0:Back"
},
{
"input": "",
"expectedContent": "Select gender: \n1:Male\n2:Female\n3:Unspecified\n0:Back"
},
{
"input": "1",
"expectedContent": "Please enter your PIN:"
@ -438,6 +623,47 @@
"expectedContent": "{balance}\n\n1:Send\n2:My Vouchers\n3:My Account\n4:Help\n9:Quit"
}
]
},
{
"name": "menu_block_account_via_view_profile",
"steps": [
{
"input": "",
"expectedContent": "{balance}\n\n1:Send\n2:My Vouchers\n3:My Account\n4:Help\n9:Quit"
},
{
"input": "3",
"expectedContent": "My Account\n1:Profile\n2:Change language\n3:Check balances\n4:Check statement\n5:PIN options\n6:My Address\n0:Back"
},
{
"input": "1",
"expectedContent": "My profile\n1:Edit name\n2:Edit family name\n3:Edit gender\n4:Edit year of birth\n5:Edit location\n6:Edit offerings\n7:View profile\n0:Back"
},
{
"input": "7",
"expectedContent": "Please enter your PIN:"
},
{
"input": "1254",
"expectedContent": "Incorrect PIN. You have: {attempts} remaining attempt(s).\n1:Retry\n9:Quit"
},
{
"input": "1",
"expectedContent": "Please enter your PIN:"
},
{
"input": "1254",
"expectedContent": "Incorrect PIN. You have: {attempts} remaining attempt(s).\n1:Retry\n9:Quit"
},
{
"input": "1",
"expectedContent": "Please enter your PIN:"
},
{
"input": "1254",
"expectedContent": "Your account has been locked. For help on how to unblock your account, contact support at: 0757628885"
}
]
}
]
}

View File

@ -21,6 +21,7 @@ var (
sessionID string
src = rand.NewSource(42)
g = rand.New(src)
secondarySessionId = "0700000000"
)
var groupTestFile = flag.String("test-file", "group_test.json", "The test file to use for running the group tests")
@ -67,6 +68,16 @@ func extractMaxAmount(response []byte) string {
return ""
}
func extractRemainingAttempts(response []byte) string {
// Regex to match "You have: <number> remaining attempt(s)"
re := regexp.MustCompile(`(?m)You have:\s+(\d+)\s+remaining attempt\(s\)`)
match := re.FindSubmatch(response)
if match != nil {
return string(match[1]) // "<number>" of remaining attempts
}
return ""
}
// Extracts the send amount value from the engine response.
func extractSendAmount(response []byte) string {
// Regex to match the pattern "will receive X.XX SYM from"
@ -87,7 +98,43 @@ func TestMain(m *testing.M) {
}
func TestAccountCreationSuccessful(t *testing.T) {
en, fn, eventChannel := testutil.TestEngine(sessionID)
en, fn, eventChannel, _, _ := testutil.TestEngine(sessionID)
defer fn()
ctx := context.Background()
sessions := testData
for _, session := range sessions {
groups := driver.FilterGroupsByName(session.Groups, "account_creation_successful")
for _, group := range groups {
for i, step := range group.Steps {
logg.TraceCtxf(ctx, "executing step", "i", i, "step", step)
cont, err := en.Exec(ctx, []byte(step.Input))
if err != nil {
t.Fatalf("Test case '%s' failed at input '%s': %v", group.Name, step.Input, err)
}
if !cont {
break
}
w := bytes.NewBuffer(nil)
_, err = en.Flush(ctx, w)
if err != nil {
t.Fatalf("Test case '%s' failed during Flush: %v", group.Name, err)
}
b := w.Bytes()
match, err := step.MatchesExpectedContent(b)
if err != nil {
t.Fatalf("Error compiling regex for step '%s': %v", step.Input, err)
}
if !match {
t.Fatalf("expected:\n\t%s\ngot:\n\t%s\n", step.ExpectedContent, b)
}
}
}
}
<-eventChannel
}
func TestSecondaryAccount(t *testing.T) {
en, fn, eventChannel, _, _ := testutil.TestEngine(secondarySessionId)
defer fn()
ctx := context.Background()
sessions := testData
@ -130,7 +177,7 @@ func TestAccountRegistrationRejectTerms(t *testing.T) {
t.Fail()
}
edgeCaseSessionID := v.String()
en, fn, _ := testutil.TestEngine(edgeCaseSessionID)
en, fn, _, _, _ := testutil.TestEngine(edgeCaseSessionID)
defer fn()
ctx := context.Background()
sessions := testData
@ -166,7 +213,7 @@ func TestAccountRegistrationRejectTerms(t *testing.T) {
}
func TestMainMenuHelp(t *testing.T) {
en, fn, _ := testutil.TestEngine(sessionID)
en, fn, _, _, _ := testutil.TestEngine(sessionID)
defer fn()
ctx := context.Background()
sessions := testData
@ -208,7 +255,7 @@ func TestMainMenuHelp(t *testing.T) {
}
func TestMainMenuQuit(t *testing.T) {
en, fn, _ := testutil.TestEngine(sessionID)
en, fn, _, _, _ := testutil.TestEngine(sessionID)
defer fn()
ctx := context.Background()
sessions := testData
@ -249,7 +296,7 @@ func TestMainMenuQuit(t *testing.T) {
}
func TestMyAccount_MyAddress(t *testing.T) {
en, fn, _ := testutil.TestEngine(sessionID)
en, fn, _, _, _ := testutil.TestEngine(sessionID)
defer fn()
ctx := context.Background()
sessions := testData
@ -293,7 +340,7 @@ func TestMyAccount_MyAddress(t *testing.T) {
}
func TestMainMenuSend(t *testing.T) {
en, fn, _ := testutil.TestEngine(sessionID)
en, fn, _, _, _ := testutil.TestEngine(sessionID)
defer fn()
ctx := context.Background()
sessions := testData
@ -344,9 +391,12 @@ func TestGroups(t *testing.T) {
if err != nil {
log.Fatalf("Failed to load test groups: %v", err)
}
en, fn, _ := testutil.TestEngine(sessionID)
en, fn, _, pe, flagParser := testutil.TestEngine(sessionID)
defer fn()
ctx := context.Background()
flag_admin_privilege, _ := flagParser.GetFlag("flag_admin_privilege")
// Create test cases from loaded groups
tests := driver.CreateTestCases(groups)
for _, tt := range tests {
@ -365,9 +415,21 @@ func TestGroups(t *testing.T) {
}
b := w.Bytes()
balance := extractBalance(b)
attempts := extractRemainingAttempts(b)
st := pe.GetState()
if st != nil {
st.SetFlag(flag_admin_privilege)
if tt.Name == "menu_my_account_reset_others_pin_with_no_privileges" {
st.ResetFlag(flag_admin_privilege)
}
}
expectedContent := []byte(tt.ExpectedContent)
expectedContent = bytes.Replace(expectedContent, []byte("{balance}"), []byte(balance), -1)
expectedContent = bytes.Replace(expectedContent, []byte("{attempts}"), []byte(attempts), -1)
expectedContent = bytes.Replace(expectedContent, []byte("{secondary_session_id}"), []byte(secondarySessionId), -1)
tt.ExpectedContent = string(expectedContent)

View File

@ -7,3 +7,4 @@ MOUT quit 9
HALT
INCMP _ 1
INCMP quit 9
INCMP . *

View File

@ -9,7 +9,9 @@ import (
"path/filepath"
"time"
"git.defalsify.org/vise.git/asm"
"git.defalsify.org/vise.git/engine"
"git.defalsify.org/vise.git/persist"
"git.defalsify.org/vise.git/resource"
"git.grassecon.net/grassrootseconomics/sarafu-api/remote"
httpremote "git.grassecon.net/grassrootseconomics/sarafu-api/remote/http"
@ -60,7 +62,7 @@ func CleanDatabase() {
}
}
func TestEngine(sessionId string) (engine.Engine, func(), chan bool) {
func TestEngine(sessionId string) (engine.Engine, func(), chan bool, *persist.Persister, *asm.FlagParser) {
config.LoadConfig()
err := config.Apply(override)
if err != nil {
@ -75,6 +77,12 @@ func TestEngine(sessionId string) (engine.Engine, func(), chan bool) {
logg.InfoCtxf(ctx, "loaded engine setup", "conns", conns)
pfp := path.Join(scriptDir, "pp.csv")
parser := asm.NewFlagParser()
_, err = parser.Load(pfp)
if err != nil {
os.Exit(1)
}
var eventChannel = make(chan bool)
cfg := engine.Config{
@ -157,5 +165,5 @@ func TestEngine(sessionId string) (engine.Engine, func(), chan bool) {
}
logg.Infof("testengine storage closed")
}
return en, cleanFn, eventChannel
return en, cleanFn, eventChannel, pe, parser
}

View File

@ -5,7 +5,7 @@ import (
)
func TestCreateEngine(t *testing.T) {
o, clean, eventC := TestEngine("foo")
o, clean, eventC, _, _ := TestEngine("foo")
defer clean()
defer func() {
<-eventC