|
1 | 1 | # pylint: disable=redefined-outer-name
|
2 | 2 | # pylint: disable=unused-argument
|
3 | 3 | # pylint: disable=unused-variable
|
| 4 | +# pylint: disable=too-many-arguments |
4 | 5 |
|
5 | 6 |
|
| 7 | +import json |
| 8 | +import re |
6 | 9 | from itertools import chain
|
7 | 10 | from typing import Any
|
8 | 11 |
|
9 | 12 | import pytest
|
10 | 13 | import simcore_service_webserver.products
|
| 14 | +import sqlalchemy as sa |
| 15 | +from faker import Faker |
| 16 | +from models_library.products import ProductName |
11 | 17 | from pydantic import BaseModel
|
| 18 | +from pytest_simcore.helpers.faker_factories import random_product |
12 | 19 | from pytest_simcore.pydantic_models import (
|
13 | 20 | assert_validation_model,
|
14 | 21 | walk_model_examples_in_package,
|
15 | 22 | )
|
| 23 | +from simcore_postgres_database.models.products import products as products_table |
| 24 | +from simcore_service_webserver.constants import FRONTEND_APP_DEFAULT |
16 | 25 | from simcore_service_webserver.products._models import Product
|
| 26 | +from sqlalchemy import String |
| 27 | +from sqlalchemy.dialects import postgresql |
17 | 28 |
|
18 | 29 |
|
19 | 30 | @pytest.mark.parametrize(
|
@@ -96,3 +107,45 @@ def test_product_host_regex_with_spaces():
|
96 | 107 | assert product.host_regex.search("osparc.bar.com")
|
97 | 108 |
|
98 | 109 | assert product. support_email == "[email protected]"
|
| 110 | + |
| 111 | + |
| 112 | +@pytest.fixture(scope="session") |
| 113 | +def product_name() -> ProductName: |
| 114 | + return ProductName(FRONTEND_APP_DEFAULT) |
| 115 | + |
| 116 | + |
| 117 | +def test_safe_load_empty_blanks_on_string_cols_from_db( |
| 118 | + faker: Faker, product_name: ProductName |
| 119 | +): |
| 120 | + def _get_server_defaults(): |
| 121 | + server_defaults = {} |
| 122 | + for c in products_table.columns: |
| 123 | + if c.server_default is not None: |
| 124 | + if isinstance(c.type, String): |
| 125 | + server_defaults[c.name] = c.server_default.arg |
| 126 | + elif isinstance(c.type, postgresql.JSONB): |
| 127 | + m = re.match(r"^'(.+)'::jsonb$", c.server_default.arg.text) |
| 128 | + if m: |
| 129 | + server_defaults[c.name] = json.loads(m.group(1)) |
| 130 | + |
| 131 | + return server_defaults |
| 132 | + |
| 133 | + nullable_strings_column_names = [ |
| 134 | + c.name |
| 135 | + for c in products_table.columns |
| 136 | + if isinstance(c.type, sa.String) and c.nullable |
| 137 | + ] |
| 138 | + |
| 139 | + server_defaults = _get_server_defaults() |
| 140 | + |
| 141 | + product_row_from_db = random_product( |
| 142 | + name=product_name, |
| 143 | + fake=faker, |
| 144 | + **{name: " " * len(name) for name in nullable_strings_column_names} |
| 145 | + ) |
| 146 | + |
| 147 | + product = Product.model_validate(product_row_from_db) |
| 148 | + |
| 149 | + assert product.model_dump(include=set(nullable_strings_column_names)) == { |
| 150 | + name: None for name in nullable_strings_column_names |
| 151 | + } |
0 commit comments