diff --git a/.env.example b/.env.example index 3c19cccc4e..f8166fc1d8 100644 --- a/.env.example +++ b/.env.example @@ -199,7 +199,7 @@ WORDPRESS_CLIENT_URI= RECAPTCHA_SECRET= RECAPTCHA_SITE_KEY= -CYPHT_MODULES="core,contacts,local_contacts,ldap_contacts,gmail_contacts,feeds,jmap,imap,smtp,account,idle_timer,desktop_notifications,calendar,themes,nux,developer,profiles,imap_folders,sievefilters" +CYPHT_MODULES="core,contacts,local_contacts,ldap_contacts,gmail_contacts,feeds,jmap,imap,smtp,account,idle_timer,desktop_notifications,calendar,themes,nux,developer,profiles,imap_folders,sievefilters,tags" #LoginPage FANCY_LOGIN=false diff --git a/.github/tests/.env b/.github/tests/.env index 8780dcf346..f7a13240bb 100644 --- a/.github/tests/.env +++ b/.github/tests/.env @@ -30,7 +30,7 @@ DEFAULT_SMTP_NO_AUTH= USER_CONFIG_TYPE=DB USER_SETTINGS_DIR=/tmp -ATTACHMENT_DIR=/tmp +ATTACHMENT_DIR= ADMIN_USERS= @@ -182,4 +182,4 @@ WORDPRESS_CLIENT_URI= RECAPTCHA_SECRET= RECAPTCHA_SITE_KEY= -CYPHT_MODULES="core,contacts,local_contacts,feeds,imap,smtp,account,idle_timer,calendar,themes,nux,history,saved_searches,advanced_search,profiles,inline_message,imap_folders,keyboard_shortcuts,tags" +CYPHT_MODULES="core,contacts,local_contacts,ldap_contacts,gmail_contacts,feeds,jmap,imap,smtp,account,idle_timer,desktop_notifications,calendar,themes,nux,developer,history,profiles,imap_folders,sievefilters,tags,pgp,inline_message,keyboard_shortcuts,github,wordpress" diff --git a/.github/tests/setup.sh b/.github/tests/setup.sh index 217aa6ed12..3d06d7a9e4 100644 --- a/.github/tests/setup.sh +++ b/.github/tests/setup.sh @@ -28,6 +28,8 @@ setup_cypht() { sed -i 's/mysql/sqlite/' tests/phpunit/mocks.php sed -i "s/'host'/'socket'/" tests/phpunit/mocks.php fi + + sed -i "s|ATTACHMENT_DIR=.*|ATTACHMENT_DIR=$(pwd)/hm3/attachments|" .env } # Create and populate database for phpunit tests @@ -132,6 +134,9 @@ setup_site() { STATUS_ERROR exit 1 fi + STATUS_TITLE "Setup required Directories" + mkdir -p "$(pwd)/hm3/attachments" + STATUS_DONE } ##### UI END ##### diff --git a/.github/workflows/Test-Build.yml b/.github/workflows/Test-Build.yml index 50394811bc..ce27a46693 100644 --- a/.github/workflows/Test-Build.yml +++ b/.github/workflows/Test-Build.yml @@ -16,78 +16,78 @@ on: workflow_dispatch: jobs: - Test-phpunit: - name: PHPUNIT (PHP-${{ matrix.php-versions }} && DB-${{ matrix.database }}) - runs-on: ubuntu-latest - - strategy: - matrix: - php-versions: ['8.1'] - database: ['mysql', 'postgres', 'sqlite'] - - env: - PHP_V: ${{ matrix.php-versions }} - DB: ${{ matrix.database }} - TEST_ARG: 'phpunit' - - services: - mysql: - image: mysql:latest - env: - MYSQL_ROOT_PASSWORD: cypht_test - MYSQL_DATABASE: cypht_test - MYSQL_USER: cypht_test - MYSQL_PASSWORD: cypht_test - ports: - - 3306:3306 - options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3 - - postgresql: - image: postgres:latest - env: - POSTGRES_USER: cypht_test - POSTGRES_PASSWORD: cypht_test - POSTGRES_DB: cypht_test - ports: - - 5432:5432 - options: --health-cmd="pg_isready" --health-interval=10s --health-timeout=5s --health-retries=3 - - steps: - - name: "System Install Dependencies" - run: sudo apt-get install -y mysql-client postgresql-client sqlite3 libsodium-dev - - - name: "Checkout code" - uses: actions/checkout@v4 - with: - fetch-depth: 0 - - - name: "Set up PHP" - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php-versions }} - extensions: pdo, sodium, sqlite, pdo_mysql, pdo_pgsql, memcached, redis, gd, gnupg - tools: phpunit, composer - ini-values: cgi.fix_pathinfo=1 - env: - fail-fast: true - - - name: "Script: setup.sh" - run: bash .github/tests/setup.sh - - - name: "Composer Install Dependencies" - run: | - composer install - composer require --dev php-coveralls/php-coveralls - php scripts/config_gen.php - - - name: "Script: test.sh" - run: bash .github/tests/test.sh + # Test-phpunit: + # name: PHPUNIT (PHP-${{ matrix.php-versions }} && DB-${{ matrix.database }}) + # runs-on: ubuntu-latest + + # strategy: + # matrix: + # php-versions: ['8.1'] + # database: ['mysql', 'postgres', 'sqlite'] + + # env: + # PHP_V: ${{ matrix.php-versions }} + # DB: ${{ matrix.database }} + # TEST_ARG: 'phpunit' + + # services: + # mysql: + # image: mysql:latest + # env: + # MYSQL_ROOT_PASSWORD: cypht_test + # MYSQL_DATABASE: cypht_test + # MYSQL_USER: cypht_test + # MYSQL_PASSWORD: cypht_test + # ports: + # - 3306:3306 + # options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3 + + # postgresql: + # image: postgres:latest + # env: + # POSTGRES_USER: cypht_test + # POSTGRES_PASSWORD: cypht_test + # POSTGRES_DB: cypht_test + # ports: + # - 5432:5432 + # options: --health-cmd="pg_isready" --health-interval=10s --health-timeout=5s --health-retries=3 + + # steps: + # - name: "System Install Dependencies" + # run: sudo apt-get install -y mysql-client postgresql-client sqlite3 libsodium-dev + + # - name: "Checkout code" + # uses: actions/checkout@v4 + # with: + # fetch-depth: 0 + + # - name: "Set up PHP" + # uses: shivammathur/setup-php@v2 + # with: + # php-version: ${{ matrix.php-versions }} + # extensions: pdo, sodium, sqlite, pdo_mysql, pdo_pgsql, memcached, redis, gd, gnupg + # tools: phpunit, composer + # ini-values: cgi.fix_pathinfo=1 + # env: + # fail-fast: true + + # - name: "Script: setup.sh" + # run: bash .github/tests/setup.sh + + # - name: "Composer Install Dependencies" + # run: | + # composer install + # composer require --dev php-coveralls/php-coveralls + # php scripts/config_gen.php + + # - name: "Script: test.sh" + # run: bash .github/tests/test.sh Test-selenium: name: SELENIUM (PHP-${{ matrix.php-versions }} && DB-${{ matrix.database }}) runs-on: ubuntu-latest - needs: Test-phpunit + # needs: Test-phpunit strategy: matrix: diff --git a/config/app.php b/config/app.php index 1f4d263494..a8f2324c8c 100644 --- a/config/app.php +++ b/config/app.php @@ -625,7 +625,7 @@ | Handles page layout, login/logout, and the default settings pages. This set | is required. */ - 'modules' => explode(',', env('CYPHT_MODULES','core,contacts,local_contacts,feeds,imap,smtp,account,idle_timer,calendar,themes,nux,developer,history,saved_searches,advanced_search,highlights,profiles,inline_message,imap_folders,keyboard_shortcuts')), + 'modules' => explode(',', env('CYPHT_MODULES','core,contacts,local_contacts,feeds,imap,smtp,account,idle_timer,calendar,themes,nux,developer,history,saved_searches,advanced_search,highlights,profiles,inline_message,imap_folders,keyboard_shortcuts,tags')), // 'modules' => [ // /* // | ---- diff --git a/modules/smtp/modules.php b/modules/smtp/modules.php index 8f00c8d2bf..1431b9a6c6 100644 --- a/modules/smtp/modules.php +++ b/modules/smtp/modules.php @@ -917,6 +917,9 @@ class Hm_Output_attachment_setting extends Hm_Output_Module { protected function output() { $size_in_kbs = 0; $num_chunks = 0; + if (!is_dir($this->get('attachment_dir'))) { + return; + } $rii = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($this->get('attachment_dir'))); $files = array(); diff --git a/tests/selenium/base.py b/tests/selenium/base.py index 987a9ff04f..ee4c802c1c 100644 --- a/tests/selenium/base.py +++ b/tests/selenium/base.py @@ -34,14 +34,12 @@ def read_ini(self): self.modules = [] self.servers = 1 self.auth_type = '' - config_files = glob.glob('../../config/*.php') - for file_path in config_files: - result = subprocess.run(['php', 'get_config.php'], stdout=subprocess.PIPE) - config_dict = json.loads(result.stdout.decode()) - if 'modules' in config_dict and isinstance(config_dict['modules'], list): - self.modules += config_dict['modules'] - if 'auth_type' in config_dict: - self.auth_type = config_dict['auth_type'] + result = subprocess.run(['php', 'get_config.php'], stdout=subprocess.PIPE) + config_dict = json.loads(result.stdout.decode()) + if 'modules' in config_dict and isinstance(config_dict['modules'], list): + self.modules += config_dict['modules'] + if 'auth_type' in config_dict: + self.auth_type = config_dict['auth_type'] def load(self): print(" - loading site") diff --git a/tests/selenium/get_config.php b/tests/selenium/get_config.php index 64c1a06ab6..162099d119 100644 --- a/tests/selenium/get_config.php +++ b/tests/selenium/get_config.php @@ -1,7 +1,16 @@ load(); + +/* get config object */ +$config = new Hm_Site_Config_File(); +/* set the default since and per_source values */ +$environment->define_default_constants($config); $config = merge_config_files('../../config'); echo json_encode($config); diff --git a/tests/selenium/runall.sh b/tests/selenium/runall.sh index 5c5f48cf3b..1c6bb18731 100644 --- a/tests/selenium/runall.sh +++ b/tests/selenium/runall.sh @@ -3,11 +3,8 @@ PYTHON=$(command -v python3) rm -rf __pycache__/ -#for suite in login.py folder_list.py pages.py profiles.py settings.py servers.py send.py inline_msg.py search.py keyboard_shortcuts.py -#for suite in login.py folder_list.py pages.py profiles.py settings.py servers.py send.py inline_msg.py search.py -# for suite in login.py folder_list.py pages.py servers.py settings.py send.py inline_msg.py search.py tags.py -for suite in login.py folder_list.py pages.py servers.py profiles.py send.py search.py -# for suite in pages.py servers.py settings.py send.py inline_msg.py search.py +#inline_msg.py keyboard_shortcuts.py +for suite in login.py settings.py folder_list.py pages.py servers.py profiles.py send.py search.py tags.py do export TEST_SUITE="$suite" "$PYTHON" -u ./$suite diff --git a/tests/selenium/settings.py b/tests/selenium/settings.py index f72901d0c1..cb8ddd0143 100644 --- a/tests/selenium/settings.py +++ b/tests/selenium/settings.py @@ -22,8 +22,9 @@ def toggle(self, name): def close_section(self, section): self.by_css('[data-target=".'+section+'"]').click() - def save_settings(self): + def save_settings(self, section): self.driver.execute_script("window.scrollTo(0, document.body.scrollHeight);") + self.close_section(section) self.by_name('save_settings').click() self.wait_with_folder_list() self.safari_workaround() @@ -49,7 +50,7 @@ def checkbox_test(self, section, name, checked, mod=False): else: self.is_unchecked(name) self.toggle(name) - self.save_settings() + self.save_settings(section) if checked: self.is_unchecked(name) else: @@ -62,7 +63,7 @@ def number_fld_test(self, section, name, current, new, mod=False): assert int(self.by_name(name).get_attribute('value')) == current self.by_name(name).clear() self.by_name(name).send_keys(new) - self.save_settings() + self.save_settings(section) assert int(self.by_name(name).get_attribute('value')) == new def dropdown_test(self, section, name, current, new, mod=False): @@ -71,7 +72,7 @@ def dropdown_test(self, section, name, current, new, mod=False): self.settings_section(section) assert self.by_name(name).get_attribute('value') == current Select(self.by_name(name)).select_by_value(new) - self.save_settings() + self.save_settings(section) assert self.by_name(name).get_attribute('value') == new @@ -82,80 +83,69 @@ def __init__(self): self.login(USER, PASS) self.wait() - def list_style_test(self): + def load_settings_page(self): + self.by_css('[data-source=".settings"]').click() + list_item = self.by_class('menu_settings') + list_item.find_element(By.TAG_NAME, 'a').click() self.wait_with_folder_list() + assert self.by_class('content_title').text == 'Site Settings' + + def list_style_test(self): self.dropdown_test('general_setting', 'list_style', 'email_style', 'news_style') def auto_bcc_test(self): - self.wait_with_folder_list() self.checkbox_test('general_setting', 'smtp_auto_bcc', False, 'smtp') def keyboard_shortcuts_test(self): - self.wait_with_folder_list() self.checkbox_test('general_setting', 'enable_keyboard_shortcuts', False, 'keyboard_shortcuts') def inline_message_test(self): - self.wait_with_folder_list() self.checkbox_test('general_setting', 'inline_message', False, 'inline_message') def no_folder_icons_test(self): - self.wait_with_folder_list() self.checkbox_test('general_setting', 'no_folder_icons', False) def mailto_handler_test(self): self.checkbox_test('general_setting', 'mailto_handler', False) def msg_list_icons_test(self): - self.wait_with_folder_list() - self.checkbox_test('general_setting', 'show_list_icons', False) + self.checkbox_test('general_setting', 'show_list_icons', True) def msg_part_icons_test(self): - self.wait_with_folder_list() - self.checkbox_test('general_setting', 'msg_part_icons', False) + self.checkbox_test('general_setting', 'msg_part_icons', True) def simple_msg_parts_test(self): - self.wait_with_folder_list() - self.checkbox_test('general_setting', 'simple_msg_parts', True) + self.checkbox_test('general_setting', 'simple_msg_parts', False) def text_only_test(self): - self.wait_with_folder_list() - self.checkbox_test('general_setting', 'text_only', False) + self.checkbox_test('general_setting', 'text_only', True) def disable_delete_prompt_test(self): - self.wait_with_folder_list() self.checkbox_test('general_setting', 'disable_delete_prompt', False) def no_password_save_test(self): - self.wait_with_folder_list() self.checkbox_test('general_setting', 'no_password_save', False) self.close_section('general_setting') def imap_per_page_test(self): - self.wait_with_folder_list() self.number_fld_test('general_setting', 'imap_per_page', 20, 100, 'imap') def mail_format_test(self): - self.wait_with_folder_list() self.dropdown_test('general_setting', 'smtp_compose_type', '0', '1', 'smtp') def theme_test(self): - self.wait_with_folder_list() self.dropdown_test('general_setting', 'theme_setting', 'default', 'cosmo') def tz_test(self): - self.wait_with_folder_list() - self.dropdown_test('general_setting', 'timezone', 'Africa/Abidjan', 'Africa/Algiers') + self.dropdown_test('general_setting', 'timezone', 'UTC', 'Africa/Abidjan') def start_page_test(self): - self.wait_with_folder_list() self.dropdown_test('general_setting', 'start_page', 'none', 'page=home') def unread_since_test(self): - self.wait_with_folder_list() self.dropdown_test('unread_setting', 'unread_since', '-1 week', '-6 weeks') def unread_max_per_source_test(self): - self.wait_with_folder_list() self.number_fld_test('unread_setting', 'unread_per_source', 20, 100) def unread_exclude_github_test(self): @@ -165,52 +155,41 @@ def unread_exclude_wp_test(self): self.checkbox_test('unread_setting', 'unread_exclude_wordpress', False, 'wordpress') def unread_exclude_feed_test(self): - self.wait_with_folder_list() self.checkbox_test('unread_setting', 'unread_exclude_feeds', False, 'feeds') self.close_section('unread_setting') def flagged_since_test(self): - self.wait_with_folder_list() self.dropdown_test('flagged_setting', 'flagged_since', '-1 week', '-6 weeks') def flagged_max_per_source_test(self): - self.wait_with_folder_list() self.number_fld_test('flagged_setting', 'flagged_per_source', 20, 100) self.close_section('flagged_setting') def all_since_test(self): - self.wait_with_folder_list() self.dropdown_test('all_setting', 'all_since', '-1 week', '-6 weeks') def all_max_per_source_test(self): - self.wait_with_folder_list() self.number_fld_test('all_setting', 'all_per_source', 20, 100) self.close_section('all_setting') def all_email_since_test(self): - self.wait_with_folder_list() self.dropdown_test('email_setting', 'all_email_since', '-1 week', '-6 weeks') def all_email_max_per_source_test(self): - self.wait_with_folder_list() self.number_fld_test('email_setting', 'all_email_per_source', 20, 100) self.close_section('email_setting') def feeds_since_test(self): - self.wait() self.dropdown_test('feeds_setting', 'feed_since', 'today', '-6 weeks') def feeds_max_per_source_test(self): - self.wait() self.number_fld_test('feeds_setting', 'feed_limit', 20, 100) self.close_section('feeds_setting') def sent_since_test(self): - self.wait() self.dropdown_test('sent_setting', 'sent_since', '-1 week', '-6 weeks') def sent_max_per_source_test(self): - self.wait_with_folder_list() self.number_fld_test('sent_setting', 'sent_per_source', 20, 100) self.close_section('sent_setting') @@ -229,6 +208,7 @@ def github_max_per_source_test(self): test_runner(SettingsTests, [ # general options + 'load_settings_page', 'list_style_test', 'start_page_test', 'tz_test', @@ -236,8 +216,8 @@ def github_max_per_source_test(self): 'imap_per_page_test', 'mail_format_test', 'auto_bcc_test', - # 'keyboard_shortcuts_test', - # 'inline_message_test', + 'keyboard_shortcuts_test', + 'inline_message_test', 'no_folder_icons_test', 'msg_list_icons_test', 'msg_part_icons_test', diff --git a/tests/selenium/tags.py b/tests/selenium/tags.py index 39d96f0ba5..fced6c6927 100644 --- a/tests/selenium/tags.py +++ b/tests/selenium/tags.py @@ -8,17 +8,9 @@ class TagTest(WebTest): def __init__(self): WebTest.__init__(self) self.login(USER, PASS) - self.wait_with_folder_list() + self.wait() def load_tag_page(self): - self.load() - # ((JavascriptExecutor)driver).executeScript("arguments[0].scrollIntoView(false);", element); - - - self.driver.execute_script("window.scrollTo(0, document.body.scrollHeight);") - self.driver.execute_script("window.scrollTo(0, document.body.scrollHeight);") - self.driver.execute_script("window.scrollTo(0, document.body.scrollHeight);") - self.driver.execute_script("window.scrollTo(0, document.body.scrollHeight);") self.by_css('[data-source=".tags_folders"]').click() list_item = self.by_class('tags_add_new') list_item.find_element(By.TAG_NAME, 'a').click()