File: test_clean_summary.py

package info (click to toggle)
python-roborock 4.12.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 2,480 kB
  • sloc: python: 16,602; makefile: 17; sh: 6
file content (223 lines) | stat: -rw-r--r-- 7,007 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
"""Tests for the CleanSummary class."""

from unittest.mock import AsyncMock, call

import pytest

from roborock.data import CleanSummary
from roborock.devices.device import RoborockDevice
from roborock.devices.traits.v1.clean_summary import CleanSummaryTrait
from roborock.exceptions import RoborockException
from roborock.roborock_typing import RoborockCommand
from tests.mock_data import CLEAN_RECORD

CLEAN_SUMMARY_DATA = [
    1442559,
    24258125000,
    296,
    [
        1756848207,
        1754930385,
        1753203976,
        1752183435,
        1747427370,
        1746204046,
        1745601543,
        1744387080,
        1743528522,
        1742489154,
        1741022299,
        1740433682,
        1739902516,
        1738875106,
        1738864366,
        1738620067,
        1736873889,
        1736197544,
        1736121269,
        1734458038,
    ],
]

CLEAN_RECORD_DATA = [
    [
        1738864366,
        1738868964,
        4358,
        81122500,
        0,
        0,
        1,
        1,
        21,
    ]
]


@pytest.fixture
def clean_summary_trait(device: RoborockDevice) -> CleanSummaryTrait:
    """Create a DoNotDisturbTrait instance with mocked dependencies."""
    assert device.v1_properties
    return device.v1_properties.clean_summary


@pytest.fixture
def sample_clean_summary() -> CleanSummary:
    """Create a sample CleanSummary for testing."""
    return CleanSummary(
        clean_area=100,
        clean_time=3600,
    )


async def test_get_clean_summary_success(
    clean_summary_trait: CleanSummaryTrait, mock_rpc_channel: AsyncMock, sample_clean_summary: CleanSummary
) -> None:
    """Test successfully getting clean summary."""
    # Setup mock to return the sample clean summary
    mock_rpc_channel.send_command.side_effect = [CLEAN_SUMMARY_DATA, CLEAN_RECORD_DATA]

    # Call the method
    await clean_summary_trait.refresh()

    # Verify the result
    assert clean_summary_trait.clean_area == 24258125000
    assert clean_summary_trait.clean_time == 1442559
    assert clean_summary_trait.square_meter_clean_area == 24258.1
    assert clean_summary_trait.clean_count == 296
    assert clean_summary_trait.records
    assert len(clean_summary_trait.records) == 20
    assert clean_summary_trait.records[0] == 1756848207
    assert clean_summary_trait.last_clean_record
    assert clean_summary_trait.last_clean_record.begin == 1738864366

    # Verify the RPC call was made correctly
    mock_rpc_channel.send_command.assert_has_calls(
        [call(RoborockCommand.GET_CLEAN_SUMMARY), call(RoborockCommand.GET_CLEAN_RECORD, params=[1756848207])]
    )


async def test_get_clean_summary_clean_time_only(
    clean_summary_trait: CleanSummaryTrait, mock_rpc_channel: AsyncMock, sample_clean_summary: CleanSummary
) -> None:
    """Test successfully getting clean summary where the response only has the clean time."""

    mock_rpc_channel.send_command.return_value = [1442559]

    # Call the method
    await clean_summary_trait.refresh()

    # Verify the result
    assert clean_summary_trait.clean_area is None
    assert clean_summary_trait.clean_time == 1442559
    assert clean_summary_trait.square_meter_clean_area is None
    assert clean_summary_trait.clean_count is None
    assert not clean_summary_trait.records

    # Verify the RPC call was made correctly
    mock_rpc_channel.send_command.assert_called_once_with(RoborockCommand.GET_CLEAN_SUMMARY)


async def test_get_clean_summary_propagates_exception(
    clean_summary_trait: CleanSummaryTrait, mock_rpc_channel: AsyncMock
) -> None:
    """Test that exceptions from RPC channel are propagated in get_clean_summary."""

    # Setup mock to raise an exception
    mock_rpc_channel.send_command.side_effect = RoborockException("Communication error")

    # Verify the exception is propagated
    with pytest.raises(RoborockException, match="Communication error"):
        await clean_summary_trait.refresh()


async def test_get_clean_record_success(
    clean_summary_trait: CleanSummaryTrait,
    mock_rpc_channel: AsyncMock,
) -> None:
    """Test successfully getting the last clean record."""
    # Setup mock to return the sample clean summary and clean record
    mock_rpc_channel.send_command.side_effect = [
        CLEAN_RECORD_DATA,
    ]

    # Call the method
    clean_record = await clean_summary_trait.get_clean_record(1738864366)

    # Verify the result
    assert clean_record.begin == 1738864366
    assert clean_record.end == 1738868964
    assert clean_record.duration == 4358
    assert clean_record.area == 81122500
    assert clean_record.complete is None
    assert clean_record.start_type is None
    assert clean_record.clean_type is None
    assert clean_record.finish_reason is None

    # Verify the RPC calls were made correctly
    mock_rpc_channel.send_command.assert_has_calls(
        [
            call(RoborockCommand.GET_CLEAN_RECORD, params=[1738864366]),
        ]
    )


async def test_get_clean_record_dict_response(
    clean_summary_trait: CleanSummaryTrait,
    mock_rpc_channel: AsyncMock,
) -> None:
    """Test successfully getting the last clean record as a dictionary."""
    # Setup mock to return the sample clean summary and clean record
    mock_rpc_channel.send_command.side_effect = [
        CLEAN_RECORD,
    ]

    # Call the method
    clean_record = await clean_summary_trait.get_clean_record(1738864366)

    # Verify the result
    assert clean_record.begin == 1672543330
    assert clean_record.end == 1672544638
    assert clean_record.duration == 1176
    assert clean_record.area == 20965000
    assert clean_record.complete == 1
    assert clean_record.start_type == 2
    assert clean_record.clean_type == 3
    assert clean_record.finish_reason == 56
    assert clean_record.dust_collection_status == 1
    assert clean_record.avoid_count == 19
    assert clean_record.wash_count == 2
    assert clean_record.map_flag == 0

    # Verify the RPC calls were made correctly
    mock_rpc_channel.send_command.assert_has_calls(
        [
            call(RoborockCommand.GET_CLEAN_RECORD, params=[1738864366]),
        ]
    )


async def test_get_clean_summary_no_records(
    clean_summary_trait: CleanSummaryTrait, mock_rpc_channel: AsyncMock
) -> None:
    """Test successfully getting clean summary with no records."""
    # Setup mock to return the sample clean summary with no records
    mock_rpc_channel.send_command.return_value = [
        1442559,
        24258125000,
        296,
        [],
    ]

    # Call the method
    await clean_summary_trait.refresh()

    # Verify the result
    assert clean_summary_trait.clean_area == 24258125000
    assert clean_summary_trait.clean_time == 1442559
    assert clean_summary_trait.clean_count == 296
    assert not clean_summary_trait.records
    assert clean_summary_trait.last_clean_record is None

    # Verify the RPC call was made correctly
    mock_rpc_channel.send_command.assert_called_once_with(RoborockCommand.GET_CLEAN_SUMMARY)