From cd00df5c135fd1011000bfa378fdc73f9ebabcb4 Mon Sep 17 00:00:00 2001 From: Roland Date: Wed, 8 May 2024 17:31:15 -0600 Subject: [PATCH] Converting flags to a dict. Using test_async_client wherever tests required it. --- app/src/DashboardPage.js | 22 ++++++++++--------- app/src/hooks/customHooks.js | 2 +- wrolpi/files/test/test_lib.py | 39 +++++++++++++++++----------------- wrolpi/files/test/test_pdfs.py | 2 +- wrolpi/flags.py | 21 +++++++----------- wrolpi/test/test_common.py | 2 +- wrolpi/test/test_events.py | 2 +- wrolpi/test/test_flags.py | 12 +++++------ wrolpi/test/test_root_api.py | 2 +- 9 files changed, 51 insertions(+), 53 deletions(-) diff --git a/app/src/DashboardPage.js b/app/src/DashboardPage.js index 1e353f65..c99df5e7 100644 --- a/app/src/DashboardPage.js +++ b/app/src/DashboardPage.js @@ -28,20 +28,23 @@ import {useWROLMode} from "./hooks/customHooks"; import {FileSearchFilterButton} from "./components/Files"; import {DateSelectorButton} from "./components/DatesSelector"; -function FlagsMessages({flags}) { +function FlagsMessages() { const {settings, fetchSettings} = React.useContext(SettingsContext); + const {status} = useContext(StatusContext); - if (!flags) { + if (!status || !'flags' in status || _.isEmpty(status['flags'])) { return <> } + const flags = status['flags']; + let refreshing; let refreshRequired; let dbDown; let kiwixRestart; // Do not tell the maintainer to refresh the files if they are already refreshing. - if (flags.indexOf('refreshing') >= 0) { + if (flags['refreshing']) { // Actively refreshing. refreshing = @@ -50,7 +53,7 @@ function FlagsMessages({flags}) {

Click here to view the progress

; - } else if (flags.indexOf('refresh_complete') === -1) { + } else if (!flags['refresh_complete']) { // `refresh_complete` flag is not set. Tell the maintainer to refresh the files. refreshRequired = @@ -61,11 +64,11 @@ function FlagsMessages({flags}) { ; } - if (flags.indexOf('kiwix_restart') >= 0) { + if (flags['kiwix_restart']) { kiwixRestart = ; } - if (flags.indexOf('db_up') === -1) { + if (!flags['db_up']) { dbDown = @@ -78,7 +81,7 @@ function FlagsMessages({flags}) { return <> {refreshing} {dbDown || refreshRequired} - {settings && settings['ignore_outdated_zims'] === false && flags.indexOf('outdated_zims') >= 0 ? + {settings && settings['ignore_outdated_zims'] === false && flags['outdated_zims'] ? : null} {kiwixRestart} @@ -90,7 +93,7 @@ export function Getters() { // Getters are Downloads or Uploads. const [selectedGetter, setSelectedGetter] = useState(null); - const gettersDisabled = status?.flags?.indexOf('refresh_complete') === -1; + const gettersDisabled = status?.flags?.refresh_completed !== true; const handleSetGetter = (e, value) => { if (e) { @@ -172,7 +175,6 @@ export function DashboardPage() { setSearchTags, months, dateRange, setDates, clearDate, } = useSearchSuggestions(searchStr, activeTags); - const {status} = useContext(StatusContext); React.useEffect(() => { setSuggestionSearchStr(localSearchStr); @@ -278,7 +280,7 @@ export function DashboardPage() { - {!searchStr && } + {!searchStr && } {body} } diff --git a/app/src/hooks/customHooks.js b/app/src/hooks/customHooks.js index 3b881ad7..4fc3f7cb 100644 --- a/app/src/hooks/customHooks.js +++ b/app/src/hooks/customHooks.js @@ -827,7 +827,7 @@ export const StatusProvider = (props) => { export const useStatusFlag = (flag) => { const {status} = useContext(StatusContext); - return status && status['flags'] && status['flags'].indexOf(flag) >= 0; + return status && status['flags'] && status['flags'][flag]; } export const useCPUTemperature = () => { diff --git a/wrolpi/files/test/test_lib.py b/wrolpi/files/test/test_lib.py index db8e008d..a7a3747b 100644 --- a/wrolpi/files/test/test_lib.py +++ b/wrolpi/files/test/test_lib.py @@ -150,7 +150,7 @@ def test_split_path_stem_and_suffix(path, expected): @pytest.mark.asyncio -async def test_refresh_files(test_session, make_files_structure, assert_file_groups): +async def test_refresh_files(test_async_client, test_session, make_files_structure, assert_file_groups): """All files in the media directory should be found when calling `refresh_files`""" files = make_files_structure([ 'foo.txt', @@ -177,7 +177,7 @@ async def test_refresh_files(test_session, make_files_structure, assert_file_gro @pytest.mark.asyncio -async def test_file_group_location(test_session, make_files_structure): +async def test_file_group_location(test_async_client, test_session, make_files_structure): """FileGroup can return the URL necessary to preview the FileGroup.""" make_files_structure({ 'foo/one.txt': 'one', @@ -191,8 +191,8 @@ async def test_file_group_location(test_session, make_files_structure): @pytest.mark.asyncio -async def test_refresh_bogus_files(test_session, make_files_structure, test_directory, assert_file_groups, - insert_file_group): +async def test_refresh_bogus_files(test_async_client, test_session, make_files_structure, test_directory, + assert_file_groups, insert_file_group): """Bogus files are removed during a refresh.""" make_files_structure(['does exist.txt']) await lib.refresh_files() @@ -212,7 +212,7 @@ async def test_refresh_bogus_files(test_session, make_files_structure, test_dire @pytest.mark.asyncio -async def test_refresh_empty_media_directory(test_session, test_directory): +async def test_refresh_empty_media_directory(test_async_client, test_session, test_directory): """refresh_paths will refuse to refresh with an empty media directory.""" with pytest.raises(UnknownDirectory): await lib.refresh_files() @@ -369,7 +369,7 @@ async def test_file_group_tag(test_session, make_files_structure, test_directory @pytest.mark.asyncio -async def test_refresh_a_text_no_indexer(test_session, make_files_structure): +async def test_refresh_a_text_no_indexer(test_async_client, test_session, make_files_structure): """File.a_text is filled even if the file does not match an Indexer.""" make_files_structure(['foo', 'bar-bar']) @@ -380,7 +380,7 @@ async def test_refresh_a_text_no_indexer(test_session, make_files_structure): @pytest.mark.asyncio -async def test_refresh_many_files(test_session, make_files_structure): +async def test_refresh_many_files(test_async_client, test_session, make_files_structure): """Used to profile file refreshing""" count = 10_000 make_files_structure([f'{uuid4()}.txt' for _ in range(count)]) @@ -416,7 +416,7 @@ async def test_refresh_cancel(test_session, make_files_structure, test_directory @pytest.mark.asyncio -async def test_mime_type(test_session, make_files_structure, test_directory, assert_files): +async def test_mime_type(test_async_client, test_session, make_files_structure, test_directory, assert_files): """Files module uses the `file` command to get the mimetype of each file.""" from PIL import Image @@ -450,7 +450,7 @@ async def test_mime_type(test_session, make_files_structure, test_directory, ass @pytest.mark.asyncio -async def test_files_indexer(test_session, make_files_structure, test_directory): +async def test_files_indexer(test_async_client, test_session, make_files_structure, test_directory): """An Indexer is provided for each file based on it's mimetype or contents.""" source_files: List[str] = [ 'a text file.txt', @@ -751,7 +751,8 @@ def test_file_group_merge(test_session, test_directory, make_files_structure, ta @pytest.mark.asyncio -async def test_move(test_session, test_directory, make_files_structure, video_bytes, singlefile_contents_factory): +async def test_move(test_async_client, test_session, test_directory, make_files_structure, video_bytes, + singlefile_contents_factory): """files.lib.move behaves likes posix mv""" make_files_structure({ 'foo/bar/video.mp4': video_bytes, @@ -784,7 +785,7 @@ async def test_move(test_session, test_directory, make_files_structure, video_by @pytest.mark.asyncio -async def test_move_files(test_session, test_directory, make_files_structure): +async def test_move_files(test_async_client, test_session, test_directory, make_files_structure): """Files can be moved using files.lib.move.""" one, two = make_files_structure({ 'foo/one.txt': 'one', @@ -799,7 +800,7 @@ async def test_move_files(test_session, test_directory, make_files_structure): @pytest.mark.asyncio -async def test_move_deep_directory(test_session, test_directory, make_files_structure): +async def test_move_deep_directory(test_async_client, test_session, test_directory, make_files_structure): """Moving files/directories from one deep directory to another is supported.""" baz, foo, quuz_mp4, quuz_txt, quux = make_files_structure({ 'foo/foo.txt': 'foo', @@ -838,7 +839,7 @@ async def test_move_deep_directory(test_session, test_directory, make_files_stru @pytest.mark.asyncio -async def test_move_directory(test_session, test_directory, make_files_structure, assert_directories): +async def test_move_directory(test_async_client, test_session, test_directory, make_files_structure, assert_directories): """A Directory record is deleted when it's directory is deleted.""" make_files_structure({ 'foo/one.txt': 'one', @@ -889,7 +890,7 @@ async def test_move_error(test_session, test_directory, make_files_structure, vi @pytest.mark.asyncio -async def test_file_group_move(test_session, make_files_structure, test_directory, video_bytes, srt_text): +async def test_file_group_move(test_async_client, test_session, make_files_structure, test_directory, video_bytes, srt_text): """Test FileGroup's move method""" video, srt = make_files_structure({ 'video.mp4': video_bytes, @@ -913,7 +914,7 @@ async def test_file_group_move(test_session, make_files_structure, test_director @pytest.mark.asyncio -async def test_move_tagged(test_session, test_directory, make_files_structure, tag_factory): +async def test_move_tagged(test_async_client, test_session, test_directory, make_files_structure, tag_factory): """A FileGroup's tag is preserved when moved or renamed.""" tag = tag_factory() foo, bar, = make_files_structure({ @@ -955,7 +956,7 @@ async def test_move_tagged(test_session, test_directory, make_files_structure, t @pytest.mark.asyncio -async def test_html_index(test_session, test_directory, make_files_structure): +async def test_html_index(test_async_client, test_session, test_directory, make_files_structure): make_files_structure({ 'archive.html': ''' The Title @@ -1001,7 +1002,7 @@ Outside element.''' @pytest.mark.asyncio -async def test_doc_indexer(test_session, example_doc): +async def test_doc_indexer(test_async_client, test_session, example_doc): """The contents of a Microsoft doc files can be indexed.""" await lib.refresh_files() assert test_session.query(FileGroup).count() == 1 @@ -1012,7 +1013,7 @@ async def test_doc_indexer(test_session, example_doc): @pytest.mark.asyncio -async def test_docx_indexer(test_session, example_docx): +async def test_docx_indexer(test_async_client, test_session, example_docx): """The contents of a Microsoft docx files can be indexed.""" await lib.refresh_files() assert test_session.query(FileGroup).count() == 1 @@ -1023,7 +1024,7 @@ async def test_docx_indexer(test_session, example_docx): @pytest.mark.asyncio -async def test_file_search_date_range(test_session, example_pdf, example_doc): +async def test_file_search_date_range(test_async_client, test_session, example_pdf, example_doc): """Test searching FileGroups by their published datetime.""" await lib.refresh_files() doc, pdf = test_session.query(FileGroup).order_by(FileGroup.primary_path).all() diff --git a/wrolpi/files/test/test_pdfs.py b/wrolpi/files/test/test_pdfs.py index c7171b27..ad5de907 100644 --- a/wrolpi/files/test/test_pdfs.py +++ b/wrolpi/files/test/test_pdfs.py @@ -9,7 +9,7 @@ from wrolpi.files.models import FileGroup @pytest.mark.asyncio -async def test_pdf_title(test_session, example_pdf): +async def test_pdf_title(test_async_client, test_session, example_pdf): """PDF modeler extracts a PDF's title and contents.""" await files_lib.refresh_files() diff --git a/wrolpi/flags.py b/wrolpi/flags.py index c3743e22..790e5a2d 100644 --- a/wrolpi/flags.py +++ b/wrolpi/flags.py @@ -3,7 +3,6 @@ import contextlib import multiprocessing import subprocess from datetime import datetime -from typing import List from sqlalchemy import Column, Boolean, Integer @@ -127,19 +126,15 @@ refresh_cleanup = Flag('refresh_cleanup') refresh_complete = Flag('refresh_complete', store_db=True) -def get_flags() -> List[str]: +def get_flags() -> dict: """Return a list of all Flags which are set.""" - flags = [] - if db_up.is_set(): - flags.append('db_up') - if refreshing.is_set(): - flags.append('refreshing') - if refresh_complete.is_set(): - flags.append('refresh_complete') - if outdated_zims.is_set(): - flags.append('outdated_zims') - if kiwix_restart.is_set(): - flags.append('kiwix_restart') + flags = dict( + db_up=db_up.is_set(), + refreshing=refreshing.is_set(), + refresh_complete=refresh_complete.is_set(), + outdated_zims=outdated_zims.is_set(), + kiwix_restart=kiwix_restart.is_set(), + ) return flags diff --git a/wrolpi/test/test_common.py b/wrolpi/test/test_common.py index 06e332ac..995979e2 100644 --- a/wrolpi/test/test_common.py +++ b/wrolpi/test/test_common.py @@ -801,7 +801,7 @@ def test_find_file(test_directory, make_files_structure): assert common.find_file(test_directory, 'does not exist', 100) is None -def test_config_backup(test_config, test_directory): +def test_config_backup(test_async_client, test_config, test_directory): """Configs have a backup each day.""" config = common.get_wrolpi_config() diff --git a/wrolpi/test/test_events.py b/wrolpi/test/test_events.py index 7a1af95e..3f0e212d 100644 --- a/wrolpi/test/test_events.py +++ b/wrolpi/test/test_events.py @@ -49,7 +49,7 @@ def test_events_history_limit(): @pytest.mark.asyncio -async def test_get_events(): +async def test_get_events(test_async_client): after = now() Events.send_global_refresh_started() diff --git a/wrolpi/test/test_flags.py b/wrolpi/test/test_flags.py index dc576d40..b73a124b 100644 --- a/wrolpi/test/test_flags.py +++ b/wrolpi/test/test_flags.py @@ -17,28 +17,28 @@ def assert_db(session: Session, name: str, expected: bool): def test_flags(test_async_client, test_session, flags_lock): """DB flags can be saved.""" assert flags.refresh_complete.is_set() is False - assert flags.get_flags() == [] + assert not any(v for k, v in flags.get_flags().items()) flags.refresh_complete.set() assert_db(test_session, 'refresh_complete', True) - assert flags.get_flags() == ['refresh_complete'] + assert flags.get_flags()['refresh_complete'] flags.refresh_complete.clear() assert_db(test_session, 'refresh_complete', False) - assert flags.get_flags() == [] + assert not any(v for k, v in flags.get_flags().items()) def test_flags_with(test_async_client, flags_lock): """A Flag can be used with `with` context.""" assert flags.refreshing.is_set() is False, 'Flag should not be set by default' - assert flags.get_flags() == [] + assert not any(v for k, v in flags.get_flags().items()) with flags.refreshing: assert flags.refreshing.is_set() is True, 'Flag should be set within context.' - assert flags.get_flags() == ['refreshing'] + assert flags.get_flags()['refreshing'] assert flags.refreshing.is_set() is False, 'Flag should not be restored after context.' - assert flags.get_flags() == [] + assert not any(v for k, v in flags.get_flags().items()) with pytest.raises(ValueError): # Can't do two `refreshing` as once. diff --git a/wrolpi/test/test_root_api.py b/wrolpi/test/test_root_api.py index 4e23378b..54edd463 100644 --- a/wrolpi/test/test_root_api.py +++ b/wrolpi/test/test_root_api.py @@ -382,7 +382,7 @@ async def test_get_status(test_async_client, test_session): assert 'throttle_status' in response.json and isinstance(response.json['throttle_status'], str) assert 'version' in response.json and isinstance(response.json['version'], str) assert 'memory_stats' in response.json and isinstance(response.json['memory_stats'], dict) - assert 'flags' in response.json and isinstance(response.json['flags'], list) + assert 'flags' in response.json and isinstance(response.json['flags'], dict) def test_post_download(test_session, test_client, test_download_manager_config):