Skip to content

Commit 14f1e2a

Browse files
Merge pull request #68 from negatic/master
Test Stage and Various Fixes
2 parents 2197750 + cbc4d8b commit 14f1e2a

12 files changed

Lines changed: 576 additions & 370 deletions

.env.test

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ FASTAPI__SWAGGER_UI_PARAMS={}
1717

1818
# Redis Configuration (RedisConfig)
1919
REDIS__MASTER_HOST=localhost:6379
20-
REDIS__IMAGE=redis:7-alpine
20+
REDIS__IMAGE=redis:8.2.0
2121
REDIS__DATABASE=0
2222
REDIS__PASSWORD=test_password
2323

@@ -31,20 +31,27 @@ POSTGRES_SQLALCHEMY__PASSWORD=test_password
3131

3232
# Keycloak Configuration (KeycloakConfig)
3333
KEYCLOAK__SERVER_URL=http://localhost:8080
34-
KEYCLOAK__IMAGE=quay.io/keycloak/keycloak:23.0
34+
KEYCLOAK__IMAGE=quay.io/keycloak/keycloak:26.3
3535
KEYCLOAK__ADMIN_USERNAME=admin
3636
KEYCLOAK__ADMIN_PASSWORD=admin
3737
KEYCLOAK__REALM_NAME=master
38+
KEYCLOAK__CLIENT_ID=admin-cli
39+
KEYCLOAK__IS_ADMIN_MODE_ENABLED=true
40+
KEYCLOAK__ADMIN_USERNAME=admin
41+
KEYCLOAK__ADMIN_PASSWORD=admin
42+
KEYCLOAK__ADMIN_REALM_NAME=master
43+
KEYCLOAK__VERIFY_SSL=false
44+
KEYCLOAK__TIMEOUT=30
3845

3946
# Elasticsearch Configuration (ElasticsearchConfig)
4047
ELASTIC__HOSTS=["http://localhost:9200"]
41-
ELASTIC__IMAGE=repo.smartech.ir/elasticsearch/elasticsearch:9.1.0
48+
ELASTIC__IMAGE=docker.elastic.co/elasticsearch/elasticsearch:9.1.0
4249
ELASTIC__PORT=9200
4350
ELASTIC__HTTP_USER_NAME=elastic
4451
ELASTIC__HTTP_PASSWORD=test_password
4552

4653
# Kafka Configuration (KafkaConfig)
47-
KAFKA__IMAGE=confluentinc/cp-kafka:7.4.0
54+
KAFKA__IMAGE=confluentinc/cp-kafka:7.4.10
4855
KAFKA__BROKERS_LIST=["localhost:9092"]
4956

5057
# MinIO Configuration (MinioConfig)

.github/workflows/tests.yml

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
name: Behave Tests
2+
3+
on:
4+
push:
5+
branches: [ master ]
6+
pull_request:
7+
branches: [ '*' ]
8+
9+
jobs:
10+
behave-tests:
11+
runs-on: ubuntu-latest
12+
strategy:
13+
matrix:
14+
python-version: ["3.13"]
15+
16+
steps:
17+
- uses: actions/checkout@v4
18+
19+
- name: Set up Python ${{ matrix.python-version }}
20+
uses: actions/setup-python@v4
21+
with:
22+
python-version: ${{ matrix.python-version }}
23+
24+
- name: Install Poetry
25+
uses: snok/install-poetry@v1
26+
with:
27+
virtualenvs-create: true
28+
virtualenvs-in-project: true
29+
30+
- name: Cache Poetry virtualenv
31+
uses: actions/cache@v3
32+
id: cache
33+
with:
34+
path: .venv
35+
key: venv-${{ runner.os }}-${{ matrix.python-version }}-${{ hashFiles('pyproject.toml') }}
36+
37+
- name: Install dependencies
38+
run: make install-dev
39+
40+
- name: Run Behave tests
41+
run: make behave

