Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
179 changes: 93 additions & 86 deletions tests/cassettes/test_get_budget.yaml

Large diffs are not rendered by default.

229 changes: 120 additions & 109 deletions tests/cassettes/test_get_budget_alert.yaml

Large diffs are not rendered by default.

179 changes: 93 additions & 86 deletions tests/cassettes/test_get_budget_with_params.yaml

Large diffs are not rendered by default.

25 changes: 13 additions & 12 deletions tests/cassettes/test_get_me.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ interactions:
uri: https://api.vantage.sh/v2/me
response:
body:
string: '{"default_workspace_token":null,"workspaces":[{"token":"wrkspc_1f841c10eacc61a7","name":"Updated_test_workspace_20251124_145143_558109","created_at":"2025-11-24T21:51:44Z","enable_currency_conversion":true,"currency":"USD","exchange_rate_date":"daily_rate"},{"token":"wrkspc_576fafc861f024a4","name":"Default","created_at":"2025-11-24T20:55:56Z","enable_currency_conversion":false,"currency":"USD","exchange_rate_date":"daily_rate"}],"bearer_token":{"description":"vantage_sdk","created_at":"2025-11-24T20:58:49Z","scope":["read","write"]}}'
string: '{"default_workspace_token":null,"default_dashboard_token":null,"workspaces":[{"token":"wrkspc_1f841c10eacc61a7","name":"Updated_test_workspace_20251124_145143_558109","created_at":"2025-11-24T21:51:44Z","enable_currency_conversion":true,"currency":"USD","exchange_rate_date":"daily_rate"},{"token":"wrkspc_576fafc861f024a4","name":"Default","created_at":"2025-11-24T20:55:56Z","enable_currency_conversion":false,"currency":"USD","exchange_rate_date":"daily_rate"}],"bearer_token":{"description":"vantage_sdk","created_at":"2025-11-24T20:58:49Z","scope":["read","write"]},"is_account_owner":true}'
headers:
Access-Control-Allow-Origin:
- '*'
Expand All @@ -29,17 +29,18 @@ interactions:
Connection:
- keep-alive
Content-Security-Policy:
- 'default-src ''self'' https:; font-src ''self'' https: data: https://fonts.gstatic.com;
img-src ''self'' https: data:; object-src ''none''; script-src ''self'' https:
''unsafe-inline''; style-src ''self'' https: https://fonts.googleapis.com
''unsafe-inline''; connect-src ''self'' https: https://browser-intake-datadoghq.com;
report-uri https://browser-intake-datadoghq.com/api/v2/logs?dd-api-key=pub6a4daf9be897fccfebb14341baa5d70c&dd-evp-origin=content-security-policy&ddsource=csp-report'
- 'default-src ''self'' https:; frame-ancestors ''self''; font-src ''self''
https: data: https://fonts.gstatic.com; img-src ''self'' https: data:; object-src
''none''; script-src ''self'' https: ''unsafe-inline''; worker-src ''self''
https: blob:; style-src ''self'' https: https://fonts.googleapis.com ''unsafe-inline'';
connect-src ''self'' https: wss: https://browser-intake-datadoghq.com; report-uri
https://browser-intake-datadoghq.com/api/v2/logs?dd-api-key=pub6a4daf9be897fccfebb14341baa5d70c&dd-evp-origin=content-security-policy&ddsource=csp-report'
Content-Type:
- application/json
ETag:
- W/"7c788d619014abf51cccaeb5e9cdc2e6"
- W/"bd91932e46e3e19e21b5e5a426790fc9"
Set-Cookie:
- _stratus_session=c2egz9oUBXKvs%2Byz23J3Zec8sTYqBF9E%2FSC3hk6BuUabzFqnF77ek2oDY53MEwrA0q3kHArM%2FuTyl1QPmPRgGIaA4KeUujp%2B6Xucb9CprkP7QofCggJg8PW0xm8VRvSpO7LZkgThDCdLA502Ua5VUmTtYo64g%2FY9KvprfvSjAeSO6MSHWahl1vz1fRVWhla%2B0%2BLqJhzgi4A%3D--UCqCok7B6jkIgtWJ--uibI2CFS3LK%2FtqBy3WqEQQ%3D%3D;
- _stratus_session=AvnRU%2FO1iBFykMB4o2dfcd4SPwYJwKylOgvIUOYBx9K6TMSYQSpoTOQSop%2BkfQBkXP7YYfn9wVKOwvTrIyXwrA1s3d%2FAspCPsOwYwe1Owoc75%2BWR7%2F6vcwEg7gs2DxJRXPMDlzTKd7O14J4lUPZMgrsFqwaGTPS40Yikqtk4TEm%2B83QfCGPtgeDItqYJk7TKXDha6gQWxVA%3D--d060sNOzIy%2FdG3ci--%2BZT0spHuwo0UobG6DsURgQ%3D%3D;
path=/; secure; HttpOnly; SameSite=Lax
Strict-Transport-Security:
- max-age=63072000; includeSubDomains
Expand All @@ -48,13 +49,13 @@ interactions:
X-Rate-Limit-Limit:
- '1000'
X-Rate-Limit-Remaining:
- '365'
- '997'
X-Rate-Limit-Reset:
- '1770576040'
- '1790812984'
X-Runtime:
- '0.035673'
- '0.037219'
content-length:
- '540'
- '595'
status:
code: 200
message: OK
Expand Down
179 changes: 93 additions & 86 deletions tests/cassettes/test_update_budget.yaml

