10
10
import requests
11
11
from airbyte_cdk .models import AirbyteLogMessage , AirbyteMessage , AirbyteRecordMessage , Level , Type
12
12
from airbyte_cdk .sources .declarative .declarative_stream import DeclarativeStream
13
+ from airbyte_cdk .sources .declarative .parsers .undefined_reference_exception import UndefinedReferenceException
13
14
from airbyte_cdk .sources .streams .http import HttpStream
14
15
from connector_builder .impl .low_code_cdk_adapter import LowCodeSourceAdapter
15
16
@@ -18,6 +19,7 @@ class MockConcreteStream(HttpStream, ABC):
18
19
"""
19
20
Test class used to verify errors are correctly thrown when the adapter receives unexpected outputs
20
21
"""
22
+
21
23
def primary_key (self ) -> Optional [Union [str , List [str ], List [List [str ]]]]:
22
24
return None
23
25
@@ -94,6 +96,69 @@ def parse_response(
94
96
],
95
97
"check" : {"stream_names" : ["hashiras" ], "class_name" : "airbyte_cdk.sources.declarative.checks.check_stream.CheckStream" },
96
98
}
99
+
100
+ MANIFEST_WITH_REFERENCES = {
101
+ "version" : "0.1.0" ,
102
+ "definitions" : {
103
+ "selector" : {
104
+ "extractor" : {
105
+ "field_pointer" : []
106
+ }
107
+ },
108
+ "requester" : {
109
+ "url_base" : "https://demonslayers.com/api/v1/" ,
110
+ "http_method" : "GET" ,
111
+ "authenticator" : {
112
+ "type" : "BearerAuthenticator" ,
113
+ "api_token" : "{{ config['api_key'] }}"
114
+ }
115
+ },
116
+ "retriever" : {
117
+ "record_selector" : {
118
+ "$ref" : "*ref(definitions.selector)"
119
+ },
120
+ "paginator" : {
121
+ "type" : "NoPagination"
122
+ },
123
+ "requester" : {
124
+ "$ref" : "*ref(definitions.requester)"
125
+ }
126
+ },
127
+ "base_stream" : {
128
+ "retriever" : {
129
+ "$ref" : "*ref(definitions.retriever)"
130
+ }
131
+ },
132
+ "ranks_stream" : {
133
+ "$ref" : "*ref(definitions.base_stream)" ,
134
+ "$options" : {
135
+ "name" : "ranks" ,
136
+ "primary_key" : "id" ,
137
+ "path" : "/ranks"
138
+ }
139
+ }
140
+ },
141
+ "streams" : ["*ref(definitions.ranks_stream)" ],
142
+ "check" : {
143
+ "stream_names" : ["ranks" ]
144
+ },
145
+ "spec" : {
146
+ "documentation_url" : "https://docsurl.com" ,
147
+ "connection_specification" : {
148
+ "title" : "Source Name Spec" ,
149
+ "type" : "object" ,
150
+ "required" : ["api_key" ],
151
+ "additionalProperties" : True ,
152
+ "properties" : {
153
+ "api_key" : {
154
+ "type" : "string" ,
155
+ "description" : "API Key"
156
+ }
157
+ }
158
+ }
159
+ }
160
+ }
161
+
97
162
INVALID_MANIFEST = {
98
163
"version" : "0.1.0" ,
99
164
"definitions" : {
@@ -128,6 +193,17 @@ def test_get_http_streams():
128
193
assert actual_urls == expected_urls
129
194
130
195
196
+ def test_get_http_manifest_with_references ():
197
+ expected_urls = {"https://demonslayers.com/api/v1/ranks" }
198
+
199
+ adapter = LowCodeSourceAdapter (MANIFEST_WITH_REFERENCES )
200
+ actual_streams = adapter .get_http_streams (config = {})
201
+ actual_urls = {http_stream .url_base + http_stream .path () for http_stream in actual_streams }
202
+
203
+ assert len (actual_streams ) == len (expected_urls )
204
+ assert actual_urls == expected_urls
205
+
206
+
131
207
def test_get_http_streams_non_declarative_streams ():
132
208
non_declarative_stream = MockConcreteStream ()
133
209
@@ -141,7 +217,8 @@ def test_get_http_streams_non_declarative_streams():
141
217
142
218
143
219
def test_get_http_streams_non_http_stream ():
144
- declarative_stream_non_http_retriever = DeclarativeStream (name = "hashiras" , primary_key = "id" , retriever = MagicMock (), config = {}, options = {})
220
+ declarative_stream_non_http_retriever = DeclarativeStream (name = "hashiras" , primary_key = "id" , retriever = MagicMock (), config = {},
221
+ options = {})
145
222
146
223
mock_source = MagicMock ()
147
224
mock_source .streams .return_value = [declarative_stream_non_http_retriever ]
@@ -182,3 +259,31 @@ def test_read_streams():
182
259
183
260
for i , expected_message in enumerate (expected_messages ):
184
261
assert actual_messages [i ] == expected_message
262
+
263
+
264
+ def test_read_streams_invalid_reference ():
265
+ invalid_reference_manifest = {
266
+ "version" : "0.1.0" ,
267
+ "definitions" : {
268
+ "selector" : {
269
+ "extractor" : {
270
+ "field_pointer" : []
271
+ }
272
+ },
273
+ "ranks_stream" : {
274
+ "$ref" : "*ref(definitions.base_stream)" ,
275
+ "$options" : {
276
+ "name" : "ranks" ,
277
+ "primary_key" : "id" ,
278
+ "path" : "/ranks"
279
+ }
280
+ }
281
+ },
282
+ "streams" : ["*ref(definitions.ranks_stream)" ],
283
+ "check" : {
284
+ "stream_names" : ["ranks" ]
285
+ }
286
+ }
287
+
288
+ with pytest .raises (UndefinedReferenceException ):
289
+ LowCodeSourceAdapter (invalid_reference_manifest )
0 commit comments