diff --git a/custom_components/mail_and_packages/__init__.py b/custom_components/mail_and_packages/__init__.py index e022d1b1..051373d4 100644 --- a/custom_components/mail_and_packages/__init__.py +++ b/custom_components/mail_and_packages/__init__.py @@ -12,6 +12,7 @@ from .const import ( CONF_AMAZON_DAYS, + CONF_AMAZON_DOMAIN, CONF_AMAZON_FWDS, CONF_IMAGE_SECURITY, CONF_IMAP_SECURITY, @@ -103,10 +104,10 @@ async def async_unload_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> async def async_migrate_entry(hass, config_entry): """Migrate an old config entry.""" version = config_entry.version - new_version = 7 + new_version = 8 _LOGGER.debug("Migrating from version %s", version) - updated_config = config_entry.data.copy() + updated_config = {**config_entry.data} # 1 -> 4: Migrate format if version == 1: @@ -160,6 +161,10 @@ async def async_migrate_entry(hass, config_entry): if CONF_IMAP_SECURITY not in updated_config: updated_config[CONF_IMAP_SECURITY] = "SSL" + if version <= 7: + if CONF_AMAZON_DOMAIN not in updated_config: + updated_config[CONF_AMAZON_DOMAIN] = "amazon.com" + if updated_config != config_entry.data: hass.config_entries.async_update_entry( config_entry, data=updated_config, version=new_version diff --git a/custom_components/mail_and_packages/config_flow.py b/custom_components/mail_and_packages/config_flow.py index 4f0f7595..417559e7 100644 --- a/custom_components/mail_and_packages/config_flow.py +++ b/custom_components/mail_and_packages/config_flow.py @@ -18,6 +18,7 @@ from .const import ( CONF_ALLOW_EXTERNAL, CONF_AMAZON_DAYS, + CONF_AMAZON_DOMAIN, CONF_AMAZON_FWDS, CONF_CUSTOM_IMG, CONF_CUSTOM_IMG_FILE, @@ -32,6 +33,7 @@ CONF_VERIFY_SSL, DEFAULT_ALLOW_EXTERNAL, DEFAULT_AMAZON_DAYS, + DEFAULT_AMAZON_DOMAIN, DEFAULT_AMAZON_FWDS, DEFAULT_CUSTOM_IMG, DEFAULT_CUSTOM_IMG_FILE, @@ -48,6 +50,7 @@ ERROR_MAILBOX_FAIL = "Problem getting mailbox listing using 'INBOX' message" IMAP_SECURITY = ["none", "startTLS", "SSL"] +AMAZON_SENSORS = ["amazon_packages", "amazon_delivered", "amazon_exception"] _LOGGER = logging.getLogger(__name__) @@ -89,13 +92,16 @@ async def _validate_user_input(user_input: dict) -> tuple: errors = {} # Validate amazon forwarding email addresses - if isinstance(user_input[CONF_AMAZON_FWDS], str): - status, amazon_list = await _check_amazon_forwards(user_input[CONF_AMAZON_FWDS]) - if status[0] == "ok": - user_input[CONF_AMAZON_FWDS] = amazon_list - else: - user_input[CONF_AMAZON_FWDS] = amazon_list - errors[CONF_AMAZON_FWDS] = status[0] + if CONF_AMAZON_FWDS in user_input: + if isinstance(user_input[CONF_AMAZON_FWDS], str): + status, amazon_list = await _check_amazon_forwards( + user_input[CONF_AMAZON_FWDS] + ) + if status[0] == "ok": + user_input[CONF_AMAZON_FWDS] = amazon_list + else: + user_input[CONF_AMAZON_FWDS] = amazon_list + errors[CONF_AMAZON_FWDS] = status[0] # Check for ffmpeg if option enabled if user_input[CONF_GENERATE_MP4]: @@ -197,10 +203,6 @@ def _get_default(key: str, fallback_default: Any = None) -> None: vol.Required( CONF_RESOURCES, default=_get_default(CONF_RESOURCES) ): cv.multi_select(get_resources()), - vol.Optional( - CONF_AMAZON_FWDS, default=_get_default(CONF_AMAZON_FWDS, "(none)") - ): cv.string, - vol.Optional(CONF_AMAZON_DAYS, default=_get_default(CONF_AMAZON_DAYS)): int, vol.Optional( CONF_SCAN_INTERVAL, default=_get_default(CONF_SCAN_INTERVAL) ): vol.All(vol.Coerce(int), vol.Range(min=5)), @@ -242,11 +244,33 @@ def _get_default(key: str, fallback_default: Any = None) -> None: ) +def _get_schema_step_amazon(user_input: list, default_dict: list) -> Any: + """Get a schema using the default_dict as a backup.""" + if user_input is None: + user_input = {} + + def _get_default(key: str, fallback_default: Any = None) -> None: + """Get default value for key.""" + return user_input.get(key, default_dict.get(key, fallback_default)) + + return vol.Schema( + { + vol.Required( + CONF_AMAZON_DOMAIN, default=_get_default(CONF_AMAZON_DOMAIN) + ): cv.string, + vol.Optional( + CONF_AMAZON_FWDS, default=_get_default(CONF_AMAZON_FWDS, "(none)") + ): cv.string, + vol.Optional(CONF_AMAZON_DAYS, default=_get_default(CONF_AMAZON_DAYS)): int, + } + ) + + @config_entries.HANDLERS.register(DOMAIN) class MailAndPackagesFlowHandler(config_entries.ConfigFlow, domain=DOMAIN): """Config flow for Mail and Packages.""" - VERSION = 7 + VERSION = 8 CONNECTION_CLASS = config_entries.CONN_CLASS_CLOUD_POLL def __init__(self): @@ -299,7 +323,12 @@ async def async_step_config_2(self, user_input=None): if user_input is not None: self._errors, user_input = await _validate_user_input(user_input) self._data.update(user_input) + _LOGGER.debug("RESOURCES: %s", self._data[CONF_RESOURCES]) if len(self._errors) == 0: + if any( + sensor in self._data[CONF_RESOURCES] for sensor in AMAZON_SENSORS + ): + return await self.async_step_config_amazon() if self._data[CONF_CUSTOM_IMG]: return await self.async_step_config_3() return self.async_create_entry( @@ -319,8 +348,6 @@ async def _show_config_2(self, user_input): CONF_DURATION: DEFAULT_GIF_DURATION, CONF_IMAGE_SECURITY: DEFAULT_IMAGE_SECURITY, CONF_IMAP_TIMEOUT: DEFAULT_IMAP_TIMEOUT, - CONF_AMAZON_FWDS: DEFAULT_AMAZON_FWDS, - CONF_AMAZON_DAYS: DEFAULT_AMAZON_DAYS, CONF_GENERATE_MP4: False, CONF_ALLOW_EXTERNAL: DEFAULT_ALLOW_EXTERNAL, CONF_CUSTOM_IMG: DEFAULT_CUSTOM_IMG, @@ -359,6 +386,36 @@ async def _show_config_3(self, user_input): errors=self._errors, ) + async def async_step_config_amazon(self, user_input=None): + """Configure form step amazon.""" + self._errors = {} + if user_input is not None: + self._data.update(user_input) + self._errors, user_input = await _validate_user_input(self._data) + if len(self._errors) == 0: + if self._data[CONF_CUSTOM_IMG]: + return await self.async_step_config_3() + return self.async_create_entry( + title=self._data[CONF_HOST], data=self._data + ) + return await self._show_config_amazon(user_input) + + return await self._show_config_amazon(user_input) + + async def _show_config_amazon(self, user_input): + """Step 3 setup.""" + # Defaults + defaults = { + CONF_AMAZON_FWDS: DEFAULT_AMAZON_FWDS, + CONF_AMAZON_DAYS: DEFAULT_AMAZON_DAYS, + } + + return self.async_show_form( + step_id="config_amazon", + data_schema=_get_schema_step_amazon(user_input, defaults), + errors=self._errors, + ) + async def async_step_reconfigure(self, user_input: dict[str, Any] | None = None): """Add reconfigure step to allow to reconfigure a config entry.""" self._entry = self.hass.config_entries.async_get_entry(self.context["entry_id"]) @@ -454,3 +511,34 @@ async def _show_reconfig_3(self, user_input): data_schema=_get_schema_step_3(user_input, defaults), errors=self._errors, ) + + async def async_step_reconfig_amazon(self, user_input=None): + """Configure form step amazon.""" + self._errors = {} + if user_input is not None: + self._data.update(user_input) + self._errors, user_input = await _validate_user_input(self._data) + if len(self._errors) == 0: + if self._data[CONF_CUSTOM_IMG]: + return await self.async_step_config_3() + return self.async_create_entry( + title=self._data[CONF_HOST], data=self._data + ) + return await self._show_reconfig_amazon(user_input) + + return await self._show_reconfig_amazon(user_input) + + async def _show_reconfig_amazon(self, user_input): + """Step 3 setup.""" + # Defaults + defaults = { + CONF_AMAZON_DOMAIN: DEFAULT_AMAZON_DOMAIN, + CONF_AMAZON_FWDS: DEFAULT_AMAZON_FWDS, + CONF_AMAZON_DAYS: DEFAULT_AMAZON_DAYS, + } + + return self.async_show_form( + step_id="reconfig_amazon", + data_schema=_get_schema_step_amazon(user_input, defaults), + errors=self._errors, + ) diff --git a/custom_components/mail_and_packages/const.py b/custom_components/mail_and_packages/const.py index 815433f4..969ea16b 100644 --- a/custom_components/mail_and_packages/const.py +++ b/custom_components/mail_and_packages/const.py @@ -56,6 +56,7 @@ CONF_AMAZON_DAYS = "amazon_days" CONF_VERIFY_SSL = "verify_ssl" CONF_IMAP_SECURITY = "imap_security" +CONF_AMAZON_DOMAIN = "amazon_domain" # Defaults DEFAULT_CAMERA_NAME = "Mail USPS Camera" @@ -73,6 +74,7 @@ DEFAULT_CUSTOM_IMG = False DEFAULT_CUSTOM_IMG_FILE = "custom_components/mail_and_packages/images/mail_none.gif" DEFAULT_AMAZON_DAYS = 3 +DEFAULT_AMAZON_DOMAIN = "amazon.com" # Amazon AMAZON_DOMAINS = [ diff --git a/custom_components/mail_and_packages/helpers.py b/custom_components/mail_and_packages/helpers.py index 16c6a201..5e9410b0 100644 --- a/custom_components/mail_and_packages/helpers.py +++ b/custom_components/mail_and_packages/helpers.py @@ -38,7 +38,6 @@ from .const import ( AMAZON_DELIVERED, AMAZON_DELIVERED_SUBJECT, - AMAZON_DOMAINS, AMAZON_EMAIL, AMAZON_EXCEPTION, AMAZON_EXCEPTION_ORDER, @@ -70,6 +69,7 @@ ATTR_USPS_MAIL, CONF_ALLOW_EXTERNAL, CONF_AMAZON_DAYS, + CONF_AMAZON_DOMAIN, CONF_AMAZON_FWDS, CONF_CUSTOM_IMG, CONF_CUSTOM_IMG_FILE, @@ -359,6 +359,9 @@ def fetch( Returns integer of sensor passed to it """ + if sensor in data: + return data[sensor] + img_out_path = f"{hass.config.path()}/{config.get(CONF_PATH)}" gif_duration = config.get(CONF_DURATION) generate_mp4 = config.get(CONF_GENERATE_MP4) @@ -367,13 +370,13 @@ def fetch( amazon_image_name = data[ATTR_AMAZON_IMAGE] amazon_days = config.get(CONF_AMAZON_DAYS) - if config.get(CONF_CUSTOM_IMG): - nomail = config.get(CONF_CUSTOM_IMG_FILE) - else: - nomail = None - - if sensor in data: - return data[sensor] + # Conditional variables + nomail = ( + config.get(CONF_CUSTOM_IMG_FILE) if config.get(CONF_CUSTOM_IMG_FILE) else None + ) + amazon_domain = ( + config.get(CONF_AMAZON_DOMAIN) if config.get(CONF_AMAZON_DOMAIN) else None + ) count = {} @@ -392,19 +395,21 @@ def fetch( ATTR_COUNT, amazon_fwds, amazon_days, + amazon_domain, ) count[AMAZON_ORDER] = get_items( account, ATTR_ORDER, amazon_fwds, amazon_days, + amazon_domain, ) elif sensor == AMAZON_HUB: value = amazon_hub(account, amazon_fwds) count[sensor] = value[ATTR_COUNT] count[AMAZON_HUB_CODE] = value[ATTR_CODE] elif sensor == AMAZON_EXCEPTION: - info = amazon_exception(account, amazon_fwds) + info = amazon_exception(account, amazon_fwds, amazon_domain) count[sensor] = info[ATTR_COUNT] count[AMAZON_EXCEPTION_ORDER] = info[ATTR_ORDER] elif "_packages" in sensor: @@ -415,7 +420,7 @@ def fetch( elif "_delivering" in sensor: prefix = sensor.replace("_delivering", "") delivered = fetch(hass, config, account, data, f"{prefix}_delivered") - info = get_count(account, sensor, True) + info = get_count(account, sensor, True, amazon_domain=amazon_domain) count[sensor] = max(0, info[ATTR_COUNT] - delivered) count[f"{prefix}_tracking"] = info[ATTR_TRACKING] elif sensor == "zpackages_delivered": @@ -435,7 +440,7 @@ def fetch( count[sensor] = update_time() else: count[sensor] = get_count( - account, sensor, False, img_out_path, hass, amazon_image_name + account, sensor, False, img_out_path, hass, amazon_image_name, amazon_domain )[ATTR_COUNT] data.update(count) @@ -922,6 +927,7 @@ def get_count( image_path: Optional[str] = None, hass: Optional[HomeAssistant] = None, amazon_image_name: Optional[str] = None, + amazon_domain: Optional[str] = None, ) -> dict: """Get Package Count. @@ -936,7 +942,9 @@ def get_count( # Return Amazon delivered info if sensor_type == AMAZON_DELIVERED: - result[ATTR_COUNT] = amazon_search(account, image_path, hass, amazon_image_name) + result[ATTR_COUNT] = amazon_search( + account, image_path, hass, amazon_image_name, amazon_domain + ) result[ATTR_TRACKING] = "" return result @@ -1093,6 +1101,7 @@ def amazon_search( image_path: str, hass: HomeAssistant, amazon_image_name: str, + amazon_domain: str, ) -> int: """Find Amazon Delivered email. @@ -1103,8 +1112,9 @@ def amazon_search( subjects = AMAZON_DELIVERED_SUBJECT today = get_formatted_date() count = 0 + domains = amazon_domain.split() - for domain in AMAZON_DOMAINS: + for domain in domains: for subject in subjects: email_address = AMAZON_EMAIL + domain _LOGGER.debug("Amazon email search address: %s", str(email_address)) @@ -1273,7 +1283,9 @@ def amazon_hub(account: Type[imaplib.IMAP4_SSL], fwds: Optional[str] = None) -> def amazon_exception( - account: Type[imaplib.IMAP4_SSL], fwds: Optional[list] = None + account: Type[imaplib.IMAP4_SSL], + fwds: Optional[list] = None, + the_domain: str = None, ) -> dict: """Find Amazon exception emails. @@ -1283,7 +1295,7 @@ def amazon_exception( tfmt = get_formatted_date() count = 0 info = {} - domains = AMAZON_DOMAINS + domains = the_domain.split() if isinstance(fwds, list): for fwd in fwds: if fwd and fwd != '""' and fwd not in domains: @@ -1348,6 +1360,7 @@ def get_items( param: str = None, fwds: Optional[str] = None, days: int = DEFAULT_AMAZON_DAYS, + the_domain: str = None, ) -> Union[List[str], int]: """Parse Amazon emails for delivery date and order number. @@ -1361,9 +1374,8 @@ def get_items( deliveries_today = [] order_number = [] domains = _process_amazon_forwards(fwds) - - for main_domain in AMAZON_DOMAINS: - domains.append(main_domain) + the_domain = the_domain.split() + domains.append(the_domain) _LOGGER.debug("Amazon email list: %s", str(domains)) diff --git a/custom_components/mail_and_packages/strings.json b/custom_components/mail_and_packages/strings.json index 0f38d355..284e6feb 100644 --- a/custom_components/mail_and_packages/strings.json +++ b/custom_components/mail_and_packages/strings.json @@ -36,12 +36,10 @@ "image_security": "Random Image Filename", "imap_timeout": "Time in seconds before connection timeout (seconds, minimum 10)", "generate_mp4": "Create mp4 from images", - "amazon_fwds": "Amazon forwarded email addresses", - "amazon_days": "Days back to check for Amazon emails", "allow_external": "Create image for notification apps", "custom_img": "Use custom 'no image' image?" }, - "description": "Finish the configuration by customizing the following based on your email structure and Home Assistant installation.\n\nFor details on the [Mail and Packages integration](https://github.com/moralmunky/Home-Assistant-Mail-And-Packages/wiki/Configuration-and-Email-Settings#configuration) options review the [configuration, templates, and automations section](https://github.com/moralmunky/Home-Assistant-Mail-And-Packages/wiki/Configuration-and-Email-Settings#configuration) on GitHub.\n\nIf using Amazon forwarded emails please seperate each address with a comma or enter (none) to clear this setting.", + "description": "Finish the configuration by customizing the following based on your email structure and Home Assistant installation.\n\nFor details on the [Mail and Packages integration](https://github.com/moralmunky/Home-Assistant-Mail-And-Packages/wiki/Configuration-and-Email-Settings#configuration) options review the [configuration, templates, and automations section](https://github.com/moralmunky/Home-Assistant-Mail-And-Packages/wiki/Configuration-and-Email-Settings#configuration) on GitHub.", "title": "Mail and Packages (Step 2 of 2)" }, "config_3": { @@ -51,6 +49,15 @@ "description": "Enter the path and file name to your custom no mail image below.\n\nExample: images/custom_nomail.gif", "title": "Mail and Packages (Step 3 of 3)" }, + "config_amazon": { + "data": { + "amazon_domain": "Amazon domain", + "amazon_fwds": "Amazon forwarded email addresses", + "amazon_days": "Days back to check for Amazon emails" + }, + "description": "Please enter the domain amazon sends email's from (ie: amazon.com or amazon.de)\n\nIf using Amazon forwarded emails please seperate each address with a comma or enter (none) to clear this setting.", + "title": "Amazon Settings" + }, "reconfigure": { "data": { "host": "Host", @@ -87,57 +94,16 @@ }, "description": "Enter the path and file name to your custom no mail image below.\n\nExample: images/custom_nomail.gif", "title": "Mail and Packages (Step 3 of 3)" - } - } - }, - "options": { - "error": { - "communication": "Unable to connect or login to the mail server. Please check the log for details.", - "invalid_path": "Please store the images in another directory.", - "ffmpeg_not_found": "Generate MP4 requires ffmpeg", - "amazon_domain": "Invalid forwarding email address.", - "file_not_found": "Image file not found", - "scan_too_low": "Scan interval too low (minimum 5)", - "timeout_too_low": "IMAP timeout too low (minumim 10)" - }, - "step": { - "init": { - "data": { - "host": "Host", - "password": "Password", - "port": "Port", - "username": "Username", - "imap_security": "IMAP Security", - "verify_ssl": "Verify SSL Cert" - }, - "description": "Please enter the connection information of your mail server.", - "title": "Mail and Packages (Step 1 of 2)" }, - "options_2": { + "reconfig_amazon": { "data": { - "folder": "Mail Folder", - "resources": "Sensors List", - "scan_interval": "Scanning Interval (minutes, minimum 5)", - "image_path": "Image Path", - "gif_duration": "Image Duration (seconds)", - "image_security": "Random Image Filename", - "imap_timeout": "Time in seconds before connection timeout (seconds, minimum 10)", - "generate_mp4": "Create mp4 from images", + "amazon_domain": "Amazon domain", "amazon_fwds": "Amazon forwarded email addresses", - "amazon_days": "Days back to check for Amazon emails", - "allow_external": "Create image for notification apps", - "custom_img": "Use custom 'no image' image?" - }, - "description": "Finish the configuration by customizing the following based on your email structure and Home Assistant installation.\n\nFor details on the [Mail and Packages integration](https://github.com/moralmunky/Home-Assistant-Mail-And-Packages/wiki/Configuration-and-Email-Settings#configuration) options review the [configuration, templates, and automations section](https://github.com/moralmunky/Home-Assistant-Mail-And-Packages/wiki/Configuration-and-Email-Settings#configuration) on GitHub.\n\nIf using Amazon forwarded emails please seperate each address with a comma or enter (none) to clear this setting.", - "title": "Mail and Packages (Step 2 of 2)" - }, - "options_3": { - "data": { - "custom_img_file": "Path to custom image: (ie: images/my_custom_no_mail.jpg)" + "amazon_days": "Days back to check for Amazon emails" }, - "description": "Enter the path and file name to your custom no mail image below.\n\nExample: images/custom_nomail.gif", - "title": "Mail and Packages (Step 3 of 3)" - } + "description": "Please enter the domain amazon sends email's from (ie: amazon.com or amazon.de)\n\nIf using Amazon forwarded emails please seperate each address with a comma or enter (none) to clear this setting.", + "title": "Amazon Settings" + } } } } \ No newline at end of file diff --git a/custom_components/mail_and_packages/translations/en.json b/custom_components/mail_and_packages/translations/en.json index 0f063ba6..ef4cc493 100644 --- a/custom_components/mail_and_packages/translations/en.json +++ b/custom_components/mail_and_packages/translations/en.json @@ -1,145 +1,109 @@ { "config": { - "abort": { - "single_instance_allowed": "Only a single configuration of Mail and Packages is allowed.", - "reconfigure_successful": "Reconfigure Successful" + "abort": { + "single_instance_allowed": "Only a single configuration of Mail and Packages is allowed.", + "reconfigure_successful": "Reconfigure Successful" + }, + "error": { + "communication": "Unable to connect or login to the mail server. Please check the log for details.", + "invalid_path": "Please store the images in another directory.", + "ffmpeg_not_found": "Generate MP4 requires ffmpeg", + "amazon_domain": "Invalid forwarding email address.", + "file_not_found": "Image file not found", + "scan_too_low": "Scan interval too low (minimum 5)", + "timeout_too_low": "IMAP timeout too low (minumim 10)" + }, + "step": { + "user": { + "data": { + "host": "Host", + "password": "Password", + "port": "Port", + "username": "Username", + "imap_security": "IMAP Security", + "verify_ssl": "Verify SSL Cert" + }, + "description": "Please enter the connection information of your mail server.", + "title": "Mail and Packages (Step 1 of 2)" }, - "error": { - "communication": "Unable to connect or login to the mail server. Please check the log for details.", - "invalid_path": "Please store the images in another directory.", - "ffmpeg_not_found": "Generate MP4 requires ffmpeg", - "amazon_domain": "Invalid forwarding email address.", - "file_not_found": "Image file not found", - "scan_too_low": "Scan interval too low (minimum 5)", - "timeout_too_low": "IMAP timeout too low (minimum 10)" + "config_2": { + "data": { + "folder": "Mail Folder", + "resources": "Sensors List", + "scan_interval": "Scanning Interval (minutes, minimum 5)", + "image_path": "Image Path", + "gif_duration": "Image Duration (seconds)", + "image_security": "Random Image Filename", + "imap_timeout": "Time in seconds before connection timeout (seconds, minimum 10)", + "generate_mp4": "Create mp4 from images", + "allow_external": "Create image for notification apps", + "custom_img": "Use custom 'no image' image?" + }, + "description": "Finish the configuration by customizing the following based on your email structure and Home Assistant installation.\n\nFor details on the [Mail and Packages integration](https://github.com/moralmunky/Home-Assistant-Mail-And-Packages/wiki/Configuration-and-Email-Settings#configuration) options review the [configuration, templates, and automations section](https://github.com/moralmunky/Home-Assistant-Mail-And-Packages/wiki/Configuration-and-Email-Settings#configuration) on GitHub.", + "title": "Mail and Packages (Step 2 of 2)" }, - "step": { - "user": { - "data": { - "host": "Host", - "password": "Password", - "port": "Port", - "username": "Username", - "imap_security": "IMAP Security", - "verify_ssl": "Verify SSL Cert" - }, - "description": "Please enter the connection information of your mail server.", - "title": "Mail and Packages (Step 1 of 2)" - }, - "config_2": { - "data": { - "folder": "Mail Folder", - "scan_interval": "Scanning Interval (minutes)", - "image_path": "Image Path", - "gif_duration": "Image Duration (seconds)", - "image_security": "Random Image Filename", - "generate_mp4": "Create mp4 from images", - "resources": "Sensors List", - "imap_timeout": "Time in seconds before connection timeout (seconds, minimum 10)", - "amazon_fwds": "Amazon fowarded email addresses", - "allow_external": "Create image for notification apps", - "amazon_days": "Days back to check for Amazon emails", - "custom_img": "Use custom 'no image' image?" - }, - "description": "Finish the configuration by customizing the following based on your email structure and Home Assistant installation.\n\nFor details on the [Mail and Packages integration](https://github.com/moralmunky/Home-Assistant-Mail-And-Packages/wiki/Configuration-and-Email-Settings#configuration) options review the [configuration, templates, and automations section](https://github.com/moralmunky/Home-Assistant-Mail-And-Packages/wiki/Configuration-and-Email-Settings#configuration) on GitHub.\n\nIf using Amazon forwarded emails please seperate each address with a comma or enter (none) to clear this setting.", - "title": "Mail and Packages (Step 2 of 2)" - }, - "config_3": { - "data": { - "custom_img_file": "Path to custom image: (i.e.: images/my_custom_no_mail.jpg)" - }, - "description": "Enter the path and file name to your custom no mail image below.\n\nExample: images/custom_nomail.gif", - "title": "Mail and Packages (Step 3 of 3)" - }, - "reconfigure": { - "data": { - "host": "Host", - "password": "Password", - "port": "Port", - "username": "Username", - "imap_security": "IMAP Security", - "verify_ssl": "Verify SSL Cert" - }, - "description": "Please enter the connection information of your mail server.", - "title": "Mail and Packages (Step 1 of 2)" - }, - "reconfig_2": { - "data": { - "folder": "Mail Folder", - "scan_interval": "Scanning Interval (minutes)", - "image_path": "Image Path", - "gif_duration": "Image Duration (seconds)", - "image_security": "Random Image Filename", - "generate_mp4": "Create mp4 from images", - "resources": "Sensors List", - "imap_timeout": "Time in seconds before connection timeout (seconds, minimum 10)", - "amazon_fwds": "Amazon fowarded email addresses", - "allow_external": "Create image for notification apps", - "amazon_days": "Days back to check for Amazon emails", - "custom_img": "Use custom 'no image' image?" - }, - "description": "Finish the configuration by customizing the following based on your email structure and Home Assistant installation.\n\nFor details on the [Mail and Packages integration](https://github.com/moralmunky/Home-Assistant-Mail-And-Packages/wiki/Configuration-and-Email-Settings#configuration) options review the [configuration, templates, and automations section](https://github.com/moralmunky/Home-Assistant-Mail-And-Packages/wiki/Configuration-and-Email-Settings#configuration) on GitHub.\n\nIf using Amazon forwarded emails please seperate each address with a comma or enter (none) to clear this setting.", - "title": "Mail and Packages (Step 2 of 2)" - }, - "reconfig_3": { - "data": { - "custom_img_file": "Path to custom image: (i.e.: images/my_custom_no_mail.jpg)" - }, - "description": "Enter the path and file name to your custom no mail image below.\n\nExample: images/custom_nomail.gif", - "title": "Mail and Packages (Step 3 of 3)" - } + "config_3": { + "data": { + "custom_img_file": "Path to custom image: (ie: images/my_custom_no_mail.jpg)" + }, + "description": "Enter the path and file name to your custom no mail image below.\n\nExample: images/custom_nomail.gif", + "title": "Mail and Packages (Step 3 of 3)" }, - "title": "Mail and Packages" - }, - "options": { - "error": { - "communication": "Unable to connect or login to the mail server. Please check the log for details.", - "invalid_path": "Please store the images in another directory.", - "ffmpeg_not_found": "Generate MP4 requires ffmpeg", - "amazon_domain": "Invalid forwarding email address.", - "file_not_found": "Image file not found", - "scan_too_low": "Scan interval too low (minimum 5)", - "timeout_too_low": "IMAP timeout too low (minimum 10)" + "config_amazon": { + "data": { + "amazon_domain": "Amazon domain", + "amazon_fwds": "Amazon forwarded email addresses", + "amazon_days": "Days back to check for Amazon emails" + }, + "description": "Please enter the domain amazon sends email's from (ie: amazon.com or amazon.de)\n\nIf using Amazon forwarded emails please seperate each address with a comma or enter (none) to clear this setting.", + "title": "Amazon Settings" + }, + "reconfigure": { + "data": { + "host": "Host", + "password": "Password", + "port": "Port", + "username": "Username", + "imap_security": "IMAP Security", + "verify_ssl": "Verify SSL Cert" + }, + "description": "Please enter the connection information of your mail server.", + "title": "Mail and Packages (Step 1 of 2)" }, - "step": { - "init": { - "data": { - "host": "Host", - "password": "Password", - "port": "Port", - "username": "Username", - "imap_security": "IMAP Security", - "verify_ssl": "Verify SSL Cert" - }, - "description": "Please enter the connection information of your mail server.", - "title": "Mail and Packages (Step 1 of 2)" + "reconfig_2": { + "data": { + "folder": "Mail Folder", + "scan_interval": "Scanning Interval (minutes)", + "image_path": "Image Path", + "gif_duration": "Image Duration (seconds)", + "image_security": "Random Image Filename", + "generate_mp4": "Create mp4 from images", + "resources": "Sensors List", + "imap_timeout": "Time in seconds before connection timeout (seconds, minimum 10)", + "amazon_fwds": "Amazon fowarded email addresses", + "allow_external": "Create image for notification apps", + "amazon_days": "Days back to check for Amazon emails", + "custom_img": "Use custom 'no image' image?" }, - "options_2": { - "data": { - "folder": "Mail Folder", - "scan_interval": "Scanning Interval (minutes)", - "image_path": "Image Path", - "gif_duration": "Image Duration (seconds)", - "image_security": "Random Image Filename", - "generate_mp4": "Create mp4 from images", - "resources": "Sensors List", - "imap_timeout": "Time in seconds before connection timeout (seconds, minimum 10)", - "amazon_fwds": "Amazon forwarded email addresses", - "allow_external": "Create image for notification apps", - "amazon_days": "Days back to check for Amazon emails", - "custom_img": "Use custom 'no image' image?" - }, - "description": "Finish the configuration by customizing the following based on your email structure and Home Assistant installation.\n\nFor details on the [Mail and Packages integration](https://github.com/moralmunky/Home-Assistant-Mail-And-Packages/wiki/Configuration-and-Email-Settings#configuration) options review the [configuration, templates, and automations section](https://github.com/moralmunky/Home-Assistant-Mail-And-Packages/wiki/Configuration-and-Email-Settings#configuration) on GitHub.\n\nIf using Amazon forwarded emails please seperate each address with a comma or enter (none) to clear this setting.", - "title": "Mail and Packages (Step 2 of 2)" + "description": "Finish the configuration by customizing the following based on your email structure and Home Assistant installation.\n\nFor details on the [Mail and Packages integration](https://github.com/moralmunky/Home-Assistant-Mail-And-Packages/wiki/Configuration-and-Email-Settings#configuration) options review the [configuration, templates, and automations section](https://github.com/moralmunky/Home-Assistant-Mail-And-Packages/wiki/Configuration-and-Email-Settings#configuration) on GitHub.\n\nIf using Amazon forwarded emails please seperate each address with a comma or enter (none) to clear this setting.", + "title": "Mail and Packages (Step 2 of 2)" + }, + "reconfig_3": { + "data": { + "custom_img_file": "Path to custom image: (i.e.: images/my_custom_no_mail.jpg)" }, - "options_3": { - "data": { - "custom_img_file": "Path to custom image: (i.e.: images/my_custom_no_mail.jpg)" - }, - "description": "Enter the path and file name to your custom no mail image below.\n\nExample: images/custom_nomail.gif", - "title": "Mail and Packages (Step 3 of 3)" - } - } - }, - "title": "Mail and Packages" -} \ No newline at end of file + "description": "Enter the path and file name to your custom no mail image below.\n\nExample: images/custom_nomail.gif", + "title": "Mail and Packages (Step 3 of 3)" + }, + "reconfig_amazon": { + "data": { + "amazon_domain": "Amazon domain", + "amazon_fwds": "Amazon forwarded email addresses", + "amazon_days": "Days back to check for Amazon emails" + }, + "description": "Please enter the domain amazon sends email's from (ie: amazon.com or amazon.de)\n\nIf using Amazon forwarded emails please seperate each address with a comma or enter (none) to clear this setting.", + "title": "Amazon Settings" + } + } + } + } \ No newline at end of file diff --git a/tests/conftest.py b/tests/conftest.py index b0e383dd..ec0b3dd6 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -14,7 +14,7 @@ from aioresponses import aioresponses from pytest_homeassistant_custom_component.common import MockConfigEntry -from custom_components.mail_and_packages.const import DOMAIN +from custom_components.mail_and_packages.const import CONF_AMAZON_DOMAIN, DOMAIN from tests.const import ( FAKE_CONFIG_DATA, FAKE_CONFIG_DATA_AMAZON_FWD_STRING, @@ -91,7 +91,7 @@ async def integration_fixture_3(hass): @pytest.fixture(name="integration_fwd_string") -async def integration_fixture_4(hass): +async def integration_fixture_4(hass, caplog): """Set up the mail_and_packages integration.""" entry = MockConfigEntry( domain=DOMAIN, @@ -103,6 +103,11 @@ async def integration_fixture_4(hass): await hass.config_entries.async_setup(entry.entry_id) await hass.async_block_till_done() + assert "Migrating from version 3" in caplog.text + assert "Migration complete to version 8" in caplog.text + + assert CONF_AMAZON_DOMAIN in entry.data + return entry @@ -143,6 +148,7 @@ async def integration_fixture_7(hass): domain=DOMAIN, title="imap.test.email", data=FAKE_CONFIG_DATA_V4_MIGRATE, + version=4, ) entry.add_to_hass(hass) await hass.config_entries.async_setup(entry.entry_id) diff --git a/tests/const.py b/tests/const.py index 4cabfc56..e7251345 100644 --- a/tests/const.py +++ b/tests/const.py @@ -57,6 +57,7 @@ FAKE_CONFIG_DATA = { "allow_external": False, "amazon_days": 3, + "amazon_domain": "amazon.com", "amazon_fwds": "fakeuser@fake.email, fakeuser2@fake.email", "custom_img": False, "folder": '"INBOX"', @@ -126,6 +127,7 @@ FAKE_CONFIG_DATA_EXTERNAL = { "allow_external": True, "amazon_days": 3, + "amazon_domain": "amazon.com", "amazon_fwds": "fakeuser@fake.email, fakeuser2@fake.email", "custom_img": False, "folder": '"INBOX"', @@ -189,6 +191,7 @@ FAKE_CONFIG_DATA_CORRECTED_EXTERNAL = { "allow_external": True, "amazon_days": 3, + "amazon_domain": "amazon.com", "amazon_fwds": ["fakeuser@fake.email", "fakeuser2@fake.email"], "custom_img": False, "folder": '"INBOX"', @@ -252,6 +255,7 @@ FAKE_CONFIG_DATA_CORRECTED = { "allow_external": False, "amazon_days": 3, + "amazon_domain": "amazon.com", "amazon_fwds": ["fakeuser@fake.email", "fakeuser2@fake.email"], "custom_img": False, "folder": '"INBOX"', @@ -319,6 +323,7 @@ } FAKE_CONFIG_DATA_NO_PATH = { + "amazon_domain": "amazon.com", "amazon_fwds": ["fakeuser@fake.email", "fakeuser2@fake.email"], "custom_img": False, "folder": '"INBOX"', @@ -380,6 +385,7 @@ FAKE_CONFIG_DATA_NO_RND = { "amazon_days": 3, + "amazon_domain": "amazon.com", "amazon_fwds": ["fakeuser@fake.email"], "custom_img": False, "folder": '"INBOX"', @@ -437,6 +443,7 @@ } FAKE_CONFIG_DATA_MP4 = { + "amazon_domain": "amazon.com", "amazon_fwds": ["fakeuser@fake.email"], "custom_img": False, "folder": '"INBOX"', @@ -542,6 +549,7 @@ } FAKE_CONFIG_DATA_MISSING_TIMEOUT = { + "amazon_domain": "amazon.com", "amazon_fwds": "fakeuser@fake.email, fakeuser2@fake.email", "custom_img": False, "folder": '"INBOX"', @@ -603,6 +611,7 @@ FAKE_CONFIG_DATA_AMAZON_FWD_STRING = { "allow_external": True, + "amazon_domain": "amazon.com", "amazon_fwds": "fakeuser@fake.email", "custom_img": False, "folder": '"INBOX"', @@ -664,6 +673,7 @@ } FAKE_CONFIG_DATA_CUSTOM_IMG = { "amazon_days": 3, + "amazon_domain": "amazon.com", "allow_external": False, "amazon_fwds": ["fakeuser@fake.email", "fakeuser2@fake.email"], "custom_img": True, @@ -828,6 +838,7 @@ } FAKE_CONFIG_DATA_V4_MIGRATE = { "allow_external": True, + "amazon_domain": "amazon.com", "amazon_fwds": ['""'], "custom_img": False, "folder": '"INBOX"', diff --git a/tests/test_binary_sensor.py b/tests/test_binary_sensor.py index bd92c69b..0c0acda1 100644 --- a/tests/test_binary_sensor.py +++ b/tests/test_binary_sensor.py @@ -3,8 +3,8 @@ from unittest.mock import patch import pytest -from pytest_homeassistant_custom_component.common import MockConfigEntry from homeassistant.helpers import entity_registry as er +from pytest_homeassistant_custom_component.common import MockConfigEntry from custom_components.mail_and_packages.const import DOMAIN from tests.const import FAKE_CONFIG_DATA diff --git a/tests/test_config_flow.py b/tests/test_config_flow.py index fddd7f7d..03668891 100644 --- a/tests/test_config_flow.py +++ b/tests/test_config_flow.py @@ -19,7 +19,7 @@ @pytest.mark.parametrize( - "input_1,step_id_2,input_2,step_id_3,input_3,title,data", + "input_1,step_id_2,input_2,step_id_3,input_3,step_id_4,input_4,title,data", [ ( { @@ -33,8 +33,6 @@ "config_2", { "allow_external": False, - "amazon_days": 3, - "amazon_fwds": "fakeuser@test.email,fakeuser2@test.email", "custom_img": True, "folder": '"INBOX"', "generate_mp4": False, @@ -70,6 +68,12 @@ "inpost_pl_packages", ], }, + "config_amazon", + { + "amazon_domain": "amazon.com", + "amazon_days": 3, + "amazon_fwds": "fakeuser@test.email,fakeuser2@test.email", + }, "config_3", { "custom_img_file": "images/test.gif", @@ -78,6 +82,7 @@ { "allow_external": False, "amazon_days": 3, + "amazon_domain": "amazon.com", "amazon_fwds": ["fakeuser@test.email", "fakeuser2@test.email"], "custom_img": True, "custom_img_file": "images/test.gif", @@ -131,6 +136,8 @@ async def test_form( input_2, step_id_3, input_3, + step_id_4, + input_4, title, data, hass, @@ -158,25 +165,30 @@ async def test_form( "custom_components.mail_and_packages.async_setup_entry", return_value=True, ) as mock_setup_entry: - result2 = await hass.config_entries.flow.async_configure( + result = await hass.config_entries.flow.async_configure( result["flow_id"], input_1 ) - assert result2["type"] == "form" - assert result2["step_id"] == step_id_2 + assert result["type"] == "form" + assert result["step_id"] == step_id_2 - result3 = await hass.config_entries.flow.async_configure( + result = await hass.config_entries.flow.async_configure( result["flow_id"], input_2 ) - assert result3["type"] == "form" - assert result3["step_id"] == step_id_3 - result4 = await hass.config_entries.flow.async_configure( + assert result["type"] == "form" + assert result["step_id"] == step_id_3 + result = await hass.config_entries.flow.async_configure( result["flow_id"], input_3 ) + assert result["type"] == "form" + assert result["step_id"] == step_id_4 + result = await hass.config_entries.flow.async_configure( + result["flow_id"], input_4 + ) - assert result4["type"] == "create_entry" - assert result4["title"] == title - assert result4["data"] == data + assert result["type"] == "create_entry" + assert result["title"] == title + assert result["data"] == data await hass.async_block_till_done() assert len(mock_setup.mock_calls) == 1 @@ -184,7 +196,7 @@ async def test_form( @pytest.mark.parametrize( - "input_1,step_id_2,input_2,step_id_3,input_3,title,data", + "input_1,step_id_2,input_2,step_id_3,input_3,step_id_4,input_4,title,data", [ ( { @@ -198,8 +210,6 @@ async def test_form( "config_2", { "allow_external": False, - "amazon_days": 3, - "amazon_fwds": "(none)", "custom_img": True, "folder": '"INBOX"', "generate_mp4": False, @@ -235,6 +245,12 @@ async def test_form( "inpost_pl_packages", ], }, + "config_amazon", + { + "amazon_domain": "amazon.com", + "amazon_days": 3, + "amazon_fwds": "(none)", + }, "config_3", { "custom_img_file": "images/test.gif", @@ -243,6 +259,7 @@ async def test_form( { "allow_external": False, "amazon_days": 3, + "amazon_domain": "amazon.com", "amazon_fwds": [], "custom_img": True, "custom_img_file": "images/test.gif", @@ -296,6 +313,8 @@ async def test_form_no_fwds( input_2, step_id_3, input_3, + step_id_4, + input_4, title, data, hass, @@ -323,25 +342,30 @@ async def test_form_no_fwds( "custom_components.mail_and_packages.async_setup_entry", return_value=True, ) as mock_setup_entry: - result2 = await hass.config_entries.flow.async_configure( + result = await hass.config_entries.flow.async_configure( result["flow_id"], input_1 ) - assert result2["type"] == "form" - assert result2["step_id"] == step_id_2 + assert result["type"] == "form" + assert result["step_id"] == step_id_2 - result3 = await hass.config_entries.flow.async_configure( + result = await hass.config_entries.flow.async_configure( result["flow_id"], input_2 ) - assert result3["type"] == "form" - assert result3["step_id"] == step_id_3 - result4 = await hass.config_entries.flow.async_configure( + assert result["type"] == "form" + assert result["step_id"] == step_id_3 + result = await hass.config_entries.flow.async_configure( result["flow_id"], input_3 ) + assert result["type"] == "form" + assert result["step_id"] == step_id_4 + result = await hass.config_entries.flow.async_configure( + result["flow_id"], input_4 + ) - assert result4["type"] == "create_entry" - assert result4["title"] == title - assert result4["data"] == data + assert result["type"] == "create_entry" + assert result["title"] == title + assert result["data"] == data await hass.async_block_till_done() assert len(mock_setup.mock_calls) == 1 @@ -349,7 +373,7 @@ async def test_form_no_fwds( @pytest.mark.parametrize( - "input_1,step_id_2,input_2,step_id_3,input_3,title,data", + "input_1,step_id_2,input_2,step_id_3,input_3,step_id_4,input_4,title,data", [ ( { @@ -363,8 +387,6 @@ async def test_form_no_fwds( "config_2", { "allow_external": False, - "amazon_days": 3, - "amazon_fwds": "fakeuser@test.email,fakeuser2@test.email", "custom_img": True, "folder": '"INBOX"', "generate_mp4": False, @@ -400,6 +422,12 @@ async def test_form_no_fwds( "inpost_pl_packages", ], }, + "config_amazon", + { + "amazon_domain": "amazon.com", + "amazon_days": 3, + "amazon_fwds": "fakeuser@test.email,fakeuser2@test.email", + }, "config_3", { "custom_img_file": "images/test.gif", @@ -408,6 +436,7 @@ async def test_form_no_fwds( { "allow_external": False, "amazon_days": 3, + "amazon_domain": "amazon.com", "amazon_fwds": ["fakeuser@test.email", "fakeuser2@test.email"], "custom_img": True, "custom_img_file": "images/test.gif", @@ -461,6 +490,8 @@ async def test_form_invalid_custom_img_path( input_2, step_id_3, input_3, + step_id_4, + input_4, title, data, hass, @@ -486,25 +517,30 @@ async def test_form_invalid_custom_img_path( "custom_components.mail_and_packages.async_setup_entry", return_value=True, ) as mock_setup_entry: - result2 = await hass.config_entries.flow.async_configure( + result = await hass.config_entries.flow.async_configure( result["flow_id"], input_1 ) - assert result2["type"] == "form" - assert result2["step_id"] == step_id_2 + assert result["type"] == "form" + assert result["step_id"] == step_id_2 - result3 = await hass.config_entries.flow.async_configure( + result = await hass.config_entries.flow.async_configure( result["flow_id"], input_2 ) - assert result3["type"] == "form" - assert result3["step_id"] == step_id_3 - result4 = await hass.config_entries.flow.async_configure( + assert result["type"] == "form" + assert result["step_id"] == step_id_3 + result = await hass.config_entries.flow.async_configure( result["flow_id"], input_3 ) + assert result["type"] == "form" + assert result["step_id"] == step_id_4 + result = await hass.config_entries.flow.async_configure( + result["flow_id"], input_4 + ) - assert result4["type"] == "form" - assert result4["step_id"] == step_id_3 - assert result4["errors"] == {"custom_img_file": "file_not_found"} + assert result["type"] == "form" + assert result["step_id"] == step_id_4 + assert result["errors"] == {"custom_img_file": "file_not_found"} @pytest.mark.parametrize( @@ -555,7 +591,7 @@ async def test_form_connection_error(input_1, step_id_2, hass, mock_imap): @pytest.mark.parametrize( - "input_1,step_id_2,input_2,title,data", + "input_1,step_id_2,input_2,step_id_3,input_3,title,data", [ ( { @@ -569,8 +605,6 @@ async def test_form_connection_error(input_1, step_id_2, hass, mock_imap): "config_2", { "allow_external": False, - "amazon_days": 3, - "amazon_fwds": "", "folder": '"INBOX"', "generate_mp4": True, "gif_duration": 5, @@ -605,9 +639,16 @@ async def test_form_connection_error(input_1, step_id_2, hass, mock_imap): "inpost_pl_packages", ], }, + "config_amazon", + { + "amazon_domain": "amazon.com", + "amazon_days": 3, + "amazon_fwds": "(none)", + }, "imap.test.email", { "amazon_days": 3, + "amazon_domain": "amazon.com", "amazon_fwds": [], "host": "imap.test.email", "port": 993, @@ -654,7 +695,7 @@ async def test_form_connection_error(input_1, step_id_2, hass, mock_imap): ) @pytest.mark.asyncio async def test_form_invalid_ffmpeg( - input_1, step_id_2, input_2, title, data, hass, mock_imap + input_1, step_id_2, input_2, step_id_3, input_3, title, data, hass, mock_imap ): """Test we get the form.""" await setup.async_setup_component(hass, "persistent_notification", {}) @@ -693,7 +734,7 @@ async def test_form_invalid_ffmpeg( @pytest.mark.parametrize( - "input_1,step_id_2,input_2,title,data", + "input_1,step_id_2,input_2,step_id_3,input_3,title,data", [ ( { @@ -708,8 +749,6 @@ async def test_form_invalid_ffmpeg( { "allow_external": False, "custom_img": False, - "amazon_days": 3, - "amazon_fwds": "", "folder": '"INBOX"', "generate_mp4": False, "gif_duration": 5, @@ -744,11 +783,18 @@ async def test_form_invalid_ffmpeg( "inpost_pl_packages", ], }, + "config_amazon", + { + "amazon_domain": "amazon.com", + "amazon_days": 3, + "amazon_fwds": "(none)", + }, "imap.test.email", { "allow_external": False, "custom_img": False, "amazon_days": 3, + "amazon_domain": "amazon.com", "amazon_fwds": [], "host": "imap.test.email", "port": 993, @@ -798,6 +844,8 @@ async def test_form_index_error( input_1, step_id_2, input_2, + step_id_3, + input_3, title, data, hass, @@ -823,19 +871,25 @@ async def test_form_index_error( "custom_components.mail_and_packages.async_setup_entry", return_value=True, ) as mock_setup_entry: - result2 = await hass.config_entries.flow.async_configure( + result = await hass.config_entries.flow.async_configure( result["flow_id"], input_1 ) - assert result2["type"] == "form" - assert result2["step_id"] == step_id_2 + assert result["type"] == "form" + assert result["step_id"] == step_id_2 - result3 = await hass.config_entries.flow.async_configure( + result = await hass.config_entries.flow.async_configure( result["flow_id"], input_2 ) - assert result3["type"] == "create_entry" - assert result3["title"] == title - assert result3["data"] == data + assert result["type"] == "form" + assert result["step_id"] == step_id_3 + result = await hass.config_entries.flow.async_configure( + result["flow_id"], input_3 + ) + + assert result["type"] == "create_entry" + assert result["title"] == title + assert result["data"] == data await hass.async_block_till_done() assert len(mock_setup.mock_calls) == 1 @@ -843,7 +897,7 @@ async def test_form_index_error( @pytest.mark.parametrize( - "input_1,step_id_2,input_2,title,data", + "input_1,step_id_2,input_2,step_id_3,input_3,title,data", [ ( { @@ -857,8 +911,6 @@ async def test_form_index_error( "config_2", { "allow_external": False, - "amazon_days": 3, - "amazon_fwds": "", "custom_img": False, "folder": '"INBOX"', "generate_mp4": False, @@ -894,10 +946,17 @@ async def test_form_index_error( "inpost_pl_packages", ], }, + "config_amazon", + { + "amazon_domain": "amazon.com", + "amazon_days": 3, + "amazon_fwds": "(none)", + }, "imap.test.email", { "allow_external": False, "amazon_days": 3, + "amazon_domain": "amazon.com", "amazon_fwds": [], "custom_img": False, "host": "imap.test.email", @@ -948,6 +1007,8 @@ async def test_form_index_error_2( input_1, step_id_2, input_2, + step_id_3, + input_3, title, data, hass, @@ -973,19 +1034,25 @@ async def test_form_index_error_2( "custom_components.mail_and_packages.async_setup_entry", return_value=True, ) as mock_setup_entry: - result2 = await hass.config_entries.flow.async_configure( + result = await hass.config_entries.flow.async_configure( result["flow_id"], input_1 ) - assert result2["type"] == "form" - assert result2["step_id"] == step_id_2 + assert result["type"] == "form" + assert result["step_id"] == step_id_2 - result3 = await hass.config_entries.flow.async_configure( + result = await hass.config_entries.flow.async_configure( result["flow_id"], input_2 ) - assert result3["type"] == "create_entry" - assert result3["title"] == title - assert result3["data"] == data + assert result["type"] == "form" + assert result["step_id"] == step_id_3 + result = await hass.config_entries.flow.async_configure( + result["flow_id"], input_3 + ) + + assert result["type"] == "create_entry" + assert result["title"] == title + assert result["data"] == data await hass.async_block_till_done() assert len(mock_setup.mock_calls) == 1 @@ -993,7 +1060,7 @@ async def test_form_index_error_2( @pytest.mark.parametrize( - "input_1,step_id_2,input_2,title,data", + "input_1,step_id_2,input_2,step_id_3,input_3,title,data", [ ( { @@ -1007,8 +1074,6 @@ async def test_form_index_error_2( "config_2", { "allow_external": False, - "amazon_days": 3, - "amazon_fwds": "", "folder": '"INBOX"', "generate_mp4": False, "gif_duration": 5, @@ -1043,11 +1108,18 @@ async def test_form_index_error_2( "inpost_pl_packages", ], }, + "config_amazon", + { + "amazon_domain": "amazon.com", + "amazon_days": 3, + "amazon_fwds": "(none)", + }, "imap.test.email", { "allow_external": False, "custom_img": False, "amazon_days": 3, + "amazon_domain": "amazon.com", "amazon_fwds": [], "host": "imap.test.email", "port": 993, @@ -1097,6 +1169,8 @@ async def test_form_mailbox_format2( input_1, step_id_2, input_2, + step_id_3, + input_3, title, data, hass, @@ -1122,19 +1196,25 @@ async def test_form_mailbox_format2( "custom_components.mail_and_packages.async_setup_entry", return_value=True, ) as mock_setup_entry: - result2 = await hass.config_entries.flow.async_configure( + result = await hass.config_entries.flow.async_configure( result["flow_id"], input_1 ) - assert result2["type"] == "form" - assert result2["step_id"] == step_id_2 + assert result["type"] == "form" + assert result["step_id"] == step_id_2 - result3 = await hass.config_entries.flow.async_configure( + result = await hass.config_entries.flow.async_configure( result["flow_id"], input_2 ) - assert result3["type"] == "create_entry" - assert result3["title"] == title - assert result3["data"] == data + assert result["type"] == "form" + assert result["step_id"] == step_id_3 + result = await hass.config_entries.flow.async_configure( + result["flow_id"], input_3 + ) + + assert result["type"] == "create_entry" + assert result["title"] == title + assert result["data"] == data await hass.async_block_till_done() assert len(mock_setup.mock_calls) == 1 @@ -1142,7 +1222,7 @@ async def test_form_mailbox_format2( @pytest.mark.parametrize( - "input_1,step_id_2,input_2,title,data", + "input_1,step_id_2,input_2,step_id_3,input_3,title,data", [ ( { @@ -1156,8 +1236,6 @@ async def test_form_mailbox_format2( "config_2", { "allow_external": False, - "amazon_days": 3, - "amazon_fwds": "", "folder": '"INBOX"', "generate_mp4": False, "gif_duration": 5, @@ -1192,11 +1270,18 @@ async def test_form_mailbox_format2( "inpost_pl_packages", ], }, + "config_amazon", + { + "amazon_domain": "amazon.com", + "amazon_days": 3, + "amazon_fwds": "(none)", + }, "imap.test.email", { "allow_external": False, "custom_img": False, "amazon_days": 3, + "amazon_domain": "amazon.com", "amazon_fwds": [], "host": "imap.test.email", "port": 993, @@ -1246,6 +1331,8 @@ async def test_form_mailbox_format3( input_1, step_id_2, input_2, + step_id_3, + input_3, title, data, hass, @@ -1271,19 +1358,25 @@ async def test_form_mailbox_format3( "custom_components.mail_and_packages.async_setup_entry", return_value=True, ) as mock_setup_entry: - result2 = await hass.config_entries.flow.async_configure( + result = await hass.config_entries.flow.async_configure( result["flow_id"], input_1 ) - assert result2["type"] == "form" - assert result2["step_id"] == step_id_2 + assert result["type"] == "form" + assert result["step_id"] == step_id_2 - result3 = await hass.config_entries.flow.async_configure( + result = await hass.config_entries.flow.async_configure( result["flow_id"], input_2 ) - assert result3["type"] == "create_entry" - assert result3["title"] == title - assert result3["data"] == data + assert result["type"] == "form" + assert result["step_id"] == step_id_3 + result = await hass.config_entries.flow.async_configure( + result["flow_id"], input_3 + ) + + assert result["type"] == "create_entry" + assert result["title"] == title + assert result["data"] == data await hass.async_block_till_done() assert len(mock_setup.mock_calls) == 1 @@ -1327,7 +1420,7 @@ async def test_imap_login_error(mock_imap_login_error, caplog): @pytest.mark.parametrize( - "input_1,step_id_2,input_2", + "input_1,step_id_2,input_2,step_id_3,input_3", [ ( { @@ -1341,8 +1434,6 @@ async def test_imap_login_error(mock_imap_login_error, caplog): "config_2", { "allow_external": False, - "amazon_days": 3, - "amazon_fwds": "testemail@amazon.com", "custom_img": False, "folder": '"INBOX"', "generate_mp4": False, @@ -1378,6 +1469,12 @@ async def test_imap_login_error(mock_imap_login_error, caplog): "inpost_pl_packages", ], }, + "config_amazon", + { + "amazon_domain": "amazon.com", + "amazon_days": 3, + "amazon_fwds": "testemail@amazon.com", + }, ), ], ) @@ -1386,6 +1483,8 @@ async def test_form_amazon_error( input_1, step_id_2, input_2, + step_id_3, + input_3, mock_imap, hass, ): @@ -1408,15 +1507,21 @@ async def test_form_amazon_error( "custom_components.mail_and_packages.async_setup_entry", return_value=True, ) as mock_setup_entry: - result2 = await hass.config_entries.flow.async_configure( + result = await hass.config_entries.flow.async_configure( result["flow_id"], input_1 ) - assert result2["type"] == "form" - assert result2["step_id"] == step_id_2 + assert result["type"] == "form" + assert result["step_id"] == step_id_2 - result3 = await hass.config_entries.flow.async_configure( + result = await hass.config_entries.flow.async_configure( result["flow_id"], input_2 ) - assert result3["type"] == "form" - assert result3["step_id"] == step_id_2 - assert result3["errors"] == {CONF_AMAZON_FWDS: "amazon_domain"} + + assert result["type"] == "form" + assert result["step_id"] == step_id_3 + result = await hass.config_entries.flow.async_configure( + result["flow_id"], input_3 + ) + assert result["type"] == "form" + assert result["step_id"] == step_id_3 + assert result["errors"] == {CONF_AMAZON_FWDS: "amazon_domain"} diff --git a/tests/test_helpers.py b/tests/test_helpers.py index 9a69d5f4..23878809 100644 --- a/tests/test_helpers.py +++ b/tests/test_helpers.py @@ -709,30 +709,32 @@ async def test_royal_out_for_delivery(hass, mock_imap_royal_out_for_delivery): @freeze_time("2020-09-11") @pytest.mark.asyncio async def test_amazon_shipped_count(hass, mock_imap_amazon_shipped): - result = get_items(mock_imap_amazon_shipped, "count") + result = get_items(mock_imap_amazon_shipped, "count", the_domain="amazon.com") assert result == 1 @pytest.mark.asyncio async def test_amazon_shipped_order(hass, mock_imap_amazon_shipped): - result = get_items(mock_imap_amazon_shipped, "order") + result = get_items(mock_imap_amazon_shipped, "order", the_domain="amazon.com") assert result == ["123-1234567-1234567"] @pytest.mark.asyncio async def test_amazon_shipped_order_alt(hass, mock_imap_amazon_shipped_alt): - result = get_items(mock_imap_amazon_shipped_alt, "order") + result = get_items(mock_imap_amazon_shipped_alt, "order", the_domain="amazon.com") assert result == ["123-1234567-1234567"] @pytest.mark.asyncio async def test_amazon_shipped_order_alt_2(hass, mock_imap_amazon_shipped_alt_2): - result = get_items(mock_imap_amazon_shipped_alt_2, "order") + result = get_items(mock_imap_amazon_shipped_alt_2, "order", the_domain="amazon.com") assert result == ["113-9999999-8459426"] with patch("datetime.date") as mock_date: mock_date.today.return_value = date(2021, 12, 3) - result = get_items(mock_imap_amazon_shipped_alt_2, "count") + result = get_items( + mock_imap_amazon_shipped_alt_2, "count", the_domain="amazon.com" + ) assert result == 1 @@ -740,25 +742,29 @@ async def test_amazon_shipped_order_alt_2(hass, mock_imap_amazon_shipped_alt_2): async def test_amazon_shipped_order_alt_timeformat( hass, mock_imap_amazon_shipped_alt_timeformat ): - result = get_items(mock_imap_amazon_shipped_alt_timeformat, "order") + result = get_items( + mock_imap_amazon_shipped_alt_timeformat, "order", the_domain="amazon.com" + ) assert result == ["321-1234567-1234567"] @pytest.mark.asyncio async def test_amazon_shipped_order_uk(hass, mock_imap_amazon_shipped_uk): - result = get_items(mock_imap_amazon_shipped_uk, "order") + result = get_items(mock_imap_amazon_shipped_uk, "order", the_domain="amazon.co.uk") assert result == ["123-4567890-1234567"] @pytest.mark.asyncio async def test_amazon_shipped_order_uk(hass, mock_imap_amazon_shipped_uk_2): - result = get_items(mock_imap_amazon_shipped_uk_2, "order") + result = get_items( + mock_imap_amazon_shipped_uk_2, "order", the_domain="amazon.co.uk" + ) assert result == ["123-4567890-1234567"] @pytest.mark.asyncio async def test_amazon_shipped_order_it(hass, mock_imap_amazon_shipped_it): - result = get_items(mock_imap_amazon_shipped_it, "order") + result = get_items(mock_imap_amazon_shipped_it, "order", the_domain="amazon.it") assert result == ["405-5236882-9395563"] @@ -766,22 +772,24 @@ async def test_amazon_shipped_order_it(hass, mock_imap_amazon_shipped_it): async def test_amazon_shipped_order_it_count(hass, mock_imap_amazon_shipped_it): with patch("datetime.date") as mock_date: mock_date.today.return_value = date(2021, 12, 1) - result = get_items(mock_imap_amazon_shipped_it, "count") + result = get_items(mock_imap_amazon_shipped_it, "count", the_domain="amazon.it") assert result == 1 @pytest.mark.asyncio async def test_amazon_search(hass, mock_imap_no_email): - result = amazon_search(mock_imap_no_email, "test/path", hass, "testfilename.jpg") + result = amazon_search( + mock_imap_no_email, "test/path", hass, "testfilename.jpg", "amazon.com" + ) assert result == 0 @pytest.mark.asyncio async def test_amazon_search_results(hass, mock_imap_amazon_shipped): result = amazon_search( - mock_imap_amazon_shipped, "test/path", hass, "testfilename.jpg" + mock_imap_amazon_shipped, "test/path", hass, "testfilename.jpg", "amazon.com" ) - assert result == 98 + assert result == 7 @pytest.mark.asyncio @@ -789,9 +797,9 @@ async def test_amazon_search_delivered( hass, mock_imap_amazon_delivered, mock_download_img ): result = amazon_search( - mock_imap_amazon_delivered, "test/path", hass, "testfilename.jpg" + mock_imap_amazon_delivered, "test/path", hass, "testfilename.jpg", "amazon.com" ) - assert result == 98 + assert result == 7 assert mock_download_img.called @@ -800,9 +808,13 @@ async def test_amazon_search_delivered_it( hass, mock_imap_amazon_delivered_it, mock_download_img ): result = amazon_search( - mock_imap_amazon_delivered_it, "test/path", hass, "testfilename.jpg" + mock_imap_amazon_delivered_it, + "test/path", + hass, + "testfilename.jpg", + "amazon.it", ) - assert result == 98 + assert result == 7 @pytest.mark.asyncio @@ -850,14 +862,14 @@ async def test_amazon_hub_2(hass, mock_imap_amazon_the_hub_2): @pytest.mark.asyncio async def test_amazon_shipped_order_exception(hass, mock_imap_amazon_shipped, caplog): with patch("quopri.decodestring", side_effect=ValueError): - get_items(mock_imap_amazon_shipped, "order") + get_items(mock_imap_amazon_shipped, "order", the_domain="amazon.com") assert "Problem decoding email message:" in caplog.text @pytest.mark.asyncio async def test_amazon_shipped_order_exception(hass, mock_imap_amazon_shipped, caplog): with patch("quopri.decodestring", side_effect=ValueError): - get_items(mock_imap_amazon_shipped, "order") + get_items(mock_imap_amazon_shipped, "order", the_domain="amazon.com") assert "Problem decoding email message:" in caplog.text @@ -1034,14 +1046,20 @@ async def test_image_file_name( @pytest.mark.asyncio async def test_amazon_exception(hass, mock_imap_amazon_exception, caplog): - result = amazon_exception(mock_imap_amazon_exception, ['""']) - assert result["order"] == ["123-1234567-1234567"] * 14 - assert result["count"] == 14 + result = amazon_exception( + mock_imap_amazon_exception, ['""'], the_domain="amazon.com" + ) + assert result["order"] == ["123-1234567-1234567"] + assert result["count"] == 1 - result = amazon_exception(mock_imap_amazon_exception, ["testemail@fakedomain.com"]) - assert result["count"] == 15 + result = amazon_exception( + mock_imap_amazon_exception, + ["testemail@fakedomain.com"], + the_domain="amazon.com", + ) + assert result["count"] == 2 assert ( - "Amazon domains to be checked: ['amazon.com', 'amazon.ca', 'amazon.co.uk', 'amazon.in', 'amazon.de', 'amazon.it', 'amazon.com.au', 'amazon.pl', 'amazon.es', 'amazon.fr', 'amazon.ae', 'amazon.nl', 'fakeuser@fake.email', 'fakeuser2@fake.email', 'testemail@fakedomain.com']" + "Amazon domains to be checked: ['amazon.com', 'testemail@fakedomain.com']" in caplog.text ) @@ -1098,6 +1116,6 @@ async def test_email_search_none(mock_imap_search_error_none, caplog): @pytest.mark.asyncio async def test_amazon_shipped_fwd(hass, mock_imap_amazon_fwd, caplog): - result = get_items(mock_imap_amazon_fwd, "order") + result = get_items(mock_imap_amazon_fwd, "order", the_domain="amazon.com") assert result == ["123-1234567-1234567"] assert "First pass: Tuesday, January 11" in caplog.text diff --git a/tests/test_init.py b/tests/test_init.py index 44dfc7ad..d74c5277 100644 --- a/tests/test_init.py +++ b/tests/test_init.py @@ -1,5 +1,6 @@ """Tests for init.""" +import logging from unittest.mock import patch import pytest @@ -117,7 +118,6 @@ async def test_amazon_fwds_string( ): """Test settting up entities.""" entry = integration_fwd_string - assert len(hass.states.async_entity_ids(SENSOR_DOMAIN)) == 42 entries = hass.config_entries.async_entries(DOMAIN) assert len(entries) == 1