-
Notifications
You must be signed in to change notification settings - Fork 48
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
JIRA: QA-23477 risk: nonprod
- Loading branch information
Showing
15 changed files
with
456 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
3.12.4 | ||
3.11.4 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
# (C) 2024 GoodData Corporation | ||
# env.py | ||
import os | ||
|
||
# Define environment variables | ||
HOST = os.getenv("GOODDATA_HOST", "https://checklist.staging.stg11.panther.intgdc.com") | ||
TOKEN = os.getenv("GOODDATA_TOKEN", "<your token>") | ||
DATASOURCE_ID = os.getenv("DATASOURCE_ID", "your datasource") | ||
WORKSPACE_ID = "your workspace" |
30 changes: 30 additions & 0 deletions
30
gooddata-sdk/integration_tests/data_response/column_total_returns_by_month.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
{ | ||
"id": "total_returns_per_month", | ||
"title": "Total Returns per Month", | ||
"visualizationType": "COLUMN", | ||
"metrics": [ | ||
{ | ||
"id": "total_returns", | ||
"type": "metric", | ||
"title": "Total Returns" | ||
} | ||
], | ||
"dimensionality": [ | ||
{ | ||
"id": "return_date.month", | ||
"type": "attribute", | ||
"title": "Return date - Month/Year" | ||
} | ||
], | ||
"filters": [], | ||
"suggestions": [ | ||
{ | ||
"query": "Switch to a line chart to better visualize the trend of total returns over the months.", | ||
"label": "Line Chart for Trends" | ||
}, | ||
{ | ||
"query": "Filter the data to show total returns for this year only.", | ||
"label": "This Year's Returns" | ||
} | ||
] | ||
} |
33 changes: 33 additions & 0 deletions
33
...dk/integration_tests/data_response/column_total_returns_by_month_filter_current_year.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
{ | ||
"id": "total_returns_per_month_current_year", | ||
"title": "Total Returns Per Month - Current Year", | ||
"visualizationType": "COLUMN", | ||
"metrics": [ | ||
{ | ||
"id": "total_returns", | ||
"type": "metric", | ||
"title": "Total Returns" | ||
} | ||
], | ||
"dimensionality": [ | ||
{ | ||
"id": "return_date.month", | ||
"type": "attribute", | ||
"title": "Return date - Month/Year" | ||
} | ||
], | ||
"filters": [ | ||
{ | ||
"using": "return_date", | ||
"granularity": "YEAR", | ||
"_from": 0, | ||
"to": 0 | ||
} | ||
], | ||
"suggestions": [ | ||
{ | ||
"query": "Switch to a line chart to better represent the trend of total returns over months.", | ||
"label": "Show Line Chart Trend" | ||
} | ||
] | ||
} |
33 changes: 33 additions & 0 deletions
33
...dk/integration_tests/data_response/line_total_customers_by_month_filter_current_year.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
{ | ||
"id": "total_customers_per_month_current_year", | ||
"title": "Total Customers per Month - Current Year", | ||
"visualizationType": "LINE", | ||
"metrics": [ | ||
{ | ||
"id": "total_customers", | ||
"type": "metric", | ||
"title": "Total Customers" | ||
} | ||
], | ||
"dimensionality": [ | ||
{ | ||
"id": "date.month", | ||
"type": "attribute", | ||
"title": "Date - Month/Year" | ||
} | ||
], | ||
"filters": [ | ||
{ | ||
"using": "date", | ||
"granularity": "YEAR", | ||
"_from": 0, | ||
"to": 0 | ||
} | ||
], | ||
"suggestions": [ | ||
{ | ||
"query": "Consider switching to a COLUMN chart for clearer comparisons of Total Customers per month.", | ||
"label": "Switch to COLUMN chart" | ||
} | ||
] | ||
} |
33 changes: 33 additions & 0 deletions
33
...-sdk/integration_tests/data_response/line_total_returns_by_month_filter_current_year.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
{ | ||
"id": "total_returns_per_month_current_year", | ||
"title": "Total Returns Per Month - Current Year", | ||
"visualizationType": "LINE", | ||
"metrics": [ | ||
{ | ||
"id": "total_returns", | ||
"type": "metric", | ||
"title": "Total Returns" | ||
} | ||
], | ||
"dimensionality": [ | ||
{ | ||
"id": "return_date.month", | ||
"type": "attribute", | ||
"title": "Return date - Month/Year" | ||
} | ||
], | ||
"filters": [ | ||
{ | ||
"using": "return_date", | ||
"granularity": "YEAR", | ||
"_from": 0, | ||
"to": 0 | ||
} | ||
], | ||
"suggestions": [ | ||
{ | ||
"query": "Switch to a line chart to better represent the trend of total returns over months.", | ||
"label": "Show Line Chart Trend" | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
[ | ||
{ | ||
"question": "What is total returns per month? show as COLUMN chart", | ||
"expected_objects_file": "column_total_returns_by_month.json" | ||
}, | ||
{ | ||
"question": "Add filter by current year, show as COLUMN chart", | ||
"expected_objects_file": "column_total_returns_by_month_filter_current_year.json" | ||
}, | ||
{ | ||
"question": "Switch to LINE chart", | ||
"expected_objects_file": "line_total_returns_by_month_filter_current_year.json" | ||
}, | ||
{ | ||
"question": "Replace metric Total Customers instead of total returns", | ||
"expected_objects_file": "line_total_customers_by_month_filter_current_year.json" | ||
} | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
# (C) 2024 GoodData Corporation | ||
import os | ||
import sys | ||
|
||
import gooddata_api_client | ||
import pytest | ||
from gooddata_api_client.api import smart_functions_api | ||
from gooddata_api_client.model.chat_history_request import ChatHistoryRequest | ||
from gooddata_api_client.model.chat_history_result import ChatHistoryResult | ||
from gooddata_api_client.model.chat_request import ChatRequest | ||
from utils import load_json, normalize_metrics | ||
|
||
sys.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) | ||
|
||
from env import WORKSPACE_ID | ||
|
||
EXPECTED_OBJECTS_DIR = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "data_response") | ||
QUESTIONS_DIR = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "fixtures") | ||
|
||
questions_list = load_json(os.path.join(QUESTIONS_DIR, "ai_questions.json")) | ||
|
||
|
||
class gooddataAiChatApp: | ||
def __init__(self, api_client, workspace_id): | ||
self.api_instance = smart_functions_api.SmartFunctionsApi(api_client) | ||
self.workspace_id = workspace_id | ||
|
||
async def ask_question(self, question: str): | ||
return self.api_instance.ai_chat(self.workspace_id, ChatRequest(question=question)) | ||
|
||
async def chat_history(self, interaction_id: int, feedback: str): | ||
return self.api_instance.ai_chat_history( | ||
self.workspace_id, ChatHistoryRequest(chat_history_interaction_id=interaction_id, user_feedback=feedback) | ||
) | ||
|
||
|
||
def validate_response(actual_response, expected_response): | ||
actual_metrics = normalize_metrics( | ||
actual_response["created_visualizations"]["objects"][0]["metrics"], exclude_keys=["title"] | ||
) | ||
expected_metrics = normalize_metrics(expected_response["metrics"], exclude_keys=["title"]) | ||
assert actual_metrics == expected_metrics, "Metrics do not match" | ||
assert ( | ||
actual_response["created_visualizations"]["objects"][0]["visualization_type"] | ||
== expected_response["visualizationType"] | ||
), "Visualization type mismatch" | ||
assert ( | ||
actual_response["created_visualizations"]["objects"][0]["dimensionality"] == expected_response["dimensionality"] | ||
), "Dimensionality mismatch" | ||
assert ( | ||
actual_response["created_visualizations"]["objects"][0]["filters"] == expected_response["filters"] | ||
), "Filters mismatch" | ||
|
||
|
||
@pytest.fixture(scope="module") | ||
def app(set_authorization_header): # Using the global fixture for Authorization header | ||
app_instance = gooddataAiChatApp(set_authorization_header, WORKSPACE_ID) | ||
return app_instance | ||
|
||
|
||
@pytest.mark.parametrize( | ||
"question, expected_file", | ||
[(item["question"], item["expected_objects_file"]) for item in questions_list], | ||
ids=[item["question"] for item in questions_list], | ||
) | ||
@pytest.mark.asyncio | ||
async def test_ai_chat(app, question, expected_file): | ||
expected_objects = load_json(os.path.join(EXPECTED_OBJECTS_DIR, expected_file)) | ||
try: | ||
api_response = await app.ask_question(question) | ||
validate_response(api_response.to_dict(), expected_objects) | ||
|
||
interaction_id = api_response.chat_history_interaction_id | ||
user_feedback = await app.chat_history(interaction_id, "POSITIVE") | ||
assert isinstance(user_feedback, ChatHistoryResult), "Invalid response from chat history" | ||
except gooddata_api_client.ApiException as e: | ||
pytest.fail(f"API exception: {e}") | ||
except Exception as e: | ||
pytest.fail(f"Unexpected error: {e}") | ||
|
||
|
||
if __name__ == "__main__": | ||
pytest.main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
# (C) 2024 GoodData Corporation | ||
import os | ||
import sys | ||
|
||
import pytest | ||
|
||
# Add the root directory to sys.path | ||
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) | ||
|
||
from env import HOST, TOKEN, WORKSPACE_ID | ||
from gooddata_sdk import GoodDataSdk | ||
|
||
|
||
@pytest.fixture | ||
def test_config(): | ||
return {"host": HOST, "token": TOKEN, "workspace_id": WORKSPACE_ID} | ||
|
||
|
||
questions = [ | ||
"What is the number of Accounts?", | ||
"What is the total of Amount?", | ||
] | ||
|
||
|
||
@pytest.mark.parametrize("question", questions) | ||
def test_ask_ai(test_config, question): | ||
sdk = GoodDataSdk.create(host_=test_config["host"], token_=test_config["token"]) | ||
workspace_id = test_config["workspace_id"] | ||
chat_ai_res = sdk.compute.ai_chat(workspace_id, question=question) | ||
|
||
print(f"Chat AI response: {chat_ai_res}") | ||
assert chat_ai_res is not None, "Response should not be None" | ||
|
||
|
||
if __name__ == "__main__": | ||
pytest.main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
# (C) 2024 GoodData Corporation | ||
|
||
import os | ||
import sys | ||
|
||
import pytest | ||
from env import HOST, TOKEN | ||
from gooddata_api_client import ApiClient, Configuration | ||
|
||
# Add the root directory to the Python path | ||
ROOT_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) | ||
sys.path.append(ROOT_DIR) | ||
|
||
|
||
@pytest.fixture(scope="session", autouse=True) | ||
def set_authorization_header(): | ||
""" | ||
Fixture to set the Authorization header globally for all tests. | ||
""" | ||
configuration = Configuration(host=HOST) | ||
configuration.access_token = TOKEN | ||
api_client = ApiClient(configuration) | ||
api_client.default_headers["Authorization"] = f"Bearer {TOKEN}" | ||
yield api_client | ||
# Cleanup after the tests, if necessary (e.g., closing client) | ||
api_client.close() |
16 changes: 16 additions & 0 deletions
16
gooddata-sdk/integration_tests/scripts/create_ref_workspace.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
# (C) 2024 GoodData Corporation | ||
from env import DATASOURCE_ID, HOST, TOKEN, WORKSPACE_ID | ||
from workspace_manager import createWorkspace, getDataSource, update_env_file | ||
|
||
if __name__ == "__main__": | ||
test_config = {"host": HOST, "token": TOKEN} | ||
|
||
if WORKSPACE_ID: | ||
print(f"Workspace ID '{WORKSPACE_ID}' already exists. Skipping workspace creation.") | ||
else: | ||
workspace_id = createWorkspace(test_config) | ||
dataSource = getDataSource(DATASOURCE_ID, test_config) | ||
if workspace_id: | ||
update_env_file(workspace_id) | ||
else: | ||
print("Failed to create workspace.") |
8 changes: 8 additions & 0 deletions
8
gooddata-sdk/integration_tests/scripts/delete_ref_workspace.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
# (C) 2024 GoodData Corporation | ||
from env import HOST, TOKEN | ||
from workspace_manager import deleteWorkspace | ||
|
||
if __name__ == "__main__": | ||
test_config = {"host": HOST, "token": TOKEN} | ||
|
||
deleteWorkspace(test_config) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
# (C) 2024 GoodData Corporation | ||
import json | ||
|
||
|
||
def load_json(file_path): | ||
"""Load a JSON file and return its contents.""" | ||
with open(file_path) as file: # Removed the "r" as it's the default mode | ||
return json.load(file) | ||
|
||
|
||
def normalize_metrics(metrics, exclude_keys=None): | ||
""" | ||
Normalize keys in the metrics list to camelCase, excluding specified keys. | ||
:param metrics: List of dictionaries with metric data. | ||
:param exclude_keys: List of keys to exclude from normalization. | ||
:return: List of normalized metric dictionaries. | ||
""" | ||
if exclude_keys is None: | ||
exclude_keys = [] | ||
|
||
def snake_to_camel(snake_str): | ||
components = snake_str.split("_") | ||
return components[0] + "".join(x.title() for x in components[1:]) | ||
|
||
return [ | ||
{snake_to_camel(key): value for key, value in metric.items() if key not in exclude_keys} | ||
for metric in metrics | ||
if isinstance(metric, dict) | ||
] |
Oops, something went wrong.