archipy/adapters/elasticsearch/adapters.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,23 @@ def exists(
258258
"""
259259
return self.client.exists(index=index, id=doc_id, **kwargs)
260260

261+
@override
262+
def index_exists(
263+
self,
264+
index: ElasticsearchIndexType,
265+
**kwargs: object,
266+
) -> ElasticsearchResponseType:
267+
"""Check if an index exists in Elasticsearch.
268+
269+
Args:
270+
index (ElasticsearchIndexType): The index name.
271+
kwargs: Additional keyword arguments passed to the Elasticsearch client.
272+
273+
Returns:
274+
ElasticsearchResponseType: True if the index exists, False otherwise.
275+
"""
276+
return self.client.indices.exists(index=index, **kwargs)
277+
261278

262279
class AsyncElasticsearchAdapter(AsyncElasticsearchPort):
263280
"""Concrete implementation of the AsyncElasticsearchPort interface using elasticsearch-py library.
@@ -495,3 +512,20 @@ async def exists(
495512
ElasticsearchResponseType: True if the document exists, False otherwise.
496513
"""
497514
return await self.client.exists(index=index, id=doc_id, **kwargs)
515+
516+
@override
517+
async def index_exists(
518+
self,
519+
index: ElasticsearchIndexType,
520+
**kwargs: object,
521+
) -> ElasticsearchResponseType:
522+
"""Check if an index exists in Elasticsearch.
523+
524+
Args:
525+
index (ElasticsearchIndexType): The index name.
526+
kwargs: Additional keyword arguments passed to the Elasticsearch client.
527+
528+
Returns:
529+
ElasticsearchResponseType: True if the index exists, False otherwise.
530+
"""
531+
return await self.client.indices.exists(index=index, **kwargs)

archipy/adapters/elasticsearch/ports.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,26 @@ def exists(
228228
"""
229229
raise NotImplementedError
230230

231+
@abstractmethod
232+
def index_exists(
233+
self,
234+
index: ElasticsearchIndexType,
235+
**kwargs: object,
236+
) -> ElasticsearchResponseType:
237+
"""Check if an index exists in Elasticsearch.
238+
239+
Args:
240+
index (ElasticsearchIndexType): The index name.
241+
**kwargs (object): Additional keyword arguments passed to the Elasticsearch client.
242+
243+
Returns:
244+
ElasticsearchResponseType: True if the index exists, False otherwise.
245+
246+
Raises:
247+
NotImplementedError: If not implemented by the subclass.
248+
"""
249+
raise NotImplementedError
250+
231251

232252
class AsyncElasticsearchPort:
233253
"""Async interface for Elasticsearch operations providing a standardized access pattern.
@@ -447,3 +467,23 @@ async def exists(
447467
NotImplementedError: If not implemented by the subclass.
448468
"""
449469
raise NotImplementedError
470+
471+
@abstractmethod
472+
async def index_exists(
473+
self,
474+
index: ElasticsearchIndexType,
475+
**kwargs: object,
476+
) -> ElasticsearchResponseType:
477+
"""Check if an index exists in Elasticsearch.
478+
479+
Args:
480+
index (ElasticsearchIndexType): The index name.
481+
**kwargs (object): Additional keyword arguments passed to the Elasticsearch client.
482+
483+
Returns:
484+
ElasticsearchResponseType: True if the index exists, False otherwise.
485+
486+
Raises:
487+
NotImplementedError: If not implemented by the subclass.
488+
"""
489+
raise NotImplementedError

features/environment.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,12 @@ class TestConfig(BaseConfig):
2727
)
2828

2929
# Test container images
30-
REDIS__IMAGE: str = "redis:7-alpine"
30+
REDIS__IMAGE: str = "redis:8.2.0"
3131
POSTGRES__IMAGE: str = "postgres:17"
32-
ELASTIC__IMAGE: str = "elasticsearch:9.1.0"
33-
KAFKA__IMAGE: str = "confluentinc/cp-kafka:7.4.0"
34-
MINIO__IMAGE: str = "minio/minio:latest"
35-
KEYCLOAK__IMAGE: str = "quay.io/keycloak/keycloak:23.0"
32+
ELASTIC__IMAGE: str = "docker.elastic.co/elasticsearch/elasticsearch:9.1.0"
33+
KAFKA__IMAGE: str = "confluentinc/cp-kafka:7.4.10"
34+
MINIO__IMAGE: str = "quay.io/minio/minio:latest"
35+
KEYCLOAK__IMAGE: str = "quay.io/keycloak/keycloak:26.3"
3636

3737
def __init__(self, **kwargs):
3838
super().__init__(**kwargs)

features/exception_utils.feature

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ Feature: Exception Utilities
1818
Scenario: Handle a gRPC exception
1919
Given a gRPC exception "BaseError"
2020
When gRPC exception is handled
21-
Then the response should have gRPC status "UNKNOWN"
21+
Then the response should have gRPC status "INTERNAL"
2222

2323
Scenario: Generate FastAPI exception responses
2424
Given a list of FastAPI errors ["InvalidPhoneNumberError", "NotFoundError"]

0 commit comments

Comments
 (0)