Skip to content
Draft
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# See [Connector Acceptance Tests](https://docs.airbyte.com/connector-development/testing-connectors/connector-acceptance-tests-reference)
# for more information about how to configure these tests
connector_image: airbyte/source-granola:dev
acceptance_tests:
spec:
tests:
- spec_path: "manifest.yaml"
connection:
tests:
- config_path: "secrets/config.json"
status: "succeed"
- config_path: "integration_tests/invalid_config.json"
status: "failed"
discovery:
tests:
- config_path: "secrets/config.json"
basic_read:
tests:
- config_path: "secrets/config.json"
configured_catalog_path: "integration_tests/configured_catalog.json"
incremental:
tests:
- config_path: "secrets/config.json"
configured_catalog_path: "integration_tests/configured_catalog_incremental.json"
future_state:
future_state_path: "integration_tests/abnormal_state.json"
full_refresh:
tests:
- config_path: "secrets/config.json"
configured_catalog_path: "integration_tests/configured_catalog.json"
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[
{
"type": "STREAM",
"stream": {
"stream_state": {
"created_at": "2120-01-01T00:00:00Z"
},
"stream_descriptor": {
"name": "notes"
}
}
}
]
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,21 @@
"json_schema": {},
"supported_sync_modes": ["full_refresh", "incremental"],
"source_defined_cursor": true,
"default_cursor_field": ["updated_at"],
"default_cursor_field": ["created_at"],
"source_defined_primary_key": [["id"]]
},
"sync_mode": "incremental",
"cursor_field": ["updated_at"],
"destination_sync_mode": "append"
"sync_mode": "full_refresh",
"destination_sync_mode": "overwrite"
},
{
"stream": {
"name": "detailed_notes",
"json_schema": {},
"supported_sync_modes": ["full_refresh"],
"source_defined_primary_key": [["id"]]
},
"sync_mode": "full_refresh",
"destination_sync_mode": "overwrite"
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"streams": [
{
"stream": {
"name": "notes",
"json_schema": {},
"supported_sync_modes": ["full_refresh", "incremental"],
"source_defined_cursor": true,
"default_cursor_field": ["created_at"],
"source_defined_primary_key": [["id"]]
},
"sync_mode": "incremental",
"cursor_field": ["created_at"],
"destination_sync_mode": "append"
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"api_key": "invalid-api-key",
"start_date": "2025-01-01"
}
13 changes: 9 additions & 4 deletions airbyte-integrations/connectors/source-granola/manifest.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,17 @@ definitions:
cursor_value: "{{ response.get('cursor', '') }}"
stop_condition: "{{ not response.get('cursor') or not response.get('hasMore', False) }}"
incremental_sync:
# created_before is exclusive with respect to a whole day when given a bare
# date, so slice bounds must stay full timestamps at second granularity.
# start_datetime keeps the date-only format of the start_date spec field, and
# cursor_datetime_formats keeps "%Y-%m-%d" to parse state saved by <= 0.2.11.
type: DatetimeBasedCursor
cursor_field: created_at
cursor_datetime_formats:
- "%Y-%m-%dT%H:%M:%SZ"
- "%Y-%m-%dT%H:%M:%S.%fZ"
datetime_format: "%Y-%m-%d"
- "%Y-%m-%d"
datetime_format: "%Y-%m-%dT%H:%M:%SZ"
start_datetime:
type: MinMaxDatetime
datetime: "{{ config.get('start_date', (now_utc() - duration('P730D')).strftime('%Y-%m-%d')) }}"
Expand All @@ -80,10 +85,10 @@ definitions:
field_name: created_before
end_datetime:
type: MinMaxDatetime
datetime: "{{ now_utc().strftime('%Y-%m-%d') }}"
datetime_format: "%Y-%m-%d"
datetime: "{{ now_utc().strftime('%Y-%m-%dT%H:%M:%SZ') }}"
datetime_format: "%Y-%m-%dT%H:%M:%SZ"
step: P30D
cursor_granularity: P1D
cursor_granularity: PT1S
schema_loader:
type: InlineSchemaLoader
schema:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ data:
connectorSubtype: api
connectorType: source
definitionId: 9023923c-002f-4131-9554-3ebdf56540a4
dockerImageTag: 0.2.11
dockerImageTag: 0.2.12
dockerRepository: airbyte/source-granola
documentationUrl: https://docs.airbyte.com/integrations/sources/granola
githubIssueLabel: source-granola
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Copyright (c) 2026 Airbyte, Inc., all rights reserved.

import os
from pathlib import Path

import pytest

from airbyte_cdk.sources.declarative.yaml_declarative_source import YamlDeclarativeSource
from airbyte_cdk.test.catalog_builder import CatalogBuilder
from airbyte_cdk.test.state_builder import StateBuilder


pytest_plugins = ["airbyte_cdk.test.utils.manifest_only_fixtures"]

os.environ["REQUEST_CACHE_PATH"] = "REQUEST_CACHE_PATH"


def _get_manifest_path() -> Path:
ci_path = Path("/airbyte/integration_code/source_declarative_manifest")
if ci_path.exists():
return ci_path
return Path(__file__).parent.parent


_YAML_FILE_PATH = _get_manifest_path() / "manifest.yaml"


def get_source(config: dict, state=None) -> YamlDeclarativeSource:
catalog = CatalogBuilder().build()
state = StateBuilder().build() if state is None else state
return YamlDeclarativeSource(path_to_yaml=str(_YAML_FILE_PATH), catalog=catalog, config=config, state=state)


@pytest.fixture(autouse=True)
def clear_cache_before_each_test():
cache_dir = Path(os.environ["REQUEST_CACHE_PATH"])
if cache_dir.exists() and cache_dir.is_dir():
for file_path in cache_dir.glob("*.sqlite"):
file_path.unlink()
yield
Loading
Loading