firmware/testing/test_notes.py
Peter D. Gray 4678fc3b3e
first pass
2024-01-24 09:46:39 -05:00

168 lines
4.6 KiB
Python

# (c) Copyright 2024 by Coinkite Inc. This file is covered by license found in COPYING-CC.
#
# tests for ../shared/notes.py
#
import pytest, time, os, shutil, json, random, pdb
from test_ux import word_menu_entry, enter_complex
from binascii import a2b_hex
from helpers import prandom
from constants import simulator_fixed_tprv
from charcodes import *
from test_bbqr import readback_bbqr, render_bbqr, readback_bbqr_ll
from bbqr import split_qrs
# All tests in this file are exclusively meant for Q
#
@pytest.fixture(autouse=True)
def THIS_FILE_requires_q1(is_q1):
if not is_q1:
raise pytest.skip('Q1 only')
@pytest.fixture
def goto_notes(cap_story, cap_menu, need_keypress, goto_home, pick_menu_item):
# drill to the notes menu
def doit(item=None):
mt = 'Secure Notes & Passwords'
goto_home()
m = cap_menu()
if mt in m:
pick_menu_item(mt)
else:
pick_menu_item('Advanced/Tools')
pick_menu_item(mt)
title, story = cap_story()
if title == 'Secure Notes':
# enable feature
need_keypress('y')
if item:
pick_menu_item(item)
return doit
@pytest.mark.parametrize('n_title', [ 'a', 'aaa', 'b'*32])
@pytest.mark.parametrize('n_body', [ 'short', 'very long '*30])
def test_build_note(n_title, n_body, goto_notes, pick_menu_item, enter_text, cap_menu, cap_story, need_keypress, cap_screen_qr, readback_bbqr, nfc_read_text):
# we don't try to preserve leading/trailing spaces on note bodies
n_body= n_body.strip()
goto_notes('New Note')
# create
enter_text(n_title)
enter_text(n_body, multiline=True)
# view
time.sleep(0.1)
m = cap_menu()
assert m[0] == f'"{n_title}"'
assert m[1] == 'View Note'
assert m[-1] == 'Export'
# test readback
for mi in ['View Note', f'"{n_title}"']:
time.sleep(0.1)
pick_menu_item(mi)
title, story = cap_story()
assert title == n_title
assert story == n_body
need_keypress(KEY_QR)
qr_rb = cap_screen_qr().decode('utf-8')
assert qr_rb == n_body
need_keypress(KEY_CANCEL)
# hidden QR button on menu feature
m = cap_menu()
assert m[1] == 'View Note'
need_keypress(KEY_QR)
qr_rb = cap_screen_qr().decode('utf-8')
assert qr_rb == n_body
need_keypress(KEY_CANCEL)
# hidden NFC button on menu feature
m = cap_menu()
assert m[1] == 'View Note'
need_keypress(KEY_NFC)
nfc_rb = nfc_read_text()
assert nfc_rb == n_body
need_keypress(KEY_CANCEL)
# export
m = cap_menu()
pick_menu_item('Export')
title, story = cap_story()
assert 'Export' in title
assert 'to save note to SD' in story
assert 'to show QR' in story
assert 'WARNING' in story
assert 'will be cleartext' in story
need_keypress(KEY_QR)
file_type, data = readback_bbqr()
assert file_type == 'J'
obj = json.loads(data)
assert obj.keys() == {'coldcard_notes'}
obj = obj['coldcard_notes']
assert len(obj) == 1
obj = obj[0]
assert obj['title'] == n_title
assert obj['misc'] == n_body
# drill back to it
goto_notes()
m = cap_menu()
found = [i for i in m if f': {n_title}' in i]
assert found
pick_menu_item(found[-1])
pick_menu_item('Delete')
title, story = cap_story()
assert 'SURE' in title
assert 'Everything about this' in story
# back to top notes menu
need_keypress(KEY_ENTER)
m = cap_menu()
assert 'Export All' in m
@pytest.mark.parametrize('size', [ 4000, 30000])
@pytest.mark.parametrize('encoding', '2Z' )
def test_huge_notes(size, encoding, goto_notes, pick_menu_item, enter_text, cap_menu, cap_story, need_keypress, cap_screen_qr, readback_bbqr, scan_a_qr, settings_set, settings_get):
# Since we don't limit note sizes, by request of NVK ... test them
n_body = ''.join(chr((i%95) + 32) for i in prandom(size))
n_title = f'Size {size}'
# kill old things, enable feature
settings_set('notes', [])
goto_notes('New Note')
enter_text(n_title)
# use BBRq to import body -- fast and verbatim
need_keypress(KEY_QR)
actual_vers, parts = split_qrs(n_body, 'U', max_version=20, encoding=encoding)
random.shuffle(parts)
for p in parts:
scan_a_qr(p)
time.sleep(2.0 / len(parts)) # just so we can watch
time.sleep(.5) # decompression time in some cases
notes = settings_get('notes')
assert len(notes) == 1
assert notes[0]['title'] == n_title
assert notes[0]['misc'] == n_body
settings_set('notes', [])
goto_notes() # redraw
# EOF