glean-indexing-sdk 0.0.3__tar.gz → 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/.cz.toml +1 -1
- {glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/PKG-INFO +1 -1
- {glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/pyproject.toml +1 -1
- {glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/src/glean/indexing/__init__.py +1 -1
- glean_indexing_sdk-0.1.0/src/glean/indexing/common/property_definition_builder.py +115 -0
- {glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/taskfile.yml +2 -0
- glean_indexing_sdk-0.1.0/tests/unit_tests/common/test_property_definition_builder.py +246 -0
- {glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/tests/unit_tests/test_base_people_connector.py +1 -1
- {glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/tests/unit_tests/test_custom_connector_integration.py +1 -1
- {glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/.env.template +0 -0
- {glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/.github/CODEOWNERS +0 -0
- {glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/.github/workflows/ci.yml +0 -0
- {glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/.github/workflows/publish.yml +0 -0
- {glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/.gitignore +0 -0
- {glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/.markdown-coderc.json +0 -0
- {glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/.python-version +0 -0
- {glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/.ruff.toml +0 -0
- {glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/.vscode/settings.json +0 -0
- {glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/CHANGELOG.md +0 -0
- {glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/CONTRIBUTING.md +0 -0
- {glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/LICENSE +0 -0
- {glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/README.md +0 -0
- {glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/RELEASE.md +0 -0
- {glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/env.template +0 -0
- {glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/mise.toml +0 -0
- {glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/snippets/non_streaming/complete.py +0 -0
- {glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/snippets/non_streaming/run_connector.py +0 -0
- {glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/snippets/non_streaming/wiki_connector.py +0 -0
- {glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/snippets/non_streaming/wiki_data_client.py +0 -0
- {glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/snippets/non_streaming/wiki_page_data.py +0 -0
- {glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/snippets/streaming/article_connector.py +0 -0
- {glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/snippets/streaming/article_data.py +0 -0
- {glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/snippets/streaming/article_data_client.py +0 -0
- {glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/snippets/streaming/run_connector.py +0 -0
- {glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/src/glean/indexing/common/__init__.py +0 -0
- {glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/src/glean/indexing/common/batch_processor.py +0 -0
- {glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/src/glean/indexing/common/content_formatter.py +0 -0
- {glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/src/glean/indexing/common/glean_client.py +0 -0
- {glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/src/glean/indexing/common/metrics.py +0 -0
- {glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/src/glean/indexing/common/mocks.py +0 -0
- {glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/src/glean/indexing/connectors/__init__.py +0 -0
- {glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/src/glean/indexing/connectors/base_connector.py +0 -0
- {glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/src/glean/indexing/connectors/base_data_client.py +0 -0
- {glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/src/glean/indexing/connectors/base_datasource_connector.py +0 -0
- {glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/src/glean/indexing/connectors/base_people_connector.py +0 -0
- {glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/src/glean/indexing/connectors/base_streaming_data_client.py +0 -0
- {glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/src/glean/indexing/connectors/base_streaming_datasource_connector.py +0 -0
- {glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/src/glean/indexing/models.py +0 -0
- {glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/src/glean/indexing/observability/__init__.py +0 -0
- {glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/src/glean/indexing/observability/observability.py +0 -0
- {glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/src/glean/indexing/py.typed +0 -0
- {glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/src/glean/indexing/testing/__init__.py +0 -0
- {glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/src/glean/indexing/testing/connector_test_harness.py +0 -0
- {glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/src/glean/indexing/testing/mock_data_source.py +0 -0
- {glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/src/glean/indexing/testing/mock_glean_client.py +0 -0
- {glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/src/glean/indexing/testing/response_validator.py +0 -0
- {glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/tests/__init__.py +0 -0
- {glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/tests/integration_tests/__init__.py +0 -0
- {glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/tests/unit_tests/__init__.py +0 -0
- {glean_indexing_sdk-0.0.3/tests/unit_tests/utils → glean_indexing_sdk-0.1.0/tests/unit_tests/common}/__init__.py +0 -0
- {glean_indexing_sdk-0.0.3/tests/unit_tests/utils → glean_indexing_sdk-0.1.0/tests/unit_tests/common}/mock_clients.py +0 -0
- {glean_indexing_sdk-0.0.3/tests/unit_tests/utils → glean_indexing_sdk-0.1.0/tests/unit_tests/common}/test_batch_processor.py +0 -0
- {glean_indexing_sdk-0.0.3/tests/unit_tests/utils → glean_indexing_sdk-0.1.0/tests/unit_tests/common}/test_content_formatter.py +0 -0
- {glean_indexing_sdk-0.0.3/tests/unit_tests/utils → glean_indexing_sdk-0.1.0/tests/unit_tests/common}/test_metrics.py +0 -0
- {glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/tests/unit_tests/test_base_connector.py +0 -0
- {glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/tests/unit_tests/test_base_data_client.py +0 -0
- {glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/tests/unit_tests/test_base_datasource_connector.py +0 -0
- {glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/tests/unit_tests/test_base_streaming_datasource_connector.py +0 -0
- {glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/uv.lock +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: glean-indexing-sdk
|
|
3
|
-
Version: 0.0
|
|
3
|
+
Version: 0.1.0
|
|
4
4
|
Summary: SDK for building custom Glean indexing integrations
|
|
5
5
|
Project-URL: Source Code, https://github.com/glean-io/glean-indexing-sdk
|
|
6
6
|
Author-email: Steve Calvert <steve.calvert@glean.com>
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "glean-indexing-sdk"
|
|
7
|
-
version = "0.0
|
|
7
|
+
version = "0.1.0"
|
|
8
8
|
description = "SDK for building custom Glean indexing integrations"
|
|
9
9
|
authors = [{ name = "Steve Calvert", email = "steve.calvert@glean.com" }]
|
|
10
10
|
readme = "README.md"
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
from typing import List, Optional
|
|
2
|
+
|
|
3
|
+
from glean.api_client.models.propertydefinition import PropertyDefinition, PropertyType, UIOptions
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class PropertyDefinitionBuilder:
|
|
7
|
+
"""
|
|
8
|
+
Builder class for creating PropertyDefinition objects with a fluent interface.
|
|
9
|
+
|
|
10
|
+
This class provides a convenient way to build multiple PropertyDefinition objects
|
|
11
|
+
with proper validation and type safety.
|
|
12
|
+
|
|
13
|
+
Example:
|
|
14
|
+
builder = PropertyDefinitionBuilder()
|
|
15
|
+
properties = (builder
|
|
16
|
+
.add_property("title", "Title", property_type=PropertyType.TEXT)
|
|
17
|
+
.add_property("author", "Author", display_label_plural="Authors")
|
|
18
|
+
.build())
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
def __init__(self) -> None:
|
|
22
|
+
self.properties: List[PropertyDefinition] = []
|
|
23
|
+
|
|
24
|
+
def add_property(
|
|
25
|
+
self,
|
|
26
|
+
name: str,
|
|
27
|
+
display_label: str,
|
|
28
|
+
display_label_plural: Optional[str] = None,
|
|
29
|
+
property_type: PropertyType = PropertyType.TEXT,
|
|
30
|
+
ui_options: UIOptions = UIOptions.SEARCH_RESULT,
|
|
31
|
+
hide_ui_facet: bool = False,
|
|
32
|
+
ui_facet_order: Optional[int] = None,
|
|
33
|
+
group: Optional[str] = None,
|
|
34
|
+
) -> "PropertyDefinitionBuilder":
|
|
35
|
+
"""
|
|
36
|
+
Add a property definition to the builder.
|
|
37
|
+
|
|
38
|
+
Args:
|
|
39
|
+
name: The property name (must not be empty)
|
|
40
|
+
display_label: The display label for the property
|
|
41
|
+
display_label_plural: Optional plural form of the display label
|
|
42
|
+
property_type: The type of property (defaults to TEXT)
|
|
43
|
+
ui_options: UI options for the property (defaults to SEARCH_RESULT)
|
|
44
|
+
hide_ui_facet: Whether to hide the UI facet
|
|
45
|
+
ui_facet_order: Optional order for UI facet display
|
|
46
|
+
group: Optional group name for the property
|
|
47
|
+
|
|
48
|
+
Returns:
|
|
49
|
+
Self for method chaining
|
|
50
|
+
|
|
51
|
+
Raises:
|
|
52
|
+
ValueError: If name or display_label is empty
|
|
53
|
+
"""
|
|
54
|
+
if not name or not name.strip():
|
|
55
|
+
raise ValueError("Property name cannot be empty")
|
|
56
|
+
if not display_label or not display_label.strip():
|
|
57
|
+
raise ValueError("Display label cannot be empty")
|
|
58
|
+
|
|
59
|
+
base_params = {
|
|
60
|
+
"name": name.strip(),
|
|
61
|
+
"display_label": display_label.strip(),
|
|
62
|
+
"property_type": property_type.value,
|
|
63
|
+
"ui_options": ui_options.value,
|
|
64
|
+
"hide_ui_facet": hide_ui_facet,
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
optional_params = {
|
|
68
|
+
k: v
|
|
69
|
+
for k, v in {
|
|
70
|
+
"display_label_plural": display_label_plural.strip()
|
|
71
|
+
if display_label_plural
|
|
72
|
+
else None,
|
|
73
|
+
"ui_facet_order": ui_facet_order,
|
|
74
|
+
"group": group.strip() if group else None,
|
|
75
|
+
}.items()
|
|
76
|
+
if v is not None
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
params = {**base_params, **optional_params}
|
|
80
|
+
|
|
81
|
+
try:
|
|
82
|
+
prop = PropertyDefinition(**params)
|
|
83
|
+
self.properties.append(prop)
|
|
84
|
+
except Exception as e:
|
|
85
|
+
raise ValueError(f"Failed to create PropertyDefinition: {e}") from e
|
|
86
|
+
|
|
87
|
+
return self
|
|
88
|
+
|
|
89
|
+
def clear(self) -> "PropertyDefinitionBuilder":
|
|
90
|
+
"""
|
|
91
|
+
Clear all properties from the builder.
|
|
92
|
+
|
|
93
|
+
Returns:
|
|
94
|
+
Self for method chaining
|
|
95
|
+
"""
|
|
96
|
+
self.properties.clear()
|
|
97
|
+
return self
|
|
98
|
+
|
|
99
|
+
def count(self) -> int:
|
|
100
|
+
"""
|
|
101
|
+
Get the number of properties currently in the builder.
|
|
102
|
+
|
|
103
|
+
Returns:
|
|
104
|
+
Number of properties
|
|
105
|
+
"""
|
|
106
|
+
return len(self.properties)
|
|
107
|
+
|
|
108
|
+
def build(self) -> List[PropertyDefinition]:
|
|
109
|
+
"""
|
|
110
|
+
Build and return the list of PropertyDefinition objects.
|
|
111
|
+
|
|
112
|
+
Returns:
|
|
113
|
+
List of PropertyDefinition objects
|
|
114
|
+
"""
|
|
115
|
+
return self.properties.copy()
|
|
@@ -178,11 +178,13 @@ tasks:
|
|
|
178
178
|
{{.PYRIGHT}} {{.PYTHON_FILES}}
|
|
179
179
|
fi
|
|
180
180
|
|
|
181
|
+
# Lint Readme task: Lint the README.md file
|
|
181
182
|
lint:readme:
|
|
182
183
|
desc: Lint the README.md file
|
|
183
184
|
cmds:
|
|
184
185
|
- npx -y markdown-code check
|
|
185
186
|
|
|
187
|
+
# Lint Readme fix task: Fix the README.md file
|
|
186
188
|
lint:readme:fix:
|
|
187
189
|
desc: Fix the README.md file
|
|
188
190
|
cmds:
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
|
|
3
|
+
from glean.api_client.models.propertydefinition import PropertyDefinition, PropertyType, UIOptions
|
|
4
|
+
from glean.indexing.common.property_definition_builder import PropertyDefinitionBuilder
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class TestPropertyDefinitionBuilder:
|
|
8
|
+
def test_basic_property_creation(self):
|
|
9
|
+
"""Test basic property creation with minimal parameters."""
|
|
10
|
+
builder = PropertyDefinitionBuilder()
|
|
11
|
+
properties = builder.add_property("test_name", "Test Label").build()
|
|
12
|
+
|
|
13
|
+
assert len(properties) == 1
|
|
14
|
+
prop = properties[0]
|
|
15
|
+
assert prop.name == "test_name"
|
|
16
|
+
assert prop.display_label == "Test Label"
|
|
17
|
+
assert prop.property_type == PropertyType.TEXT.value
|
|
18
|
+
assert prop.ui_options == UIOptions.SEARCH_RESULT.value
|
|
19
|
+
assert prop.hide_ui_facet is False
|
|
20
|
+
|
|
21
|
+
def test_property_creation_with_all_parameters(self):
|
|
22
|
+
"""Test property creation with all parameters specified."""
|
|
23
|
+
builder = PropertyDefinitionBuilder()
|
|
24
|
+
properties = builder.add_property(
|
|
25
|
+
name="full_test",
|
|
26
|
+
display_label="Full Test Label",
|
|
27
|
+
display_label_plural="Full Test Labels",
|
|
28
|
+
property_type=PropertyType.DATE,
|
|
29
|
+
ui_options=UIOptions.DOC_HOVERCARD,
|
|
30
|
+
hide_ui_facet=True,
|
|
31
|
+
ui_facet_order=5,
|
|
32
|
+
group="test_group",
|
|
33
|
+
).build()
|
|
34
|
+
|
|
35
|
+
assert len(properties) == 1
|
|
36
|
+
prop = properties[0]
|
|
37
|
+
assert prop.name == "full_test"
|
|
38
|
+
assert prop.display_label == "Full Test Label"
|
|
39
|
+
assert prop.display_label_plural == "Full Test Labels"
|
|
40
|
+
assert prop.property_type == PropertyType.DATE.value
|
|
41
|
+
assert prop.ui_options == UIOptions.DOC_HOVERCARD.value
|
|
42
|
+
assert prop.hide_ui_facet is True
|
|
43
|
+
assert prop.ui_facet_order == 5
|
|
44
|
+
assert prop.group == "test_group"
|
|
45
|
+
|
|
46
|
+
def test_enum_value_conversion(self):
|
|
47
|
+
"""Test that enum objects are properly converted to string values."""
|
|
48
|
+
builder = PropertyDefinitionBuilder()
|
|
49
|
+
properties = builder.add_property(
|
|
50
|
+
"enum_test",
|
|
51
|
+
"Enum Test",
|
|
52
|
+
property_type=PropertyType.INT,
|
|
53
|
+
ui_options=UIOptions.SEARCH_RESULT,
|
|
54
|
+
).build()
|
|
55
|
+
|
|
56
|
+
prop = properties[0]
|
|
57
|
+
assert isinstance(prop.property_type, str)
|
|
58
|
+
assert isinstance(prop.ui_options, str)
|
|
59
|
+
assert prop.property_type == PropertyType.INT.value
|
|
60
|
+
assert prop.ui_options == UIOptions.SEARCH_RESULT.value
|
|
61
|
+
|
|
62
|
+
def test_method_chaining(self):
|
|
63
|
+
"""Test that the builder supports method chaining."""
|
|
64
|
+
builder = PropertyDefinitionBuilder()
|
|
65
|
+
properties = (
|
|
66
|
+
builder.add_property("prop1", "Property 1")
|
|
67
|
+
.add_property("prop2", "Property 2", property_type=PropertyType.USERID)
|
|
68
|
+
.add_property("prop3", "Property 3", ui_options=UIOptions.DOC_HOVERCARD)
|
|
69
|
+
.build()
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
assert len(properties) == 3
|
|
73
|
+
assert properties[0].name == "prop1"
|
|
74
|
+
assert properties[1].name == "prop2"
|
|
75
|
+
assert properties[1].property_type == PropertyType.USERID.value
|
|
76
|
+
assert properties[2].name == "prop3"
|
|
77
|
+
assert properties[2].ui_options == UIOptions.DOC_HOVERCARD.value
|
|
78
|
+
|
|
79
|
+
def test_optional_parameters_none_handling(self):
|
|
80
|
+
"""Test that None values for optional parameters are properly handled."""
|
|
81
|
+
builder = PropertyDefinitionBuilder()
|
|
82
|
+
properties = builder.add_property(
|
|
83
|
+
"optional_test",
|
|
84
|
+
"Optional Test",
|
|
85
|
+
display_label_plural=None,
|
|
86
|
+
ui_facet_order=None,
|
|
87
|
+
group=None,
|
|
88
|
+
).build()
|
|
89
|
+
|
|
90
|
+
prop = properties[0]
|
|
91
|
+
assert not hasattr(prop, "display_label_plural") or prop.display_label_plural is None
|
|
92
|
+
assert not hasattr(prop, "ui_facet_order") or prop.ui_facet_order is None
|
|
93
|
+
assert not hasattr(prop, "group") or prop.group is None
|
|
94
|
+
|
|
95
|
+
def test_string_trimming(self):
|
|
96
|
+
"""Test that string parameters are properly trimmed."""
|
|
97
|
+
builder = PropertyDefinitionBuilder()
|
|
98
|
+
properties = builder.add_property(
|
|
99
|
+
" trimmed_name ",
|
|
100
|
+
" Trimmed Label ",
|
|
101
|
+
display_label_plural=" Trimmed Plural ",
|
|
102
|
+
group=" trimmed_group ",
|
|
103
|
+
).build()
|
|
104
|
+
|
|
105
|
+
prop = properties[0]
|
|
106
|
+
assert prop.name == "trimmed_name"
|
|
107
|
+
assert prop.display_label == "Trimmed Label"
|
|
108
|
+
assert prop.display_label_plural == "Trimmed Plural"
|
|
109
|
+
assert prop.group == "trimmed_group"
|
|
110
|
+
|
|
111
|
+
def test_empty_name_validation(self):
|
|
112
|
+
"""Test that empty or whitespace-only names raise ValueError."""
|
|
113
|
+
builder = PropertyDefinitionBuilder()
|
|
114
|
+
|
|
115
|
+
with pytest.raises(ValueError, match="Property name cannot be empty"):
|
|
116
|
+
builder.add_property("", "Valid Label")
|
|
117
|
+
|
|
118
|
+
with pytest.raises(ValueError, match="Property name cannot be empty"):
|
|
119
|
+
builder.add_property(" ", "Valid Label")
|
|
120
|
+
|
|
121
|
+
def test_empty_display_label_validation(self):
|
|
122
|
+
"""Test that empty or whitespace-only display labels raise ValueError."""
|
|
123
|
+
builder = PropertyDefinitionBuilder()
|
|
124
|
+
|
|
125
|
+
with pytest.raises(ValueError, match="Display label cannot be empty"):
|
|
126
|
+
builder.add_property("valid_name", "")
|
|
127
|
+
|
|
128
|
+
with pytest.raises(ValueError, match="Display label cannot be empty"):
|
|
129
|
+
builder.add_property("valid_name", " ")
|
|
130
|
+
|
|
131
|
+
def test_property_definition_creation_error_handling(self):
|
|
132
|
+
"""Test error handling when PropertyDefinition creation fails."""
|
|
133
|
+
builder = PropertyDefinitionBuilder()
|
|
134
|
+
|
|
135
|
+
with pytest.raises(ValueError, match="Property name cannot be empty"):
|
|
136
|
+
builder.add_property(None, "Test Label") # type: ignore
|
|
137
|
+
|
|
138
|
+
def test_clear_method(self):
|
|
139
|
+
"""Test that clear method removes all properties and supports chaining."""
|
|
140
|
+
builder = PropertyDefinitionBuilder()
|
|
141
|
+
builder.add_property("prop1", "Property 1")
|
|
142
|
+
builder.add_property("prop2", "Property 2")
|
|
143
|
+
|
|
144
|
+
assert builder.count() == 2
|
|
145
|
+
|
|
146
|
+
result = builder.clear()
|
|
147
|
+
assert result is builder
|
|
148
|
+
assert builder.count() == 0
|
|
149
|
+
assert len(builder.build()) == 0
|
|
150
|
+
|
|
151
|
+
def test_count_method(self):
|
|
152
|
+
"""Test that count method returns the correct number of properties."""
|
|
153
|
+
builder = PropertyDefinitionBuilder()
|
|
154
|
+
|
|
155
|
+
assert builder.count() == 0
|
|
156
|
+
|
|
157
|
+
builder.add_property("prop1", "Property 1")
|
|
158
|
+
assert builder.count() == 1
|
|
159
|
+
|
|
160
|
+
builder.add_property("prop2", "Property 2")
|
|
161
|
+
assert builder.count() == 2
|
|
162
|
+
|
|
163
|
+
builder.clear()
|
|
164
|
+
assert builder.count() == 0
|
|
165
|
+
|
|
166
|
+
def test_build_returns_copy(self):
|
|
167
|
+
"""Test that build returns a copy, not the original list."""
|
|
168
|
+
builder = PropertyDefinitionBuilder()
|
|
169
|
+
builder.add_property("prop1", "Property 1")
|
|
170
|
+
|
|
171
|
+
properties1 = builder.build()
|
|
172
|
+
properties2 = builder.build()
|
|
173
|
+
|
|
174
|
+
assert properties1 is not properties2
|
|
175
|
+
assert properties1 == properties2
|
|
176
|
+
|
|
177
|
+
properties1.append("fake_property") # type: ignore
|
|
178
|
+
assert len(properties2) == 1
|
|
179
|
+
|
|
180
|
+
def test_empty_builder_build(self):
|
|
181
|
+
"""Test that building an empty builder returns an empty list."""
|
|
182
|
+
builder = PropertyDefinitionBuilder()
|
|
183
|
+
properties = builder.build()
|
|
184
|
+
|
|
185
|
+
assert isinstance(properties, list)
|
|
186
|
+
assert len(properties) == 0
|
|
187
|
+
|
|
188
|
+
def test_all_property_types(self):
|
|
189
|
+
"""Test that all PropertyType enum values work correctly."""
|
|
190
|
+
builder = PropertyDefinitionBuilder()
|
|
191
|
+
|
|
192
|
+
property_types = [
|
|
193
|
+
PropertyType.TEXT,
|
|
194
|
+
PropertyType.USERID,
|
|
195
|
+
PropertyType.INT,
|
|
196
|
+
]
|
|
197
|
+
|
|
198
|
+
for i, prop_type in enumerate(property_types):
|
|
199
|
+
builder.add_property(f"prop_{i}", f"Property {i}", property_type=prop_type)
|
|
200
|
+
|
|
201
|
+
properties = builder.build()
|
|
202
|
+
assert len(properties) == len(property_types)
|
|
203
|
+
|
|
204
|
+
for i, prop in enumerate(properties):
|
|
205
|
+
assert prop.property_type == property_types[i].value
|
|
206
|
+
|
|
207
|
+
def test_all_ui_options(self):
|
|
208
|
+
"""Test that all UIOptions enum values work correctly."""
|
|
209
|
+
builder = PropertyDefinitionBuilder()
|
|
210
|
+
|
|
211
|
+
ui_options = [
|
|
212
|
+
UIOptions.SEARCH_RESULT,
|
|
213
|
+
UIOptions.DOC_HOVERCARD,
|
|
214
|
+
]
|
|
215
|
+
|
|
216
|
+
for i, ui_option in enumerate(ui_options):
|
|
217
|
+
builder.add_property(f"prop_{i}", f"Property {i}", ui_options=ui_option)
|
|
218
|
+
|
|
219
|
+
properties = builder.build()
|
|
220
|
+
assert len(properties) == len(ui_options)
|
|
221
|
+
|
|
222
|
+
for i, prop in enumerate(properties):
|
|
223
|
+
assert prop.ui_options == ui_options[i].value
|
|
224
|
+
|
|
225
|
+
def test_complex_workflow(self):
|
|
226
|
+
"""Test a complex workflow with multiple operations."""
|
|
227
|
+
builder = PropertyDefinitionBuilder()
|
|
228
|
+
|
|
229
|
+
builder.add_property("title", "Title", property_type=PropertyType.TEXT)
|
|
230
|
+
builder.add_property("author", "Author", display_label_plural="Authors")
|
|
231
|
+
assert builder.count() == 2
|
|
232
|
+
|
|
233
|
+
builder.clear()
|
|
234
|
+
assert builder.count() == 0
|
|
235
|
+
|
|
236
|
+
properties = (
|
|
237
|
+
builder.add_property("name", "Full Name", group="personal")
|
|
238
|
+
.add_property("email", "Email Address", property_type=PropertyType.TEXT)
|
|
239
|
+
.add_property("department", "Department", ui_options=UIOptions.DOC_HOVERCARD)
|
|
240
|
+
.build()
|
|
241
|
+
)
|
|
242
|
+
|
|
243
|
+
assert len(properties) == 3
|
|
244
|
+
assert all(isinstance(prop, PropertyDefinition) for prop in properties)
|
|
245
|
+
assert properties[0].group == "personal"
|
|
246
|
+
assert properties[2].ui_options == UIOptions.DOC_HOVERCARD.value
|
{glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/tests/unit_tests/test_base_people_connector.py
RENAMED
|
@@ -4,7 +4,7 @@ import pytest
|
|
|
4
4
|
|
|
5
5
|
from glean.api_client.models import EmployeeInfoDefinition
|
|
6
6
|
from glean.indexing.connectors.base_people_connector import BasePeopleConnector
|
|
7
|
-
from tests.unit_tests.
|
|
7
|
+
from tests.unit_tests.common.mock_clients import MockPeopleClient
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
class DummyPeopleConnector(BasePeopleConnector[dict]):
|
|
@@ -11,7 +11,7 @@ from glean.api_client.models.customdatasourceconfig import (
|
|
|
11
11
|
from glean.api_client.models.documentdefinition import DocumentDefinition
|
|
12
12
|
from glean.api_client.models.userreferencedefinition import UserReferenceDefinition
|
|
13
13
|
from glean.indexing.connectors import BaseDataClient, BaseDatasourceConnector
|
|
14
|
-
from tests.unit_tests.
|
|
14
|
+
from tests.unit_tests.common.mock_clients import MockDataSourceClient
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
class CustomDatasourceConnector(BaseDatasourceConnector[dict]):
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/snippets/non_streaming/run_connector.py
RENAMED
|
File without changes
|
{glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/snippets/non_streaming/wiki_connector.py
RENAMED
|
File without changes
|
{glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/snippets/non_streaming/wiki_data_client.py
RENAMED
|
File without changes
|
{glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/snippets/non_streaming/wiki_page_data.py
RENAMED
|
File without changes
|
{glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/snippets/streaming/article_connector.py
RENAMED
|
File without changes
|
|
File without changes
|
{glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/snippets/streaming/article_data_client.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/src/glean/indexing/common/batch_processor.py
RENAMED
|
File without changes
|
{glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/src/glean/indexing/common/content_formatter.py
RENAMED
|
File without changes
|
{glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/src/glean/indexing/common/glean_client.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/src/glean/indexing/connectors/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/src/glean/indexing/observability/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/src/glean/indexing/testing/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/src/glean/indexing/testing/mock_data_source.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/tests/unit_tests/test_base_connector.py
RENAMED
|
File without changes
|
{glean_indexing_sdk-0.0.3 → glean_indexing_sdk-0.1.0}/tests/unit_tests/test_base_data_client.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|