Skip to content

Add new Nintendo Parental Controls integration #145343

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 28 commits into
base: dev
Choose a base branch
from

Conversation

pantherale0
Copy link
Contributor

@pantherale0 pantherale0 commented May 20, 2025

Breaking change

Proposed change

This PR adds a new Nintendo Parental Controls integration, at the moment this is very basic, however future PRs will update the integration to support the platforms and features available in my custom integration (https://github.com/pantherale0/ha-nintendoparentalcontrols)

Library: https://github.com/pantherale0/pynintendoparental

Type of change

  • Dependency upgrade
  • Bugfix (non-breaking change which fixes an issue)
  • New integration (thank you!)
  • New feature (which adds functionality to an existing integration)
  • Deprecation (breaking change to happen in the future)
  • Breaking change (fix/feature causing existing functionality to break)
  • Code quality improvements to existing code or addition of tests

Additional information

Checklist

  • The code change is tested and works locally.
  • Local tests pass. Your PR cannot be merged unless tests pass
  • There is no commented out code in this PR.
  • I have followed the development checklist
  • I have followed the perfect PR recommendations
  • The code has been formatted using Ruff (ruff format homeassistant tests)
  • Tests have been added to verify that the new code works.

If user exposed functionality or configuration variables are added/changed:

If the code communicates with devices, web services, or third-party tools:

  • The manifest file has all fields filled out correctly.
    Updated and included derived files by running: python3 -m script.hassfest.
  • New or updated dependencies have been added to requirements_all.txt.
    Updated by running python3 -m script.gen_requirements_all.
  • For the updated dependencies - a link to the changelog, or at minimum a diff between library versions is added to the PR description.

To help with the load of incoming pull requests:

@tr4nt0r
Copy link
Contributor

tr4nt0r commented May 20, 2025

Please run python -m script.hassfest to register the integration in Home Assistant

@tr4nt0r
Copy link
Contributor

tr4nt0r commented May 20, 2025

And please also add the link to the library source (github) to the PR description

@pantherale0 pantherale0 marked this pull request as ready for review May 20, 2025 22:29
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't mock the internals of the library, instead mock only the front-facing methods you access in the config flow

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I don't mock the internals of the library, the tests won't pass because:

  • The authentication methods require valid responses from either a user input (and what is mocked is not valid), or the OAuth service itself.
  • The verifier code is generated on each new instance of a config flow
  • Data is needed inside the library itself to allow other functions to work (which will be more important for future PRs)

Comment on lines +71 to +82
mock_request_handler.return_value = {
"status": 400,
"text": "ERROR",
"json": {},
"headers": {"Content-Type": "application/json"},
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just let the client raise instead of mocking the http request. Parametrize to also test the other exceptions.

    mock_authenticator_client.complete_login.side_effect = InvalidSessionTokenException

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See my reply above, this won't work because of the validation done in the library.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did just attempt this again, tests fail -

2025-05-21 10:26:13.542 INFO     MainThread homeassistant.setup:setup.py:394 Setting up nintendo_parental
2025-05-21 10:26:13.545 DEBUG    MainThread pynintendoparental.authenticator:__init__.py:65 >> Init authenticator.
2025-05-21 10:26:13.545 DEBUG    MainThread pynintendoparental.authenticator:__init__.py:135 Refreshing access token.
2025-05-21 10:26:13.546 DEBUG    MainThread pynintendoparental:__init__.py:49 Received request to update data.
2025-05-21 10:26:13.547 DEBUG    MainThread pynintendoparental:api.py:46 Sending request to get_account_devices
2025-05-21 10:26:13.547 DEBUG    MainThread pynintendoparental:api.py:57 Built URL https://api-lp1.pctl.srv.nintendo.net/moon/v1/users/aabbccddee112233/devices?filter.device.activated.$eq=true
2025-05-21 10:26:13.573 ERROR    MainThread homeassistant.components.nintendo_parental.coordinator:update_coordinator.py:451 Unexpected error fetching nintendo_parental data
Traceback (most recent call last):
  File "/home/jordan/Documents/repos/home-assistant/homeassistant/helpers/update_coordinator.py", line 380, in _async_refresh
    self.data = await self._async_update_data()
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/jordan/Documents/repos/home-assistant/homeassistant/components/nintendo_parental/coordinator.py", line 58, in _async_update_data
    return await self.api.update()
           ^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/jordan/Documents/repos/home-assistant/venv/lib64/python3.13/site-packages/pynintendoparental/__init__.py", line 50, in update
    await self._get_devices()
  File "/home/jordan/Documents/repos/home-assistant/venv/lib64/python3.13/site-packages/pynintendoparental/__init__.py", line 33, in _get_devices
    response = await self._api.send_request(
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    ...<2 lines>...
    )
    ^
  File "/home/jordan/Documents/repos/home-assistant/venv/lib64/python3.13/site-packages/pynintendoparental/api.py", line 78, in send_request
    async with session.request(
               ~~~~~~~~~~~~~~~^
        method=e_point.get("method"),
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        url=url,
        ^^^^^^^^
        json=body
        ^^^^^^^^^
    ) as response:
    ^
  File "/home/jordan/Documents/repos/home-assistant/venv/lib64/python3.13/site-packages/aiohttp/client.py", line 1425, in __aenter__
    self._resp: _RetType = await self._coro
                           ^^^^^^^^^^^^^^^^
  File "/home/jordan/Documents/repos/home-assistant/venv/lib64/python3.13/site-packages/aiohttp/client.py", line 703, in _request
    conn = await self._connector.connect(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        req, traces=traces, timeout=real_timeout
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    )
    ^
  File "/home/jordan/Documents/repos/home-assistant/venv/lib64/python3.13/site-packages/aiohttp/connector.py", line 548, in connect
    proto = await self._create_connection(req, traces, timeout)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/jordan/Documents/repos/home-assistant/venv/lib64/python3.13/site-packages/aiohttp/connector.py", line 1056, in _create_connection
    _, proto = await self._create_direct_connection(req, traces, timeout)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/jordan/Documents/repos/home-assistant/venv/lib64/python3.13/site-packages/aiohttp/connector.py", line 1375, in _create_direct_connection
    transp, proto = await self._wrap_create_connection(
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    ...<7 lines>...
    )
    ^
  File "/home/jordan/Documents/repos/home-assistant/venv/lib64/python3.13/site-packages/aiohttp/connector.py", line 1115, in _wrap_create_connection
    sock = await aiohappyeyeballs.start_connection(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    ...<5 lines>...
    )
    ^
  File "/home/jordan/Documents/repos/home-assistant/venv/lib64/python3.13/site-packages/aiohappyeyeballs/impl.py", line 127, in start_connection
    raise first_exception
  File "/home/jordan/Documents/repos/home-assistant/venv/lib64/python3.13/site-packages/aiohappyeyeballs/_staggered.py", line 132, in run_one_coro
    result = await coro_fn()
             ^^^^^^^^^^^^^^^
  File "/home/jordan/Documents/repos/home-assistant/venv/lib64/python3.13/site-packages/aiohappyeyeballs/impl.py", line 183, in _connect_sock
    sock = socket.socket(family=family, type=type_, proto=proto)
  File "/home/jordan/Documents/repos/home-assistant/venv/lib64/python3.13/site-packages/pytest_socket.py", line 89, in __new__
    raise SocketBlockedError()
pytest_socket.SocketBlockedError: A test tried to use socket.socket.
2025-05-21 10:26:13.578 DEBUG    MainThread homeassistant.components.nintendo_parental.coordinator:update_coordinator.py:460 Finished fetching nintendo_parental data in 0.032 seconds (success: False)
2025-05-21 10:26:13.578 DEBUG    MainThread homeassistant.config_entries:config_entries.py:802 Config entry 'aabbccddee112233' for nintendo_parental integration not ready yet: A test tried to use socket.socket.; Retrying in 5 seconds
2025-05-21 10:26:13.581 DEBUG    MainThread homeassistant.core:core.py:1546 Bus:Handling <Event component_loaded[L]: component=nintendo_parental>

 tests/components/nintendo_parental/test_config_flow.py::test_invalid_api_token ⨯                                                                                                                                                                                           75% ███████▌  
 tests/components/nintendo_parental/test_config_flow.py::test_general_error ✓                                                                                                                                                                                              100% ██████████

---------- coverage: platform linux, python 3.13.3-final-0 -----------
Name                                                        Stmts   Miss  Cover   Missing
-----------------------------------------------------------------------------------------
homeassistant/components/nintendo_parental/__init__.py         22      7    68%   31-34, 39-41, 48
homeassistant/components/nintendo_parental/config_flow.py      27      1    96%   38
homeassistant/components/nintendo_parental/const.py             3      0   100%
homeassistant/components/nintendo_parental/coordinator.py      27      1    96%   60
homeassistant/components/nintendo_parental/entity.py           16     16     0%   3-34
homeassistant/components/nintendo_parental/sensor.py           33     33     0%   3-102
-----------------------------------------------------------------------------------------
TOTAL                                                         128     58    55%

================================================================================================================================ short test summary info =================================================================================================================================
FAILED tests/components/nintendo_parental/test_config_flow.py::test_invalid_api_token - AssertionError: assert <FlowResultType.CREATE_ENTRY: 'create_entry'> is <FlowResultType.FORM: 'form'>
 +  where <FlowResultType.FORM: 'form'> = FlowResultType.FORM

Results (1.69s):
       3 passed
       1 failed
         - tests/components/nintendo_parental/test_config_flow.py:65 test_invalid_api_token

Comment on lines +87 to +103
mock_request_handler.return_value = {
"status": 200,
"text": "OK",
"json": {
"session_token": "valid_token",
"expires_in": 3500,
"id": "aabbccddee112233",
"name": "Home Assistant Tester",
},
"headers": {"Content-Type": "application/json"},
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and to clear the exception...

        mock_authenticator_client.complete_login.side_effect = None

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As above

@home-assistant home-assistant bot marked this pull request as draft May 20, 2025 22:48
@home-assistant
Copy link

Please take a look at the requested changes, and use the Ready for review button when you are done, thanks 👍

Learn more about our pull request process.

@pantherale0
Copy link
Contributor Author

Thanks both for your reviews and feedback. I think we might be close now? Only thing left that is outstanding is regarding patching internals.

@pantherale0 pantherale0 marked this pull request as ready for review May 21, 2025 09:33
@home-assistant home-assistant bot requested review from tr4nt0r and joostlek May 21, 2025 09:33
@pantherale0
Copy link
Contributor Author

This can be marked as a draft again - adding some further tests and changing how the python module handles API calls so internals don't need to be patched (pantherale0/pynintendoparental#29)

@home-assistant home-assistant bot marked this pull request as draft May 21, 2025 20:50
@pantherale0 pantherale0 marked this pull request as ready for review May 22, 2025 09:28
@home-assistant home-assistant bot requested a review from joostlek May 22, 2025 09:28
pantherale0 and others added 25 commits May 22, 2025 11:46
Co-authored-by: Manu <4445816+tr4nt0r@users.noreply.github.com>
Co-authored-by: Manu <4445816+tr4nt0r@users.noreply.github.com>
Co-authored-by: Manu <4445816+tr4nt0r@users.noreply.github.com>
Co-authored-by: Manu <4445816+tr4nt0r@users.noreply.github.com>
Co-authored-by: Manu <4445816+tr4nt0r@users.noreply.github.com>
Co-authored-by: Manu <4445816+tr4nt0r@users.noreply.github.com>
Co-authored-by: Manu <4445816+tr4nt0r@users.noreply.github.com>
Co-authored-by: Manu <4445816+tr4nt0r@users.noreply.github.com>
Co-authored-by: Manu <4445816+tr4nt0r@users.noreply.github.com>
Co-authored-by: Manu <4445816+tr4nt0r@users.noreply.github.com>
Co-authored-by: Manu <4445816+tr4nt0r@users.noreply.github.com>
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
Co-authored-by: Joost Lekkerkerker <joostlek@outlook.com>
@pantherale0 pantherale0 force-pushed the integration/nintento_parental branch from 1ee9218 to 56ae08b Compare May 22, 2025 10:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy