# SPDX-License-Identifier: CC0-1.0 """ Haketilo unit tests - displaying list of resources/mappings """ # This file is part of Haketilo # # Copyright (C) 2022, Wojtek Kosior # # This program is free software: you can redistribute it and/or modify # it under the terms of the CC0 1.0 Universal License as published by # the Creative Commons Corporation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # CC0 1.0 Universal License for more details. import pytest from selenium.webdriver.support.ui import WebDriverWait from ..extension_crafting import ExtraHTML from ..script_loader import load_script from .utils import sample_files, sample_files_by_hash, sample_file_ref, \ item_version_string broker_js = lambda: load_script('background/broadcast_broker.js') + ';start();' def make_sample_mapping(identifier, long_name): return { 'source_name': 'example-org-fixes-new', 'source_copyright': [ sample_file_ref('report.spdx'), sample_file_ref('LICENSES/CC0-1.0.txt') ], 'type': 'mapping', 'identifier': identifier, 'long_name': long_name, 'uuid': '54d23bba-472e-42f5-9194-eaa24c0e3ee7', 'version': [2022, 5, 10], 'description': 'suckless something something', 'payloads': { 'https://example.org/a/*': { 'identifier': 'some-KISS-resource' }, 'https://example.org/t/*': { 'identifier': 'another-KISS-resource' } } } def make_sample_resource(identifier, long_name): return { 'source_name': 'hello', 'source_copyright': [ sample_file_ref('report.spdx'), sample_file_ref('LICENSES/CC0-1.0.txt') ], 'type': 'resource', 'identifier': identifier, 'long_name': long_name, 'uuid': 'a6754dcb-58d8-4b7a-a245-24fd7ad4cd68', 'version': [2021, 11, 10], 'revision': 1, 'description': 'greets an apple', 'dependencies': ['hello-message'], 'scripts': [ sample_file_ref('hello.js'), sample_file_ref('bye.js') ] } @pytest.mark.ext_data({ 'background_script': broker_js, 'extra_html': ExtraHTML('html/item_list.html', {}), 'navigate_to': 'html/item_list.html' }) @pytest.mark.usefixtures('webextension') @pytest.mark.parametrize('item_type', ['resource', 'mapping']) def test_item_list_ordering(driver, execute_in_page, item_type): """ A test case of items list proper ordering. """ execute_in_page(load_script('html/item_list.js')) make_item = make_sample_resource if item_type == 'resource' \ else make_sample_mapping # Choose sample long names so as to test automatic sorting of items. long_names = ['sample', 'sample it', 'Sample it', 'SAMPLE IT', 'test', 'test it', 'Test it', 'TEST IT'] # Let's operate on a reverse-sorted copy long_names_reversed = [*long_names] long_names_reversed.reverse() items = [make_item(f'it_{hex(2 * i + copy)[-1]}', name) for i, name in enumerate(long_names_reversed) for copy in (1, 0)] # When adding/updating items this item will be updated at the end and this # last update will be used to verify that a set of opertions completed. extra_item = make_item('extraitem', 'extra item') extra_dict = {'extraitem': {item_version_string(extra_item): extra_item}} # After this reversal items are sorted in the exact order they are expected # to appear in the HTML list. items.reverse() sample_data = { 'resources': {}, 'mappings': {}, 'files': sample_files_by_hash } def is_prime(n): return n > 1 and all([n % i != 0 for i in range(2, n)]) indexes_added = set() for iteration, to_include in enumerate([ set([i for i in range(len(items)) if is_prime(i)]), set([i for i in range(len(items)) if not is_prime(i) and i & 1]), set([i for i in range(len(items)) if i % 3 == 0]), set([i for i in range(len(items)) if i % 3 and not i & 1 and not is_prime(i)]), set(range(16)) ]): # On the last iteration, re-add ALL items but with changed names. if len(to_include) == 16: for it in items: it['long_name'] = f'somewhat renamed {it["long_name"]}' items_to_inclue = [items[i] for i in sorted(to_include)] sample_data[item_type + 's'] = \ dict([(it['identifier'], {item_version_string(it): it}) for it in items_to_inclue]) execute_in_page('returnval(haketilodb.save_items(arguments[0]));', sample_data) extra_item['long_name'] = f'{iteration} {extra_item["long_name"]}' sample_data[item_type + 's'] = extra_dict execute_in_page('returnval(haketilodb.save_items(arguments[0]));', sample_data) if iteration == 0: execute_in_page( f''' let list_ctx, items = arguments[0]; async function create_list() {{ list_ctx = await {item_type}_list(); document.body.append(list_ctx.main_div); }} returnval(create_list()); ''') def lis_ready(driver): return extra_item['long_name'] == execute_in_page( 'returnval(list_ctx.ul.firstElementChild.textContent);' ) indexes_added.update(to_include) WebDriverWait(driver, 10).until(lis_ready) li_texts = execute_in_page( ''' var lis = [...list_ctx.ul.children].slice(1); returnval(lis.map(li => li.textContent)); ''') assert li_texts == [items[i]['long_name'] for i in indexes_added] preview_texts = execute_in_page( '''{ const get_texts = li => [li.click(), list_ctx.preview_container.textContent][1]; returnval(lis.map(get_texts)); }''') for i, text in zip(sorted(indexes_added), preview_texts): assert items[i]['identifier'] in text assert items[i]['long_name'] in text