Skip to content

Commit b58fa6c

Browse files
committed
Add tests and prove there's a bug in translate_state
1 parent 67bad82 commit b58fa6c

File tree

2 files changed

+148
-6
lines changed

2 files changed

+148
-6
lines changed

tap_github/sync.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -119,16 +119,17 @@ def translate_state(state, catalog, repositories):
119119

120120
for key in previous_state_keys:
121121
# Loop through each key of `bookmarks` available in the previous state.
122-
for inner_key in state['bookmarks'][key].keys():
123-
if inner_key not in stream_names and inner_key not in repositories:
124-
# Return the existing state if all repos from the previous state are deselected(not found) in the current sync.
125-
return state
122+
for inner_key, inner_value in state['bookmarks'][key].items():
123+
if inner_key in stream_names:
124+
new_state['bookmarks'][inner_key][key] = inner_value
125+
else:
126+
new_state['bookmarks'][key][inner_key] = inner_value
126127

127128
for stream in catalog['streams']:
128129
stream_name = stream['tap_stream_id']
129130
for repo in repositories:
130131
if bookmarks.get_bookmark(state, stream_name, repo):
131-
return state
132+
new_state['bookmarks'][stream_name][repo] = bookmarks.get_bookmark(state, stream_name, repo)
132133
if bookmarks.get_bookmark(state, repo, stream_name):
133134
new_state['bookmarks'][stream_name][repo] = bookmarks.get_bookmark(state, repo, stream_name)
134135

tests/unittests/test_sync.py

Lines changed: 142 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import unittest
22
from unittest import mock
3-
from tap_github.sync import sync, write_schemas
3+
from tap_github.sync import sync, write_schemas, translate_state
44

55

66

@@ -152,3 +152,144 @@ def test_no_streams_selected(self, mock_update_curr_sync, mock_selected_streams,
152152
# def test_nested_child_selected(self, mock_write_schema):
153153
# write_schemas("project_cards", self.mock_catalog, ["project_cards"])
154154
# mock_write_schema.assert_called_with("project_cards", mock.ANY, mock.ANY)
155+
156+
157+
class TestTranslateState(unittest.TestCase):
158+
"""Tests for `translate_state`
159+
160+
There are many combinations of test cases due to:
161+
- 2 versions of the state structure
162+
- "Old style" repo-stream
163+
- "New style" stream-repo
164+
- 4 possibilities of a stream being in/not-in state and catalog
165+
- Yes in state, Yes in catalog
166+
- Yes in state, Not in catalog
167+
- Not in state, Yes in catalog
168+
- Not in state, Not in catalog
169+
- 2 possibilities of a repo being in/not-in state
170+
- repo in state
171+
- repo not in state
172+
"""
173+
174+
def test_repo_stream_state_is_translated(self):
175+
state = {
176+
"bookmarks": {
177+
"singer-io/tap-adwords": {
178+
"commits": {
179+
"since": "2018-11-14T13:21:20.700360Z"
180+
}
181+
},
182+
"singer-io/tap-salesforce": {
183+
"commits": {
184+
"since": "2018-11-14T13:21:20.700360Z"
185+
}
186+
}
187+
}
188+
}
189+
190+
catalog = {"streams": [{"tap_stream_id": "commits"}]}
191+
repos = ["singer-io/tap-adwords"]
192+
193+
actual = translate_state(state, catalog, repos)
194+
expected = {
195+
"bookmarks": {
196+
"commits": {
197+
"singer-io/tap-adwords": {
198+
"since": "2018-11-14T13:21:20.700360Z"
199+
},
200+
"singer-io/tap-salesforce": {
201+
"since": "2018-11-14T13:21:20.700360Z"
202+
}
203+
}
204+
}
205+
}
206+
207+
assert actual == expected
208+
209+
def test_stream_repo_state_is_not_translated(self):
210+
state = {
211+
"bookmarks": {
212+
"commits": {
213+
"singer-io/tap-adwords": {
214+
"since": "2018-11-14T13:21:20.700360Z"
215+
},
216+
"singer-io/tap-salesforce": {
217+
"since": "2018-11-14T13:21:20.700360Z"
218+
}
219+
}
220+
}
221+
}
222+
catalog = {"streams": [{"tap_stream_id": "commits"}]}
223+
repos = ["singer-io/tap-adwords"]
224+
225+
actual = translate_state(state, catalog, repos)
226+
expected = {
227+
"bookmarks": {
228+
"commits": {
229+
"singer-io/tap-adwords": {
230+
"since": "2018-11-14T13:21:20.700360Z"
231+
},
232+
"singer-io/tap-salesforce": {
233+
"since": "2018-11-14T13:21:20.700360Z"
234+
}
235+
}
236+
}
237+
}
238+
239+
assert actual == expected
240+
241+
def test_stream_repo_state_and_not_selected_is_not_translated(self):
242+
state = {
243+
"bookmarks": {
244+
"commits": {
245+
"singer-io/tap-adwords": {
246+
"since": "2018-11-14T13:21:20.700360Z"
247+
},
248+
"singer-io/tap-salesforce": {
249+
"since": "2018-11-14T13:21:20.700360Z"
250+
}
251+
}
252+
}
253+
}
254+
catalog = {"streams": [{"tap_stream_id": "issues"}]}
255+
repos = ["singer-io/tap-adwords"]
256+
257+
actual = translate_state(state, catalog, repos)
258+
expected = {
259+
"bookmarks": {
260+
"commits": {
261+
"singer-io/tap-adwords": {
262+
"since": "2018-11-14T13:21:20.700360Z"
263+
},
264+
"singer-io/tap-salesforce": {
265+
"since": "2018-11-14T13:21:20.700360Z"
266+
}
267+
}
268+
}
269+
}
270+
assert actual == expected
271+
272+
def test_real_sceanario(self):
273+
state = {
274+
"bookmarks": {
275+
"issue_events": {
276+
"singer-io/tap-github": {
277+
"since": "2025-09-24T13:50:18Z"
278+
}
279+
}
280+
}
281+
}
282+
283+
catalog = {"streams": [{"tap_stream_id": "commits"}]}
284+
repos = ["singer-io/tap-github"]
285+
actual = translate_state(state, catalog, repos)
286+
expected = {
287+
"bookmarks": {
288+
"issue_events": {
289+
"singer-io/tap-github": {
290+
"since": "2025-09-24T13:50:18Z"
291+
}
292+
}
293+
}
294+
}
295+
assert actual == expected

0 commit comments

Comments
 (0)