Large diffs are not rendered by default.

68 changes: 34 additions & 34 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,50 +10,41 @@
regardless of when they were recorded.
"""

from datetime import datetime

# This fixes a type issue with the generated code in models.py
import builtins
import time
from datetime import datetime
from pathlib import Path

builtins.bytes_aliased = bytes

import pytest
from httpx import HTTPError, Timeout

from tests.test_models import Settings, ResourceNameFactory
from tests.test_models import ResourceNameFactory, Settings
from vantage_sdk import VantageSDK
from vantage_sdk.models import (
AccessGrant,
AccessGrantTokenParams,
AnomalyNotification,
AnomalyNotificationTokenParams,
AuditLog,
AuditLogs,
AuditLogsGetParametersQuery,
BillingRule,
BillingRuleTokenParams,
Budget,
BudgetAlert,
BudgetAlertTokenParams,
BudgetAlertsPostRequest,
BudgetAlertTokenParams,
BudgetTokenParams,
BusinessMetric,
BusinessMetricTokenParams,
Canvas,
CanvasTokenParams,
CostAlert,
CostAlertTokenParams,
CostReport,
CostReportTokenParams,
CostsDataExportsPostRequest,
CreateCostReportChartType,
CreateDashboardDateBin,
CreateCostReportDateBin,
CreateDashboardDateInterval,
CreateFinancialCommitmentReportDateInterval,
CreateKubernetesEfficiencyReportDateInterval,
CreateNetworkFlowReportDateInterval,
CreateCostExportSchema,
CreateAccessGrant,
CreateAccessGrantAccess,
CreateAnomalyNotification,
Expand All @@ -62,39 +53,49 @@
CreateBudgetPeriod,
CreateBusinessMetric,
CreateBusinessMetricCostReportTokensWithMetadatum,
CreateBusinessMetricCostReportTokensWithMetadatumUnitScale,
CreateBusinessMetricForecastedValue,
CreateBusinessMetricValue,
CreateCanvas,
CreateCostAlert,
CreateCostExportSchema,
CreateCostReport,
CreateCostReportChartSettings,
CreateCostReportChartType,
CreateCostReportDateBin,
CreateCostReportSettings,
CreateDashboard,
CreateDashboardDateBin,
CreateDashboardDateInterval,
CreateDashboardWidget,
CreateDashboardWidgetSettings,
CreateFinancialCommitmentReport,
CreateFinancialCommitmentReportDateInterval,
CreateFolder,
CreateKubernetesEfficiencyReport,
CreateKubernetesEfficiencyReportDateInterval,
CreateManagedAccount,
CreateNetworkFlowReport,
CreateNetworkFlowReportDateInterval,
CreateNetworkFlowReportFlowDirection,
CreateNetworkFlowReportFlowWeight,
CreateNetworkFlowReportGrouping,
CreateResourceReport,
CreateSavedFilter,
CreateTeam,
CreateTeamRole,
CreateVirtualTagConfig,
Canvas,
CanvasTokenParams,
CreateVirtualTagConfigCollapsedTagKey,
CreateVirtualTagConfigValue,
CreateWorkspace,
Dashboard,
DashboardTokenParams,
CreateNetworkFlowReportFlowDirection,
CreateNetworkFlowReportFlowWeight,
CreateNetworkFlowReportGrouping,
FinancialCommitmentReport,
FinancialCommitmentReportTokenParams,
Folder,
FolderTokenParams,
CreateBusinessMetricForecastedValue,
KubernetesEfficiencyReport,
KubernetesEfficiencyReportTokenParams,
CreateCostReportSettings,
CreateDashboardWidgetSettings,
CreateVirtualTagConfigValue,
VirtualTagConfigValue,
ManagedAccount,
ManagedAccountTokenParams,
NetworkFlowReport,
Expand All @@ -103,18 +104,11 @@
ResourceReportTokenParams,
SavedFilter,
SavedFilterTokenParams,
CreateCostReportChartSettings,
CreateVirtualTagConfigCollapsedTagKey,
VirtualTagConfigValueCostMetricAggregation,
VirtualTagConfigValuePercentage,
Team,
TeamTokenParams,
UpdateCostReport,
CreateBusinessMetricCostReportTokensWithMetadatumUnitScale,
CreateDashboardWidget,
VirtualTagConfig,
VirtualTagTokenParams,
CreateWorkspace,
Workspace,
WorkspaceTokenParams,
)
Expand All @@ -124,11 +118,13 @@

settings = Settings()


def _scrub_request(request):
if "authorization" in request.headers:
request.headers["authorization"] = "REDACTED"
return request


def _scrub_response(response):
response["headers"].pop("Date", None)
response["headers"].pop("X-Request-Id", None)
Expand All @@ -141,6 +137,7 @@ def pytest_configure(config) -> None:
config.addinivalue_line("markers", "live: mark test as requiring the live API")
config.addinivalue_line("markers", "vcr_only: mark test as requiring VCR cassettes (skipped against live API)")


def pytest_collection_modifyitems(items):
use_vcr = settings.vcr_enabled
if not use_vcr:
Expand All @@ -151,10 +148,15 @@ def pytest_collection_modifyitems(items):
for item in items:
item.add_marker(pytest.mark.vcr)


@pytest.fixture(scope="session")
def vcr_cassette_dir():
return str(CASSETTE_DIR)


@pytest.fixture(scope="session")
def vcr_config():
return {
"cassette_library_dir": str(CASSETTE_DIR),
"filter_headers": ["authorization"],
"before_record_request": _scrub_request,
"before_record_response": _scrub_response,
Expand Down Expand Up @@ -683,7 +685,6 @@ def budget_alert_fixture(vantage_sdk, budget_fixture):
@pytest.fixture()
def dashboard_fixture(vantage_sdk, cost_report_fixture):
"""Fixture to create a dashboard for testing"""

# setup - create a test dashboard
dashboard_title = RESOURCES.dashboard_name

Expand Down Expand Up @@ -724,7 +725,6 @@ def dashboard_fixture(vantage_sdk, cost_report_fixture):
@pytest.fixture()
def canvas_fixture(vantage_sdk):
"""Fixture to create a canvas for testing"""

# setup - create a test canvas
canvas_title = RESOURCES.canvas_name

Expand Down
26 changes: 26 additions & 0 deletions tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
from pydantic import BaseModel, Field
from pydantic_settings import BaseSettings, SettingsConfigDict

from vantage_sdk.models import UnitCostCalculationType, UnitCosts


class WorkspaceConfig(BaseModel):
"""Workspace configuration with token information"""
Expand Down Expand Up @@ -135,3 +137,27 @@ def tag_name(self) -> str:
@property
def updated_prefix(self) -> str:
return self.name_generator(ResourcePrefix.UPDATED)


def test_unit_costs_nonempty_response():
unit_costs = UnitCosts.model_validate(
{
"unit_costs": [
{
"business_metric_token": "bsnss_mtrc_test",
"business_metric_title": "Total Revenue",
"calculation_type": "unit_cost",
"unit_cost_amount": "4.25",
"business_metric_amount": "0.371",
"scale": 1.0,
"date": "2026-01-01",
}
]
}
)

assert len(unit_costs.unit_costs) == 1
unit_cost = unit_costs.unit_costs[0]
assert unit_cost.calculation_type is UnitCostCalculationType.unit_cost
assert unit_cost.unit_cost_amount == "4.25"
assert unit_cost.business_metric_amount == "0.371"
2 changes: 1 addition & 1 deletion uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion vantage_sdk/models/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -601,7 +601,6 @@ class BudgetAlertsPostRequest(create_budget_alert_model.CreateBudgetAlert):
"""Extends CreateBudgetAlert to accept integer durations"""

duration_in_days: int | str | None = None # type: ignore[assignment]
workspace_token: str | None = None


class BudgetAlertsBudgetAlertTokenPutRequest(update_budget_alert_model.UpdateBudgetAlert):
Expand Down
Loading
Loading