コード例 #1
0
def test_long_text_field_type(data_fixture):
    user = data_fixture.create_user()
    table = data_fixture.create_database_table(user=user)
    field = data_fixture.create_text_field(table=table, order=1, name='name')

    handler = FieldHandler()
    handler.create_field(user=user,
                         table=table,
                         type_name='long_text',
                         name='description')
    field = handler.update_field(user=user,
                                 field=field,
                                 new_type_name='long_text')

    assert len(LongTextField.objects.all()) == 2

    fake = Faker()
    text = fake.text()
    model = table.get_model(attribute_names=True)
    row = model.objects.create(description=text, name='Test')

    assert row.description == text
    assert row.name == 'Test'

    handler.delete_field(user=user, field=field)
    assert len(LongTextField.objects.all()) == 1
コード例 #2
0
    def fill_example_table_data(self, user, table):
        """
        Fills the table with some initial example data. A new table is expected that
        already has the a primary field named 'name'.

        :param user: The user on whose behalf the table is filled.
        :type: user: User
        :param table: The table that needs the initial data.
        :type table: User
        """

        view_handler = ViewHandler()
        field_handler = FieldHandler()

        view = view_handler.create_view(user, table, GridViewType.type, name='Grid')
        notes = field_handler.create_field(user, table, LongTextFieldType.type,
                                           name='Notes')
        active = field_handler.create_field(user, table, BooleanFieldType.type,
                                            name='Active')

        field_options = {
            notes.id: {'width': 400},
            active.id: {'width': 100}
        }
        fields = [notes, active]
        view_handler.update_grid_view_field_options(view, field_options, fields=fields)

        model = table.get_model(attribute_names=True)
        model.objects.create(name='Tesla', active=True)
        model.objects.create(name='Amazon', active=False)
コード例 #3
0
ファイル: fill_table.py プロジェクト: bram2w/baserow
 def create_a_column_for_every_type(table):
     field_handler = FieldHandler()
     all_kwargs_per_type = construct_all_possible_field_kwargs(None)
     for field_type_name, all_possible_kwargs in all_kwargs_per_type.items(
     ):
         if field_type_name == "link_row":
             continue
         i = 0
         for kwargs in all_possible_kwargs:
             i = i + 1
             field_handler.create_field(table.database.group.users.first(),
                                        table, field_type_name, **kwargs)
コード例 #4
0
def test_single_select_field_type_random_value(data_fixture):
    """
    Verify that the random_value function of the single select field type correctly
    returns one option of a given select_options list. If the select_options list is
    empty or the passed field type is not of single select field type by any chance
    it should return None.
    """

    user = data_fixture.create_user()
    database = data_fixture.create_database_application(user=user,
                                                        name="Placeholder")
    table = data_fixture.create_database_table(name="Example",
                                               database=database)
    field_handler = FieldHandler()
    cache = {}
    fake = Faker()

    field = field_handler.create_field(
        user=user,
        table=table,
        type_name="single_select",
        name="Single select",
        select_options=[
            {
                "value": "Option 1",
                "color": "blue"
            },
            {
                "value": "Option 2",
                "color": "red"
            },
        ],
    )

    select_options = field.select_options.all()
    random_choice = SingleSelectFieldType().random_value(field, fake, cache)
    assert random_choice in select_options
    random_choice = SingleSelectFieldType().random_value(field, fake, cache)
    assert random_choice in select_options

    email_field = field_handler.create_field(
        user=user,
        table=table,
        type_name="email",
        name="E-Mail",
    )
    random_choice_2 = SingleSelectFieldType().random_value(
        email_field, fake, cache)
    assert random_choice_2 is None
コード例 #5
0
def test_import_export_single_select_field(data_fixture):
    user = data_fixture.create_user()
    table = data_fixture.create_database_table(user=user)
    field_handler = FieldHandler()
    field = field_handler.create_field(user=user,
                                       table=table,
                                       type_name='single_select',
                                       name='Single select',
                                       select_options=[{
                                           'value': 'Option 1',
                                           'color': 'blue'
                                       }])
    select_option = field.select_options.all().first()
    field_type = field_type_registry.get_by_model(field)
    field_serialized = field_type.export_serialized(field)
    id_mapping = {}
    field_imported = field_type.import_serialized(table, field_serialized,
                                                  id_mapping)

    assert field_imported.select_options.all().count() == 1
    imported_select_option = field_imported.select_options.all().first()
    assert imported_select_option.id != select_option.id
    assert imported_select_option.value == select_option.value
    assert imported_select_option.color == select_option.color
    assert imported_select_option.order == select_option.order
コード例 #6
0
def test_single_select_field_type_random_value(data_fixture):
    """
    Verify that the random_value function of the single select field type correctly
    returns one option of a given select_options list. If the select_options list is
    empty or the passed field type is not of single select field type by any chance
    it should return None.
    """

    user = data_fixture.create_user()
    database = data_fixture.create_database_application(user=user,
                                                        name='Placeholder')
    table = data_fixture.create_database_table(name='Example',
                                               database=database)
    field_handler = FieldHandler()
    cache = {}
    fake = Faker()

    field = field_handler.create_field(
        user=user,
        table=table,
        type_name='single_select',
        name='Single select',
        select_options=[{
            'value': 'Option 1',
            'color': 'blue'
        }, {
            'value': 'Option 2',
            'color': 'red'
        }],
    )

    select_options = field.select_options.all()
    random_choice = SingleSelectFieldType().random_value(field, fake, cache)
    assert random_choice in select_options
    random_choice = SingleSelectFieldType().random_value(field, fake, cache)
    assert random_choice in select_options

    email_field = field_handler.create_field(
        user=user,
        table=table,
        type_name='email',
        name='E-Mail',
    )
    random_choice_2 = SingleSelectFieldType().random_value(
        email_field, fake, cache)
    assert random_choice_2 is None
コード例 #7
0
def test_create_primary_field(data_fixture):
    user = data_fixture.create_user()
    table_1 = data_fixture.create_database_table(user=user)
    table_2 = data_fixture.create_database_table(user=user)
    data_fixture.create_text_field(table=table_1, primary=True)

    with pytest.raises(PrimaryFieldAlreadyExists):
        handler = FieldHandler()
        handler.create_field(user=user,
                             table=table_1,
                             type_name='text',
                             primary=True)

    handler = FieldHandler()
    field = handler.create_field(user=user,
                                 table=table_2,
                                 type_name='text',
                                 primary=True)

    assert field.primary

    with pytest.raises(PrimaryFieldAlreadyExists):
        handler.create_field(user=user,
                             table=table_2,
                             type_name='text',
                             primary=True)

    # Should be able to create a regular field when there is already a primary field.
    handler.create_field(user=user,
                         table=table_2,
                         type_name='text',
                         primary=False)
コード例 #8
0
def test_call_apps_registry_pending_operations(data_fixture):
    user = data_fixture.create_user()
    database = data_fixture.create_database_application(user=user, name="Placeholder")
    table = data_fixture.create_database_table(name="Example", database=database)
    customers_table = data_fixture.create_database_table(
        name="Customers", database=database
    )
    field_handler = FieldHandler()
    field_handler.create_field(
        user=user,
        table=table,
        type_name="link_row",
        name="Test",
        link_row_table=customers_table,
    )
    table.get_model()
    # Make sure that there are no pending operations in the app registry. Because a
    # Django ManyToManyField registers pending operations every time a table model is
    # generated, which can causes a memory leak if they are not triggered.
    assert len(apps._pending_operations) == 0
コード例 #9
0
def test_link_row_enhance_queryset(data_fixture, django_assert_num_queries):
    user = data_fixture.create_user()
    database = data_fixture.create_database_application(user=user, name="Placeholder")
    example_table = data_fixture.create_database_table(
        name="Example", database=database
    )
    customers_table = data_fixture.create_database_table(
        name="Customers", database=database
    )

    field_handler = FieldHandler()
    row_handler = RowHandler()

    link_row_field = field_handler.create_field(
        user=user,
        table=example_table,
        type_name="link_row",
        link_row_table=customers_table,
    )

    customers_row_1 = row_handler.create_row(user=user, table=customers_table)
    customers_row_2 = row_handler.create_row(user=user, table=customers_table)
    customers_row_3 = row_handler.create_row(user=user, table=customers_table)

    row_handler.create_row(
        user=user,
        table=example_table,
        values={
            f"field_{link_row_field.id}": [customers_row_1.id, customers_row_2.id],
        },
    )
    row_handler.create_row(
        user=user,
        table=example_table,
        values={
            f"field_{link_row_field.id}": [customers_row_1.id],
        },
    )
    row_handler.create_row(
        user=user,
        table=example_table,
        values={
            f"field_{link_row_field.id}": [customers_row_3.id],
        },
    )

    model = example_table.get_model()
    rows = list(model.objects.all().enhance_by_fields())

    with django_assert_num_queries(0):
        for row in rows:
            list(getattr(row, f"field_{link_row_field.id}").all())
コード例 #10
0
def test_single_select_field_type(data_fixture):
    user = data_fixture.create_user()
    database = data_fixture.create_database_application(user=user, name='Placeholder')
    table = data_fixture.create_database_table(name='Example', database=database)

    field_handler = FieldHandler()

    field = field_handler.create_field(
        user=user, table=table, type_name='single_select', name='Single select',
        select_options=[{'value': 'Option 1', 'color': 'blue'}]
    )

    assert SingleSelectField.objects.all().first().id == field.id
    assert SelectOption.objects.all().count() == 1

    select_options = field.select_options.all()
    assert len(select_options) == 1
    assert select_options[0].order == 0
    assert select_options[0].field_id == field.id
    assert select_options[0].value == 'Option 1'
    assert select_options[0].color == 'blue'

    field = field_handler.update_field(
        user=user, table=table, field=field,
        select_options=[
            {'value': 'Option 2 B', 'color': 'red 2'},
            {'id': select_options[0].id, 'value': 'Option 1 B', 'color': 'blue 2'},
        ]
    )

    assert SelectOption.objects.all().count() == 2
    select_options_2 = field.select_options.all()
    assert len(select_options_2) == 2
    assert select_options_2[0].order == 0
    assert select_options_2[0].field_id == field.id
    assert select_options_2[0].value == 'Option 2 B'
    assert select_options_2[0].color == 'red 2'
    assert select_options_2[1].id == select_options[0].id
    assert select_options_2[1].order == 1
    assert select_options_2[1].field_id == field.id
    assert select_options_2[1].value == 'Option 1 B'
    assert select_options_2[1].color == 'blue 2'

    field_handler.delete_field(user=user, field=field)
    assert SelectOption.objects.all().count() == 0
コード例 #11
0
def test_date_field_type(data_fixture):
    user = data_fixture.create_user()
    table = data_fixture.create_database_table(user=user)

    field_handler = FieldHandler()
    row_handler = RowHandler()

    amsterdam = timezone('Europe/Amsterdam')
    utc = timezone('utc')

    date_field_1 = field_handler.create_field(user=user,
                                              table=table,
                                              type_name='date',
                                              name='Date')
    date_field_2 = field_handler.create_field(user=user,
                                              table=table,
                                              type_name='date',
                                              name='Datetime',
                                              date_include_time=True)

    assert date_field_1.date_include_time == False
    assert date_field_2.date_include_time == True
    assert len(DateField.objects.all()) == 2

    model = table.get_model(attribute_names=True)

    row = row_handler.create_row(user=user,
                                 table=table,
                                 values={},
                                 model=model)
    assert row.date == None
    assert row.datetime == None

    row = row_handler.create_row(user=user,
                                 table=table,
                                 values={
                                     'date': '2020-4-1',
                                     'datetime': '2020-4-1 12:30:30'
                                 },
                                 model=model)
    row.refresh_from_db()
    assert row.date == date(2020, 4, 1)
    assert row.datetime == datetime(2020, 4, 1, 12, 30, 30, tzinfo=utc)

    row = row_handler.create_row(user=user,
                                 table=table,
                                 values={
                                     'datetime':
                                     make_aware(
                                         datetime(2020, 4, 1, 12, 30, 30),
                                         amsterdam)
                                 },
                                 model=model)
    row.refresh_from_db()
    assert row.date == None
    assert row.datetime == datetime(2020,
                                    4,
                                    1,
                                    10,
                                    30,
                                    30,
                                    tzinfo=timezone('UTC'))

    date_field_1 = field_handler.update_field(user=user,
                                              field=date_field_1,
                                              date_include_time=True)
    date_field_2 = field_handler.update_field(user=user,
                                              field=date_field_2,
                                              date_include_time=False)

    assert date_field_1.date_include_time == True
    assert date_field_2.date_include_time == False

    model = table.get_model(attribute_names=True)
    rows = model.objects.all()

    assert rows[0].date == None
    assert rows[0].datetime == None
    assert rows[1].date == datetime(2020, 4, 1, tzinfo=timezone('UTC'))
    assert rows[1].datetime == date(2020, 4, 1)
    assert rows[2].date == None
    assert rows[2].datetime == date(2020, 4, 1)

    field_handler.delete_field(user=user, field=date_field_1)
    field_handler.delete_field(user=user, field=date_field_2)

    assert len(DateField.objects.all()) == 0
コード例 #12
0
def test_url_field_type(data_fixture):
    user = data_fixture.create_user()
    table = data_fixture.create_database_table(user=user)
    table_2 = data_fixture.create_database_table(user=user,
                                                 database=table.database)
    field = data_fixture.create_text_field(table=table, order=1, name='name')

    field_handler = FieldHandler()
    row_handler = RowHandler()

    field_2 = field_handler.create_field(user=user,
                                         table=table,
                                         type_name='url',
                                         name='url')
    number = field_handler.create_field(user=user,
                                        table=table,
                                        type_name='number',
                                        name='number')

    assert len(URLField.objects.all()) == 1
    model = table.get_model(attribute_names=True)

    with pytest.raises(ValidationError):
        row_handler.create_row(user=user,
                               table=table,
                               values={'url': 'invalid_url'},
                               model=model)

    with pytest.raises(ValidationError):
        row_handler.create_row(user=user,
                               table=table,
                               values={'url': 'httpss'},
                               model=model)

    with pytest.raises(ValidationError):
        row_handler.create_row(user=user,
                               table=table,
                               values={'url': 'httpss'},
                               model=model)

    row_0 = row_handler.create_row(user=user,
                                   table=table,
                                   values={
                                       'name': 'http://test.nl',
                                       'url': 'https://baserow.io',
                                       'number': 5
                                   },
                                   model=model)
    row_1 = row_handler.create_row(user=user,
                                   table=table,
                                   values={
                                       'name': 'http;//',
                                       'url': 'http://localhost',
                                       'number': 10
                                   },
                                   model=model)
    row_2 = row_handler.create_row(user=user,
                                   table=table,
                                   values={
                                       'name': '*****@*****.**',
                                       'url': 'http://www.baserow.io'
                                   },
                                   model=model)
    row_3 = row_handler.create_row(
        user=user,
        table=table,
        values={
            'name': 'NOT A URL',
            'url': 'http://www.baserow.io/blog/building-a-database'
        },
        model=model)
    row_4 = row_handler.create_row(
        user=user,
        table=table,
        values={
            'name':
            'ftps://www.complex.website.com?querystring=test&something=else',
            'url': ''
        },
        model=model)
    row_5 = row_handler.create_row(user=user,
                                   table=table,
                                   values={
                                       'url': None,
                                   },
                                   model=model)
    row_6 = row_handler.create_row(user=user,
                                   table=table,
                                   values={},
                                   model=model)

    # Convert to text field to a url field so we can check how the conversion of values
    # went.
    field_handler.update_field(user=user, field=field, new_type_name='url')
    field_handler.update_field(user=user, field=number, new_type_name='url')

    model = table.get_model(attribute_names=True)
    rows = model.objects.all()

    assert rows[0].name == 'http://test.nl'
    assert rows[0].url == 'https://baserow.io'
    assert rows[0].number == ''

    assert rows[1].name == ''
    assert rows[1].url == 'http://localhost'
    assert rows[1].number == ''

    assert rows[2].name == ''
    assert rows[2].url == 'http://www.baserow.io'
    assert rows[2].number == ''

    assert rows[3].name == ''
    assert rows[3].url == 'http://www.baserow.io/blog/building-a-database'
    assert rows[3].number == ''

    assert (rows[4].name ==
            'ftps://www.complex.website.com?querystring=test&something=else')
    assert rows[4].url == ''
    assert rows[4].number == ''

    assert rows[5].name == ''
    assert rows[5].url == ''
    assert rows[5].number == ''

    assert rows[6].name == ''
    assert rows[6].url == ''
    assert rows[6].number == ''

    field_handler.delete_field(user=user, field=field_2)
    assert len(URLField.objects.all()) == 2
コード例 #13
0
def test_link_row_field_type_api_row_views(api_client, data_fixture):
    user, token = data_fixture.create_user_and_token()
    database = data_fixture.create_database_application(user=user, name="Placeholder")
    example_table = data_fixture.create_database_table(
        name="Example", database=database
    )
    customers_table = data_fixture.create_database_table(
        name="Customers", database=database
    )
    grid = data_fixture.create_grid_view(table=example_table)

    data_fixture.create_text_field(name="Name", table=example_table, primary=True)
    customers_primary = data_fixture.create_text_field(
        name="Customer name", table=customers_table, primary=True
    )

    field_handler = FieldHandler()
    row_handler = RowHandler()

    link_row_field = field_handler.create_field(
        user=user,
        table=example_table,
        type_name="link_row",
        link_row_table=customers_table,
    )

    customers_row_1 = row_handler.create_row(
        user=user,
        table=customers_table,
        values={f"field_{customers_primary.id}": "John Doe"},
    )
    customers_row_2 = row_handler.create_row(
        user=user,
        table=customers_table,
        values={f"field_{customers_primary.id}": "Jane Doe"},
    )
    customers_row_3 = row_handler.create_row(user=user, table=customers_table)

    response = api_client.post(
        reverse("api:database:rows:list", kwargs={"table_id": example_table.id}),
        {
            f"field_{link_row_field.id}": "Random",
        },
        format="json",
        HTTP_AUTHORIZATION=f"JWT {token}",
    )
    response_json = response.json()
    assert response.status_code == HTTP_400_BAD_REQUEST
    assert response_json["error"] == "ERROR_REQUEST_BODY_VALIDATION"
    assert (
        response_json["detail"][f"field_{link_row_field.id}"][0]["code"] == "not_a_list"
    )

    response = api_client.post(
        reverse("api:database:rows:list", kwargs={"table_id": example_table.id}),
        {
            f"field_{link_row_field.id}": ["a"],
        },
        format="json",
        HTTP_AUTHORIZATION=f"JWT {token}",
    )
    response_json = response.json()
    assert response.status_code == HTTP_400_BAD_REQUEST
    assert response_json["error"] == "ERROR_REQUEST_BODY_VALIDATION"
    assert (
        response_json["detail"][f"field_{link_row_field.id}"]["0"][0]["code"]
        == "invalid"
    )

    response = api_client.post(
        reverse("api:database:rows:list", kwargs={"table_id": example_table.id}),
        {
            f"field_{link_row_field.id}": [customers_row_1.id, customers_row_2.id, 999],
        },
        format="json",
        HTTP_AUTHORIZATION=f"JWT {token}",
    )
    response_json = response.json()
    row_id = response_json["id"]
    assert response.status_code == HTTP_200_OK
    assert len(response_json[f"field_{link_row_field.id}"]) == 2
    assert response_json[f"field_{link_row_field.id}"][0]["id"] == customers_row_1.id
    assert response_json[f"field_{link_row_field.id}"][0]["value"] == "John Doe"
    assert response_json[f"field_{link_row_field.id}"][1]["id"] == customers_row_2.id
    assert response_json[f"field_{link_row_field.id}"][1]["value"] == "Jane Doe"

    model = example_table.get_model()
    assert model.objects.all().count() == 1

    url = reverse(
        "api:database:rows:item",
        kwargs={"table_id": example_table.id, "row_id": row_id},
    )
    response = api_client.patch(
        url,
        {
            f"field_{link_row_field.id}": [],
        },
        format="json",
        HTTP_AUTHORIZATION=f"JWT {token}",
    )
    response_json = response.json()
    assert response.status_code == HTTP_200_OK
    assert len(response_json[f"field_{link_row_field.id}"]) == 0

    url = reverse(
        "api:database:rows:item",
        kwargs={"table_id": example_table.id, "row_id": row_id},
    )
    response = api_client.patch(
        url,
        {
            f"field_{link_row_field.id}": [customers_row_2.id, customers_row_3.id],
        },
        format="json",
        HTTP_AUTHORIZATION=f"JWT {token}",
    )
    response_json = response.json()
    assert response.status_code == HTTP_200_OK
    assert len(response_json[f"field_{link_row_field.id}"]) == 2
    assert response_json[f"field_{link_row_field.id}"][0]["id"] == customers_row_2.id
    assert response_json[f"field_{link_row_field.id}"][0]["value"] == "Jane Doe"
    assert response_json[f"field_{link_row_field.id}"][1]["id"] == customers_row_3.id
    assert not response_json[f"field_{link_row_field.id}"][1]["value"]

    url = reverse("api:database:views:grid:list", kwargs={"view_id": grid.id})
    response = api_client.get(url, **{"HTTP_AUTHORIZATION": f"JWT {token}"})
    response_json = response.json()
    assert response.status_code == HTTP_200_OK
    assert response_json["count"] == 1
    assert response_json["results"][0]["id"] == row_id
    assert len(response_json["results"][0][f"field_{link_row_field.id}"]) == 2

    url = reverse(
        "api:database:rows:item",
        kwargs={"table_id": example_table.id, "row_id": row_id},
    )
    response = api_client.delete(url, HTTP_AUTHORIZATION=f"JWT {token}")
    assert response.status_code == HTTP_204_NO_CONTENT
    assert model.objects.all().count() == 0

    response = api_client.post(
        reverse("api:database:rows:list", kwargs={"table_id": example_table.id}),
        {},
        format="json",
        HTTP_AUTHORIZATION=f"JWT {token}",
    )
    response_json = response.json()
    assert response.status_code == HTTP_200_OK
    assert len(response_json[f"field_{link_row_field.id}"]) == 0
コード例 #14
0
def test_link_row_field_type_rows(data_fixture):
    user = data_fixture.create_user()
    database = data_fixture.create_database_application(user=user,
                                                        name='Placeholder')
    example_table = data_fixture.create_database_table(name='Example',
                                                       database=database)
    customers_table = data_fixture.create_database_table(name='Customers',
                                                         database=database)
    users_table = data_fixture.create_database_table(name='Users',
                                                     database=database)

    field_handler = FieldHandler()
    row_handler = RowHandler()

    link_row_field = field_handler.create_field(user=user,
                                                table=example_table,
                                                type_name='link_row',
                                                link_row_table=customers_table)

    customers_row_1 = row_handler.create_row(user=user, table=customers_table)
    customers_row_2 = row_handler.create_row(user=user, table=customers_table)
    customers_row_3 = row_handler.create_row(user=user, table=customers_table)

    row = row_handler.create_row(user=user,
                                 table=example_table,
                                 values={
                                     f'field_{link_row_field.id}':
                                     [customers_row_1.id, customers_row_2.id],
                                 })
    row_2 = row_handler.create_row(user=user,
                                   table=example_table,
                                   values={
                                       f'field_{link_row_field.id}':
                                       [customers_row_1.id],
                                   })

    example_table.name = 'Example2'
    example_table.save()

    customers_table.name = 'Customers2'
    customers_table.save()

    row_1_all = getattr(row, f'field_{link_row_field.id}').all()
    row_2_all = getattr(row_2, f'field_{link_row_field.id}').all()
    row_1_ids = [i.id for i in row_1_all]
    row_2_ids = [i.id for i in row_2_all]

    assert row_1_all.count() == 2
    assert row_2_all.count() == 1
    assert customers_row_1.id in row_1_ids
    assert customers_row_2.id in row_1_ids
    assert customers_row_1.id in row_2_ids

    row = row_handler.update_row(
        user=user,
        table=example_table,
        row_id=row.id,
        values={f'field_{link_row_field.id}': [customers_row_3.id]})
    row_2 = row_handler.update_row(
        user=user,
        table=example_table,
        row_id=row_2.id,
        values={
            f'field_{link_row_field.id}':
            [customers_row_2.id, customers_row_1.id]
        })

    row_1_all = getattr(row, f'field_{link_row_field.id}').all()
    row_2_all = getattr(row_2, f'field_{link_row_field.id}').all()
    row_1_ids = [i.id for i in row_1_all]
    row_2_ids = [i.id for i in row_2_all]

    assert row_1_all.count() == 1
    assert row_2_all.count() == 2
    assert customers_row_3.id in row_1_ids
    assert customers_row_1.id in row_2_ids
    assert customers_row_2.id in row_2_ids

    # Check if the relations are there via the customers table.
    customers_table.refresh_from_db()
    customers_model = customers_table.get_model()
    related_field = link_row_field.link_row_related_field
    customer_rows = customers_model.objects.all()

    assert customer_rows.count() == 3

    customers_row_1 = customer_rows[0]
    customers_row_2 = customer_rows[1]
    customers_row_3 = customer_rows[2]

    customer_row_1_all = getattr(customers_row_1,
                                 f'field_{related_field.id}').all()
    customer_row_2_all = getattr(customers_row_2,
                                 f'field_{related_field.id}').all()
    customer_row_3_all = getattr(customers_row_3,
                                 f'field_{related_field.id}').all()

    assert customer_row_1_all.count() == 1
    assert customer_row_2_all.count() == 1
    assert customer_row_3_all.count() == 1

    customers_row_1_ids = [i.id for i in customer_row_1_all]
    customers_row_2_ids = [i.id for i in customer_row_2_all]
    customers_row_3_ids = [i.id for i in customer_row_3_all]

    assert row_2.id in customers_row_1_ids
    assert row_2.id in customers_row_2_ids
    assert row.id in customers_row_3_ids

    # When changing the link row table table all the existing relations should be
    # deleted.
    link_row_field = field_handler.update_field(user=user,
                                                field=link_row_field,
                                                type_name='link_row',
                                                link_row_table=users_table)

    example_table.refresh_from_db()
    model = example_table.get_model()
    rows = model.objects.all()
    row = rows[0]
    row_2 = rows[1]

    assert getattr(row, f'field_{link_row_field.id}').all().count() == 0
    assert getattr(row_2, f'field_{link_row_field.id}').all().count() == 0

    # Just check if the field can be deleted can be deleted.
    field_handler.delete_field(user=user, field=link_row_field)
    assert Field.objects.all().count() == 0
コード例 #15
0
def test_single_select_field_type_api_row_views(api_client, data_fixture):
    user, token = data_fixture.create_user_and_token()
    database = data_fixture.create_database_application(user=user,
                                                        name='Placeholder')
    table = data_fixture.create_database_table(name='Example',
                                               database=database)
    other_select_option = data_fixture.create_select_option()

    field_handler = FieldHandler()

    field = field_handler.create_field(user=user,
                                       table=table,
                                       type_name='single_select',
                                       select_options=[{
                                           'value': 'Option 1',
                                           'color': 'red'
                                       }, {
                                           'value': 'Option 2',
                                           'color': 'blue'
                                       }])

    select_options = field.select_options.all()

    response = api_client.post(reverse('api:database:rows:list',
                                       kwargs={'table_id': table.id}),
                               {f'field_{field.id}': 'Nothing'},
                               format='json',
                               HTTP_AUTHORIZATION=f'JWT {token}')
    response_json = response.json()
    assert response.status_code == HTTP_400_BAD_REQUEST
    assert response_json['error'] == 'ERROR_REQUEST_BODY_VALIDATION'
    assert response_json['detail'][f'field_{field.id}'][0][
        'code'] == 'incorrect_type'

    response = api_client.post(reverse('api:database:rows:list',
                                       kwargs={'table_id': table.id}),
                               {f'field_{field.id}': 999999},
                               format='json',
                               HTTP_AUTHORIZATION=f'JWT {token}')
    response_json = response.json()
    assert response.status_code == HTTP_400_BAD_REQUEST
    assert response_json['error'] == 'ERROR_REQUEST_BODY_VALIDATION'
    assert response_json['detail'][f'field_{field.id}'][0][
        'code'] == 'does_not_exist'

    response = api_client.post(reverse('api:database:rows:list',
                                       kwargs={'table_id': table.id}),
                               {f'field_{field.id}': other_select_option.id},
                               format='json',
                               HTTP_AUTHORIZATION=f'JWT {token}')
    response_json = response.json()
    assert response.status_code == HTTP_400_BAD_REQUEST
    assert response_json['error'] == 'ERROR_REQUEST_BODY_VALIDATION'
    assert response_json['detail'][f'field_{field.id}'][0][
        'code'] == 'does_not_exist'

    response = api_client.post(reverse('api:database:rows:list',
                                       kwargs={'table_id': table.id}),
                               {f'field_{field.id}': select_options[0].id},
                               format='json',
                               HTTP_AUTHORIZATION=f'JWT {token}')
    response_json = response.json()
    assert response.status_code == HTTP_200_OK
    assert response_json[f'field_{field.id}']['id'] == select_options[0].id
    assert response_json[f'field_{field.id}']['value'] == 'Option 1'
    assert response_json[f'field_{field.id}']['color'] == 'red'

    url = reverse('api:database:rows:item',
                  kwargs={
                      'table_id': table.id,
                      'row_id': response_json['id']
                  })
    response = api_client.patch(url, {},
                                format='json',
                                HTTP_AUTHORIZATION=f'JWT {token}')
    assert response.status_code == HTTP_200_OK

    url = reverse('api:database:rows:item',
                  kwargs={
                      'table_id': table.id,
                      'row_id': response_json['id']
                  })
    response = api_client.patch(url,
                                {f'field_{field.id}': select_options[1].id},
                                format='json',
                                HTTP_AUTHORIZATION=f'JWT {token}')
    response_json = response.json()
    assert response.status_code == HTTP_200_OK
    assert response_json[f'field_{field.id}']['id'] == select_options[1].id
    assert response_json[f'field_{field.id}']['value'] == 'Option 2'
    assert response_json[f'field_{field.id}']['color'] == 'blue'

    url = reverse('api:database:rows:item',
                  kwargs={
                      'table_id': table.id,
                      'row_id': response_json['id']
                  })
    response = api_client.patch(url, {f'field_{field.id}': None},
                                format='json',
                                HTTP_AUTHORIZATION=f'JWT {token}')
    response_json = response.json()
    assert response.status_code == HTTP_200_OK
    assert response_json[f'field_{field.id}'] is None

    url = reverse('api:database:rows:item',
                  kwargs={
                      'table_id': table.id,
                      'row_id': response_json['id']
                  })
    response = api_client.delete(url,
                                 format='json',
                                 HTTP_AUTHORIZATION=f'JWT {token}')
    assert response.status_code == HTTP_204_NO_CONTENT
    assert SelectOption.objects.all().count() == 3
コード例 #16
0
def test_phone_number_field_type(data_fixture):
    user = data_fixture.create_user()
    table = data_fixture.create_database_table(user=user)
    data_fixture.create_database_table(user=user, database=table.database)

    field_handler = FieldHandler()
    row_handler = RowHandler()

    text_field = field_handler.create_field(user=user, table=table,
                                            order=1,
                                            type_name='text',
                                            name='name')
    phone_number_field = field_handler.create_field(user=user, table=table,
                                                    type_name='phone_number',
                                                    name='phonenumber')
    email_field = field_handler.create_field(user=user, table=table,
                                             type_name='email',
                                             name='email')
    number_field = data_fixture.create_number_field(table=table, order=1,
                                                    number_negative=True, name="number")

    assert len(PhoneNumberField.objects.all()) == 1
    model = table.get_model(attribute_names=True)

    with pytest.raises(ValidationError):
        row_handler.create_row(user=user, table=table, values={
            'phonenumber': 'invalid phone number'
        }, model=model)

    with pytest.raises(ValidationError):
        row_handler.create_row(user=user, table=table, values={
            'phonenumber': 'Phone: 2312321 2349432 '
        }, model=model)
    with pytest.raises(ValidationError):
        row_handler.create_row(user=user, table=table, values={
            'phonenumber': '1' * (PhoneNumberFieldType.MAX_PHONE_NUMBER_LENGTH+1)
        }, model=model)

    max_length_phone_number = '1' * PhoneNumberFieldType.MAX_PHONE_NUMBER_LENGTH
    row_handler.create_row(user=user, table=table, values={
        'name': '+45(1424) 322314 324234',
        'phonenumber': max_length_phone_number,
        'number': 1234534532,
        'email': '*****@*****.**'
    }, model=model)
    row_handler.create_row(user=user, table=table, values={
        'name': 'some text which should be blanked out after conversion',
        'phonenumber': '1234567890 NnXx,+._*()#=;/ -',
        'number': 0
    }, model=model)
    row_handler.create_row(user=user, table=table, values={
        'name': max_length_phone_number,
        'phonenumber': '',
        'number': -10230450,
    }, model=model)
    row_handler.create_row(user=user, table=table, values={
        'phonenumber': None,
        'name': '1' * (PhoneNumberFieldType.MAX_PHONE_NUMBER_LENGTH+1)

    }, model=model)
    row_handler.create_row(user=user, table=table, values={}, model=model)

    # No actual database type change occurs here as a phone number field is also a text
    # field. Instead the after_update hook is being used to clear out invalid
    # phone numbers.
    field_handler.update_field(user=user, field=text_field,
                               new_type_name='phone_number')

    field_handler.update_field(user=user, field=number_field,
                               new_type_name='phone_number')
    field_handler.update_field(user=user, field=email_field,
                               new_type_name='phone_number')

    model = table.get_model(attribute_names=True)
    rows = model.objects.all()

    assert rows[0].name == '+45(1424) 322314 324234'
    assert rows[0].phonenumber == max_length_phone_number
    assert rows[0].number == '1234534532'
    assert rows[0].email == ''

    assert rows[1].name == ''
    assert rows[1].phonenumber == '1234567890 NnXx,+._*()#=;/ -'
    assert rows[1].number == '0'

    assert rows[2].name == max_length_phone_number
    assert rows[2].phonenumber == ''
    assert rows[2].number == '-10230450'

    assert rows[3].name == ''
    assert rows[3].phonenumber == ''
    assert rows[3].number == ''

    field_handler.delete_field(user=user, field=phone_number_field)
    assert len(PhoneNumberField.objects.all()) == 3
コード例 #17
0
def test_file_field_type(data_fixture):
    user = data_fixture.create_user()
    table = data_fixture.create_database_table(user=user)
    user_file_1 = data_fixture.create_user_file()
    user_file_2 = data_fixture.create_user_file()
    user_file_3 = data_fixture.create_user_file()

    field_handler = FieldHandler()
    row_handler = RowHandler()

    file = field_handler.create_field(user=user, table=table, type_name='file',
                                      name='File')

    assert FileField.objects.all().count() == 1
    model = table.get_model(attribute_names=True)

    with pytest.raises(ValidationError):
        row_handler.create_row(user=user, table=table, values={
            'file': 'not_a_json'
        }, model=model)

    with pytest.raises(ValidationError):
        row_handler.create_row(user=user, table=table, values={
            'file': {}
        }, model=model)

    with pytest.raises(ValidationError):
        row_handler.create_row(user=user, table=table, values={
            'file': [{'no_name': 'test'}]
        }, model=model)

    with pytest.raises(InvalidUserFileNameError):
        row_handler.create_row(user=user, table=table, values={
            'file': [{'name': 'wrongfilename.jpg'}]
        }, model=model)

    with pytest.raises(UserFileDoesNotExist):
        row_handler.create_row(user=user, table=table, values={
            'file': [{'name': 'file_name.jpg'}]
        }, model=model)

    row = row_handler.create_row(user=user, table=table, values={
        'file': [{'name': user_file_1.name}]
    }, model=model)
    assert row.file[0]['visible_name'] == user_file_1.original_name
    del row.file[0]['visible_name']
    assert row.file[0] == user_file_1.serialize()

    row = row_handler.create_row(user=user, table=table, values={
        'file': [
            {'name': user_file_2.name},
            {'name': user_file_1.name},
            {'name': user_file_1.name}
        ]
    }, model=model)
    assert row.file[0]['visible_name'] == user_file_2.original_name
    assert row.file[1]['visible_name'] == user_file_1.original_name
    assert row.file[2]['visible_name'] == user_file_1.original_name
    del row.file[0]['visible_name']
    del row.file[1]['visible_name']
    del row.file[2]['visible_name']
    assert row.file[0] == user_file_2.serialize()
    assert row.file[1] == user_file_1.serialize()
    assert row.file[2] == user_file_1.serialize()

    row = row_handler.create_row(user=user, table=table, values={
        'file': [
            {'name': user_file_1.name},
            {'name': user_file_3.name},
            {'name': user_file_2.name}
        ]
    }, model=model)
    assert row.file[0]['visible_name'] == user_file_1.original_name
    assert row.file[1]['visible_name'] == user_file_3.original_name
    assert row.file[2]['visible_name'] == user_file_2.original_name
    del row.file[0]['visible_name']
    del row.file[1]['visible_name']
    del row.file[2]['visible_name']
    assert row.file[0] == user_file_1.serialize()
    assert row.file[1] == user_file_3.serialize()
    assert row.file[2] == user_file_2.serialize()

    row = row_handler.update_row(user=user, table=table, row_id=row.id, values={
        'file': [
            {'name': user_file_1.name, 'visible_name': 'not_original.jpg'},
        ]
    }, model=model)
    assert row.file[0]['visible_name'] == 'not_original.jpg'
    del row.file[0]['visible_name']
    assert row.file[0] == user_file_1.serialize()

    assert model.objects.all().count() == 3
    field_handler.delete_field(user=user, field=file)
    assert FileField.objects.all().count() == 0
    model.objects.all().delete()

    text = field_handler.create_field(user=user, table=table, type_name='text',
                                      name='Text')
    model = table.get_model(attribute_names=True)

    row = row_handler.create_row(user=user, table=table, values={
        'text': 'Some random text'
    }, model=model)
    row_handler.create_row(user=user, table=table, values={
        'text': '["Not compatible"]'
    }, model=model)
    row_handler.create_row(user=user, table=table, values={
        'text': json.dumps(user_file_1.serialize())
    }, model=model)

    file = field_handler.update_field(user=user, table=table, field=text,
                                      new_type_name='file', name='File')
    model = table.get_model(attribute_names=True)
    results = model.objects.all()
    assert results[0].file == []
    assert results[1].file == []
    assert results[2].file == []

    row_handler.update_row(user=user, table=table, row_id=row.id, values={
        'file': [
            {'name': user_file_1.name, 'visible_name': 'not_original.jpg'},
        ]
    }, model=model)

    field_handler.update_field(user=user, table=table, field=file,
                               new_type_name='text', name='text')
    model = table.get_model(attribute_names=True)
    results = model.objects.all()
    assert results[0].text is None
    assert results[1].text is None
    assert results[2].text is None
コード例 #18
0
ファイル: test_field_handler.py プロジェクト: bram2w/baserow
def test_can_convert_between_all_fields(data_fixture):
    """
    A nuclear option test turned off by default to help verify changes made to
    field conversions work in every possible conversion scenario. This test checks
    is possible to convert from every possible field to every other possible field
    including converting to themselves. It only checks that the conversion does not
    raise any exceptions.
    """

    user = data_fixture.create_user()
    database = data_fixture.create_database_application(user=user)
    table = data_fixture.create_database_table(database=database, user=user)
    link_table = data_fixture.create_database_table(database=database,
                                                    user=user)
    data_fixture.create_text_field(table=link_table,
                                   name="text_field",
                                   primary=True)
    handler = FieldHandler()
    row_handler = RowHandler()
    fake = Faker()

    model = table.get_model()
    cache = {}
    # Make a blank row to test empty field conversion also.
    model.objects.create(**{})
    second_row_with_values = model.objects.create(**{})

    # Some baserow field types have multiple different 'modes' which result in
    # different conversion behaviour or entirely different database columns being
    # created. Here the kwargs which control these modes are enumerated so we can then
    # generate every possible type of conversion.
    all_possible_kwargs_per_type = construct_all_possible_field_kwargs(
        link_table)

    i = 1
    for field_type_name, all_possible_kwargs in all_possible_kwargs_per_type.items(
    ):
        for kwargs in all_possible_kwargs:
            for inner_field_type_name in field_type_registry.get_types():
                for inner_kwargs in all_possible_kwargs_per_type[
                        inner_field_type_name]:
                    field_type = field_type_registry.get(field_type_name)
                    from_field = handler.create_field(
                        user=user,
                        table=table,
                        type_name=field_type_name,
                        **kwargs,
                    )
                    random_value = field_type.random_value(
                        from_field, fake, cache)
                    if isinstance(random_value, date):
                        # Faker produces subtypes of date / datetime which baserow
                        # does not want, instead just convert to str.
                        random_value = str(random_value)
                    row_handler.update_row(
                        user=user,
                        table=table,
                        row_id=second_row_with_values.id,
                        values={f"field_{from_field.id}": random_value},
                    )
                    handler.update_field(
                        user=user,
                        field=from_field,
                        new_type_name=inner_field_type_name,
                        **inner_kwargs,
                    )
                    i = i + 1
コード例 #19
0
def test_create_field(data_fixture):
    user = data_fixture.create_user()
    user_2 = data_fixture.create_user()
    table = data_fixture.create_database_table(user=user)

    handler = FieldHandler()
    handler.create_field(user=user,
                         table=table,
                         type_name='text',
                         name='Test text field',
                         text_default='Some default')

    assert Field.objects.all().count() == 1
    assert TextField.objects.all().count() == 1

    text_field = TextField.objects.all().first()
    assert text_field.name == 'Test text field'
    assert text_field.order == 1
    assert text_field.table == table
    assert text_field.text_default == 'Some default'
    assert not text_field.primary

    table_model = table.get_model()
    field_name = f'field_{text_field.id}'
    assert field_name in [
        field.name for field in table_model._meta.get_fields()
    ]

    instance = table_model.objects.create(**{field_name: 'Test 1'})
    assert getattr(instance, field_name) == 'Test 1'

    instance_2 = table_model.objects.create()
    assert getattr(instance_2, field_name) == 'Some default'

    with pytest.raises(ValueError):
        handler.create_field(user=user,
                             table=table,
                             type_name='number',
                             name='Test number field',
                             number_type='NOT_EXISTING')

    with pytest.raises(ValueError):
        handler.create_field(user=user,
                             table=table,
                             type_name='number',
                             name='Test number field',
                             number_type='DECIMAL',
                             number_decimal_places=9999)

    handler.create_field(user=user,
                         table=table,
                         type_name='number',
                         name='Test number field',
                         number_type='INTEGER',
                         number_decimal_places=2,
                         number_negative=True)

    number_field = NumberField.objects.all().first()
    assert number_field.name == 'Test number field'
    assert number_field.order == 2
    assert number_field.table == table
    assert number_field.number_type == 'INTEGER'
    assert number_field.number_decimal_places == 2
    assert number_field.number_negative

    handler.create_field(user=user,
                         table=table,
                         type_name='boolean',
                         name='Test boolean field',
                         random_other_field='WILL_BE_IGNORED')

    boolean_field = BooleanField.objects.all().first()
    assert boolean_field.name == 'Test boolean field'
    assert boolean_field.order == 3
    assert boolean_field.table == table

    assert Field.objects.all().count() == 3
    assert TextField.objects.all().count() == 1
    assert NumberField.objects.all().count() == 1
    assert BooleanField.objects.all().count() == 1

    with pytest.raises(UserNotInGroupError):
        handler.create_field(user=user_2, table=table, type_name='text')

    with pytest.raises(FieldTypeDoesNotExist):
        handler.create_field(user=user, table=table, type_name='UNKNOWN')
コード例 #20
0
def test_email_field_type(data_fixture):
    user = data_fixture.create_user()
    table = data_fixture.create_database_table(user=user)
    table_2 = data_fixture.create_database_table(user=user,
                                                 database=table.database)
    field = data_fixture.create_text_field(table=table, order=1, name='name')

    field_handler = FieldHandler()
    row_handler = RowHandler()

    field_2 = field_handler.create_field(user=user,
                                         table=table,
                                         type_name='email',
                                         name='email')
    number = field_handler.create_field(user=user,
                                        table=table,
                                        type_name='number',
                                        name='number')

    assert len(EmailField.objects.all()) == 1
    model = table.get_model(attribute_names=True)

    with pytest.raises(ValidationError):
        row_handler.create_row(user=user,
                               table=table,
                               values={'email': 'invalid_email'},
                               model=model)

    with pytest.raises(ValidationError):
        row_handler.create_row(user=user,
                               table=table,
                               values={'email': 'invalid@email'},
                               model=model)

    row_0 = row_handler.create_row(user=user,
                                   table=table,
                                   values={
                                       'name':
                                       '*****@*****.**',
                                       'email': '*****@*****.**',
                                       'number': 5
                                   },
                                   model=model)
    row_1 = row_handler.create_row(user=user,
                                   table=table,
                                   values={
                                       'name': 'someuser',
                                       'email': '*****@*****.**',
                                       'number': 10
                                   },
                                   model=model)
    row_2 = row_handler.create_row(user=user,
                                   table=table,
                                   values={
                                       'name': 'http://www.baserow.io',
                                       'email': '*****@*****.**'
                                   },
                                   model=model)
    row_3 = row_handler.create_row(user=user,
                                   table=table,
                                   values={
                                       'name': 'NOT AN EMAIL',
                                       'email': '*****@*****.**'
                                   },
                                   model=model)
    row_4 = row_handler.create_row(user=user,
                                   table=table,
                                   values={
                                       'name': '*****@*****.**',
                                       'email': ''
                                   },
                                   model=model)
    row_5 = row_handler.create_row(user=user,
                                   table=table,
                                   values={
                                       'email': None,
                                   },
                                   model=model)
    row_6 = row_handler.create_row(user=user,
                                   table=table,
                                   values={},
                                   model=model)

    # Convert the text field to a url field so we can check how the conversion of
    # values went.
    field_handler.update_field(user=user, field=field, new_type_name='email')
    field_handler.update_field(user=user, field=number, new_type_name='email')

    model = table.get_model(attribute_names=True)
    rows = model.objects.all()

    assert rows[0].name == '*****@*****.**'
    assert rows[0].email == '*****@*****.**'
    assert rows[0].number == ''

    assert rows[1].name == ''
    assert rows[1].email == '*****@*****.**'
    assert rows[1].number == ''

    assert rows[2].name == ''
    assert rows[2].email == '*****@*****.**'
    assert rows[2].number == ''

    assert rows[3].name == ''
    assert rows[3].email == '*****@*****.**'
    assert rows[3].number == ''

    assert rows[4].name == '*****@*****.**'
    assert rows[4].email == ''
    assert rows[4].number == ''

    assert rows[5].name == ''
    assert rows[5].email == ''
    assert rows[5].number == ''

    assert rows[6].name == ''
    assert rows[6].email == ''
    assert rows[6].number == ''

    field_handler.delete_field(user=user, field=field_2)
    assert len(EmailField.objects.all()) == 2
コード例 #21
0
def test_link_row_field_type(data_fixture):
    user = data_fixture.create_user()
    database = data_fixture.create_database_application(user=user,
                                                        name='Placeholder')
    table = data_fixture.create_database_table(name='Example',
                                               database=database)
    customers_table = data_fixture.create_database_table(name='Customers',
                                                         database=database)
    cars_table = data_fixture.create_database_table(name='Cars',
                                                    database=database)
    unrelated_table_1 = data_fixture.create_database_table(name='Unrelated')

    field_handler = FieldHandler()
    row_handler = RowHandler()

    # Create a primary field and some example data for the customers table.
    customers_primary_field = field_handler.create_field(user=user,
                                                         table=customers_table,
                                                         type_name='text',
                                                         name='Name',
                                                         primary=True)
    customers_row_1 = row_handler.create_row(
        user=user,
        table=customers_table,
        values={f'field_{customers_primary_field.id}': 'John'})
    customers_row_2 = row_handler.create_row(
        user=user,
        table=customers_table,
        values={f'field_{customers_primary_field.id}': 'Jane'})

    # Create a primary field and some example data for the cars table.
    cars_primary_field = field_handler.create_field(user=user,
                                                    table=cars_table,
                                                    type_name='text',
                                                    name='Name',
                                                    primary=True)
    cars_row_1 = row_handler.create_row(
        user=user,
        table=cars_table,
        values={f'field_{cars_primary_field.id}': 'BMW'})
    cars_row_2 = row_handler.create_row(
        user=user,
        table=cars_table,
        values={f'field_{cars_primary_field.id}': 'Audi'})

    with pytest.raises(LinkRowTableNotProvided):
        field_handler.create_field(user=user,
                                   table=table,
                                   type_name='link_row',
                                   name='Without table')

    with pytest.raises(LinkRowTableNotInSameDatabase):
        field_handler.create_field(user=user,
                                   table=table,
                                   type_name='link_row',
                                   name='Unrelated',
                                   link_row_table=unrelated_table_1)

    link_field_1 = field_handler.create_field(user=user,
                                              table=table,
                                              type_name='link_row',
                                              name='Customer',
                                              link_row_table=customers_table)
    link_field_2 = field_handler.create_field(user=user,
                                              table=table,
                                              type_name='link_row',
                                              name='Customer',
                                              link_row_table=customers_table)

    assert link_field_1.link_row_related_field.name == 'Example'
    assert link_field_2.link_row_related_field.name == 'Example'

    connection = connections['default']
    tables = connection.introspection.table_names()

    assert (link_field_1.through_table_name ==
            link_field_1.link_row_related_field.through_table_name)
    assert (link_field_2.through_table_name ==
            link_field_2.link_row_related_field.through_table_name)

    assert link_field_1.through_table_name in tables
    assert link_field_2.through_table_name in tables

    model = table.get_model()
    table_row = model.objects.create()

    getattr(table_row, f'field_{link_field_1.id}').add(customers_row_1.id)
    results = getattr(table_row, f'field_{link_field_1.id}').all()
    assert len(results) == 1
    assert getattr(results[0], f'field_{customers_primary_field.id}') == 'John'

    getattr(table_row, f'field_{link_field_2.id}').add(customers_row_1.id,
                                                       customers_row_2.id)
    results = getattr(table_row, f'field_{link_field_2.id}').all()
    assert len(results) == 2
    assert getattr(results[0], f'field_{customers_primary_field.id}') == 'John'
    assert getattr(results[1], f'field_{customers_primary_field.id}') == 'Jane'

    table_row_2 = model.objects.create()
    getattr(table_row_2, f'field_{link_field_1.id}').add(customers_row_2.id)
    results = getattr(table_row_2, f'field_{link_field_1.id}').all()
    assert len(results) == 1
    assert getattr(results[0], f'field_{customers_primary_field.id}') == 'Jane'

    # Going to change only the name of the field. This should not result in any errors
    # of schema changes.
    link_field_1 = field_handler.update_field(user,
                                              link_field_1,
                                              name='Customer 2')

    with pytest.raises(LinkRowTableNotInSameDatabase):
        field_handler.update_field(user,
                                   link_field_1,
                                   link_row_table=unrelated_table_1)

    model = table.get_model()
    assert model.objects.all().count() == 2

    # Change the table, this should destroy all relations.
    old_link_field_1_relation_id = link_field_1.link_row_relation_id
    link_field_1 = field_handler.update_field(user,
                                              link_field_1,
                                              link_row_table=cars_table)

    model = table.get_model()
    table_rows = model.objects.all()
    table_row = table_rows[0]
    table_row_2 = table_rows[1]

    assert link_field_1.link_row_table.id == cars_table.id
    assert link_field_1.link_row_relation_id == old_link_field_1_relation_id
    assert getattr(table_row, f'field_{link_field_1.id}').all().count() == 0
    assert getattr(table_row, f'field_{link_field_2.id}').all().count() == 2
    assert getattr(table_row_2, f'field_{link_field_1.id}').all().count() == 0
    assert getattr(table_row_2, f'field_{link_field_2.id}').all().count() == 0

    link_field_2 = field_handler.update_field(user,
                                              link_field_2,
                                              new_type_name='text')

    model = table.get_model()
    table_row = model.objects.all().first()

    assert getattr(table_row, f'field_{link_field_2.id}') is None
    assert LinkRowField.objects.all().count() == 2

    setattr(table_row, f'field_{link_field_2.id}', 'Text value')
    table_row.save()
    assert getattr(table_row, f'field_{link_field_2.id}') == 'Text value'

    # Delete the existing field. Alter that the related field should be deleted and
    # no table named _relation_ should exist.
    field_handler.delete_field(user, link_field_1)
    assert LinkRowField.objects.all().count() == 0
    for t in connection.introspection.table_names():
        if '_relation_' in t:
            assert False

    # Change a the text field back into a link row field.
    link_field_2 = field_handler.update_field(user,
                                              link_field_2,
                                              new_type_name='link_row',
                                              link_row_table=customers_table)

    assert link_field_2.link_row_related_field.name == 'Example'
    assert (link_field_2.through_table_name ==
            link_field_2.link_row_related_field.through_table_name)
    assert link_field_2.through_table_name in connection.introspection.table_names(
    )
    assert LinkRowField.objects.all().count() == 2

    model = table.get_model()
    table_row = model.objects.all().first()

    getattr(table_row, f'field_{link_field_2.id}').add(customers_row_1.id,
                                                       customers_row_2.id)
    results = getattr(table_row, f'field_{link_field_2.id}').all()
    assert len(results) == 2
    assert getattr(results[0], f'field_{customers_primary_field.id}') == 'John'
    assert getattr(results[1], f'field_{customers_primary_field.id}') == 'Jane'
コード例 #22
0
def test_primary_single_select_field_with_link_row_field(
        api_client, data_fixture, django_assert_num_queries):
    """
    We expect the relation to a table that has a single select field to work.
    """

    user, token = data_fixture.create_user_and_token()
    database = data_fixture.create_database_application(user=user,
                                                        name='Placeholder')
    example_table = data_fixture.create_database_table(name='Example',
                                                       database=database)
    customers_table = data_fixture.create_database_table(name='Customers',
                                                         database=database)

    field_handler = FieldHandler()
    row_handler = RowHandler()

    data_fixture.create_text_field(name='Name',
                                   table=example_table,
                                   primary=True)
    customers_primary = field_handler.create_field(user=user,
                                                   table=customers_table,
                                                   type_name='single_select',
                                                   select_options=[{
                                                       'value':
                                                       'Option 1',
                                                       'color':
                                                       'red'
                                                   }, {
                                                       'value':
                                                       'Option 2',
                                                       'color':
                                                       'blue'
                                                   }, {
                                                       'value':
                                                       'Option 3',
                                                       'color':
                                                       'orange'
                                                   }],
                                                   primary=True)
    link_row_field = field_handler.create_field(user=user,
                                                table=example_table,
                                                type_name='link_row',
                                                link_row_table=customers_table)
    select_options = customers_primary.select_options.all()

    customers_row_1 = row_handler.create_row(
        user=user,
        table=customers_table,
        values={f'field_{customers_primary.id}': select_options[0].id})
    customers_row_2 = row_handler.create_row(
        user=user,
        table=customers_table,
        values={f'field_{customers_primary.id}': select_options[1].id})
    customers_row_3 = row_handler.create_row(
        user=user,
        table=customers_table,
        values={f'field_{customers_primary.id}': select_options[2].id})
    row_handler.create_row(user,
                           table=example_table,
                           values={
                               f'field_{link_row_field.id}':
                               [customers_row_1.id, customers_row_2.id]
                           })
    row_handler.create_row(
        user,
        table=example_table,
        values={f'field_{link_row_field.id}': [customers_row_1.id]})
    row_handler.create_row(
        user,
        table=example_table,
        values={f'field_{link_row_field.id}': [customers_row_3.id]})

    model = example_table.get_model()
    queryset = model.objects.all().enhance_by_fields()
    serializer_class = get_row_serializer_class(model,
                                                RowSerializer,
                                                is_response=True)

    with django_assert_num_queries(3):
        serializer = serializer_class(queryset, many=True)
        serializer.data

    response = api_client.get(reverse('api:database:rows:list',
                                      kwargs={'table_id': example_table.id}),
                              format='json',
                              HTTP_AUTHORIZATION=f'JWT {token}')
    response_json = response.json()

    assert (response_json['results'][0][f'field_{link_row_field.id}'][0]
            ['value'] == 'Option 1')
    assert (response_json['results'][0][f'field_{link_row_field.id}'][1]
            ['value'] == 'Option 2')
    assert (response_json['results'][1][f'field_{link_row_field.id}'][0]
            ['value'] == 'Option 1')
    assert (response_json['results'][2][f'field_{link_row_field.id}'][0]
            ['value'] == 'Option 3')
コード例 #23
0
def test_link_row_field_type_api_row_views(api_client, data_fixture):
    user, token = data_fixture.create_user_and_token()
    database = data_fixture.create_database_application(user=user,
                                                        name='Placeholder')
    example_table = data_fixture.create_database_table(name='Example',
                                                       database=database)
    customers_table = data_fixture.create_database_table(name='Customers',
                                                         database=database)
    grid = data_fixture.create_grid_view(table=example_table)

    example_primary = data_fixture.create_text_field(name='Name',
                                                     table=example_table,
                                                     primary=True)
    customers_primary = data_fixture.create_text_field(name='Customer name',
                                                       table=customers_table,
                                                       primary=True)

    field_handler = FieldHandler()
    row_handler = RowHandler()

    link_row_field = field_handler.create_field(user=user,
                                                table=example_table,
                                                type_name='link_row',
                                                link_row_table=customers_table)

    customers_row_1 = row_handler.create_row(
        user=user,
        table=customers_table,
        values={f'field_{customers_primary.id}': 'John Doe'})
    customers_row_2 = row_handler.create_row(
        user=user,
        table=customers_table,
        values={f'field_{customers_primary.id}': 'Jane Doe'})
    customers_row_3 = row_handler.create_row(user=user, table=customers_table)

    response = api_client.post(reverse('api:database:rows:list',
                                       kwargs={'table_id': example_table.id}),
                               {
                                   f'field_{link_row_field.id}': 'Random',
                               },
                               format='json',
                               HTTP_AUTHORIZATION=f'JWT {token}')
    response_json = response.json()
    assert response.status_code == HTTP_400_BAD_REQUEST
    assert response_json['error'] == 'ERROR_REQUEST_BODY_VALIDATION'
    assert (response_json['detail'][f'field_{link_row_field.id}'][0]['code'] ==
            'not_a_list')

    response = api_client.post(reverse('api:database:rows:list',
                                       kwargs={'table_id': example_table.id}),
                               {
                                   f'field_{link_row_field.id}': ['a'],
                               },
                               format='json',
                               HTTP_AUTHORIZATION=f'JWT {token}')
    response_json = response.json()
    assert response.status_code == HTTP_400_BAD_REQUEST
    assert response_json['error'] == 'ERROR_REQUEST_BODY_VALIDATION'
    assert (response_json['detail'][f'field_{link_row_field.id}']['0'][0]
            ['code'] == 'invalid')

    response = api_client.post(reverse(
        'api:database:rows:list', kwargs={'table_id': example_table.id}), {
            f'field_{link_row_field.id}':
            [customers_row_1.id, customers_row_2.id, 999],
        },
                               format='json',
                               HTTP_AUTHORIZATION=f'JWT {token}')
    response_json = response.json()
    row_id = response_json['id']
    assert response.status_code == HTTP_200_OK
    assert len(response_json[f'field_{link_row_field.id}']) == 2
    assert response_json[f'field_{link_row_field.id}'][0][
        'id'] == customers_row_1.id
    assert response_json[f'field_{link_row_field.id}'][0][
        'value'] == 'John Doe'
    assert response_json[f'field_{link_row_field.id}'][1][
        'id'] == customers_row_2.id
    assert response_json[f'field_{link_row_field.id}'][1][
        'value'] == 'Jane Doe'

    model = example_table.get_model()
    assert model.objects.all().count() == 1

    url = reverse('api:database:rows:item',
                  kwargs={
                      'table_id': example_table.id,
                      'row_id': row_id
                  })
    response = api_client.patch(url, {
        f'field_{link_row_field.id}': [],
    },
                                format='json',
                                HTTP_AUTHORIZATION=f'JWT {token}')
    response_json = response.json()
    assert response.status_code == HTTP_200_OK
    assert len(response_json[f'field_{link_row_field.id}']) == 0

    url = reverse('api:database:rows:item',
                  kwargs={
                      'table_id': example_table.id,
                      'row_id': row_id
                  })
    response = api_client.patch(url, {
        f'field_{link_row_field.id}': [customers_row_2.id, customers_row_3.id],
    },
                                format='json',
                                HTTP_AUTHORIZATION=f'JWT {token}')
    response_json = response.json()
    assert response.status_code == HTTP_200_OK
    assert len(response_json[f'field_{link_row_field.id}']) == 2
    assert response_json[f'field_{link_row_field.id}'][0][
        'id'] == customers_row_2.id
    assert response_json[f'field_{link_row_field.id}'][0][
        'value'] == 'Jane Doe'
    assert response_json[f'field_{link_row_field.id}'][1][
        'id'] == customers_row_3.id
    assert not response_json[f'field_{link_row_field.id}'][1]['value']

    url = reverse('api:database:views:grid:list', kwargs={'view_id': grid.id})
    response = api_client.get(url, **{'HTTP_AUTHORIZATION': f'JWT {token}'})
    response_json = response.json()
    assert response.status_code == HTTP_200_OK
    assert response_json['count'] == 1
    assert response_json['results'][0]['id'] == row_id
    assert len(response_json['results'][0][f'field_{link_row_field.id}']) == 2

    url = reverse('api:database:rows:item',
                  kwargs={
                      'table_id': example_table.id,
                      'row_id': row_id
                  })
    response = api_client.delete(url, HTTP_AUTHORIZATION=f'JWT {token}')
    assert response.status_code == HTTP_204_NO_CONTENT
    assert model.objects.all().count() == 0

    response = api_client.post(reverse('api:database:rows:list',
                                       kwargs={'table_id': example_table.id}),
                               {},
                               format='json',
                               HTTP_AUTHORIZATION=f'JWT {token}')
    response_json = response.json()
    assert response.status_code == HTTP_200_OK
    assert len(response_json[f'field_{link_row_field.id}']) == 0
コード例 #24
0
ファイル: test_field_handler.py プロジェクト: bram2w/baserow
def test_create_field(send_mock, data_fixture):
    user = data_fixture.create_user()
    user_2 = data_fixture.create_user()
    table = data_fixture.create_database_table(user=user)

    handler = FieldHandler()
    field = handler.create_field(
        user=user,
        table=table,
        type_name="text",
        name="Test text field",
        text_default="Some default",
    )

    send_mock.assert_called_once()
    assert send_mock.call_args[1]["field"].id == field.id
    assert send_mock.call_args[1]["user"].id == user.id

    assert Field.objects.all().count() == 1
    assert TextField.objects.all().count() == 1

    text_field = TextField.objects.all().first()
    assert text_field.name == "Test text field"
    assert text_field.order == 1
    assert text_field.table == table
    assert text_field.text_default == "Some default"
    assert not text_field.primary

    table_model = table.get_model()
    field_name = f"field_{text_field.id}"
    assert field_name in [
        field.name for field in table_model._meta.get_fields()
    ]

    instance = table_model.objects.create(**{field_name: "Test 1"})
    assert getattr(instance, field_name) == "Test 1"

    instance_2 = table_model.objects.create()
    assert getattr(instance_2, field_name) == "Some default"

    with pytest.raises(ValueError):
        handler.create_field(
            user=user,
            table=table,
            type_name="number",
            name="Test number field",
            number_type="NOT_EXISTING",
        )

    with pytest.raises(ValueError):
        handler.create_field(
            user=user,
            table=table,
            type_name="number",
            name="Test number field",
            number_type="DECIMAL",
            number_decimal_places=9999,
        )

    handler.create_field(
        user=user,
        table=table,
        type_name="number",
        name="Test number field",
        number_type="INTEGER",
        number_decimal_places=2,
        number_negative=True,
    )

    number_field = NumberField.objects.all().first()
    assert number_field.name == "Test number field"
    assert number_field.order == 2
    assert number_field.table == table
    assert number_field.number_type == "INTEGER"
    assert number_field.number_decimal_places == 2
    assert number_field.number_negative

    handler.create_field(
        user=user,
        table=table,
        type_name="boolean",
        name="Test boolean field",
        random_other_field="WILL_BE_IGNORED",
    )

    boolean_field = BooleanField.objects.all().first()
    assert boolean_field.name == "Test boolean field"
    assert boolean_field.order == 3
    assert boolean_field.table == table

    assert Field.objects.all().count() == 3
    assert TextField.objects.all().count() == 1
    assert NumberField.objects.all().count() == 1
    assert BooleanField.objects.all().count() == 1

    field_limit = settings.MAX_FIELD_LIMIT
    settings.MAX_FIELD_LIMIT = 2

    with pytest.raises(MaxFieldLimitExceeded):
        handler.create_field(
            user=user,
            table=table,
            type_name="text",
            name="Test text field",
            text_default="Some default",
        )

    settings.MAX_FIELD_LIMIT = field_limit

    with pytest.raises(UserNotInGroup):
        handler.create_field(user=user_2, table=table, type_name="text")

    with pytest.raises(FieldTypeDoesNotExist):
        handler.create_field(user=user, table=table, type_name="UNKNOWN")
コード例 #25
0
def test_link_row_field_type_rows(data_fixture):
    user = data_fixture.create_user()
    database = data_fixture.create_database_application(user=user, name="Placeholder")
    example_table = data_fixture.create_database_table(
        name="Example", database=database
    )
    customers_table = data_fixture.create_database_table(
        name="Customers", database=database
    )
    data_fixture.create_text_field(name="Name", table=customers_table, primary=True)
    users_table = data_fixture.create_database_table(name="Users", database=database)

    field_handler = FieldHandler()
    row_handler = RowHandler()

    link_row_field = field_handler.create_field(
        user=user,
        table=example_table,
        type_name="link_row",
        link_row_table=customers_table,
    )

    customers_row_1 = row_handler.create_row(user=user, table=customers_table)
    customers_row_2 = row_handler.create_row(user=user, table=customers_table)
    customers_row_3 = row_handler.create_row(user=user, table=customers_table)

    row = row_handler.create_row(
        user=user,
        table=example_table,
        values={
            f"field_{link_row_field.id}": [customers_row_1.id, customers_row_2.id],
        },
    )
    row_2 = row_handler.create_row(
        user=user,
        table=example_table,
        values={
            f"field_{link_row_field.id}": [customers_row_1.id],
        },
    )

    example_table.name = "Example2"
    example_table.save()

    customers_table.name = "Customers2"
    customers_table.save()

    row_1_all = getattr(row, f"field_{link_row_field.id}").all()
    row_2_all = getattr(row_2, f"field_{link_row_field.id}").all()
    row_1_ids = [i.id for i in row_1_all]
    row_2_ids = [i.id for i in row_2_all]

    assert row_1_all.count() == 2
    assert row_2_all.count() == 1
    assert customers_row_1.id in row_1_ids
    assert customers_row_2.id in row_1_ids
    assert customers_row_1.id in row_2_ids

    row = row_handler.update_row(
        user=user,
        table=example_table,
        row_id=row.id,
        values={f"field_{link_row_field.id}": [customers_row_3.id]},
    )
    row_2 = row_handler.update_row(
        user=user,
        table=example_table,
        row_id=row_2.id,
        values={f"field_{link_row_field.id}": [customers_row_2.id, customers_row_1.id]},
    )

    row_1_all = getattr(row, f"field_{link_row_field.id}").all()
    row_2_all = getattr(row_2, f"field_{link_row_field.id}").all()
    row_1_ids = [i.id for i in row_1_all]
    row_2_ids = [i.id for i in row_2_all]

    assert row_1_all.count() == 1
    assert row_2_all.count() == 2
    assert customers_row_3.id in row_1_ids
    assert customers_row_1.id in row_2_ids
    assert customers_row_2.id in row_2_ids

    # Check if the relations are there via the customers table.
    customers_table.refresh_from_db()
    customers_model = customers_table.get_model()
    related_field = link_row_field.link_row_related_field
    customer_rows = customers_model.objects.all()

    assert customer_rows.count() == 3

    customers_row_1 = customer_rows[0]
    customers_row_2 = customer_rows[1]
    customers_row_3 = customer_rows[2]

    customer_row_1_all = getattr(customers_row_1, f"field_{related_field.id}").all()
    customer_row_2_all = getattr(customers_row_2, f"field_{related_field.id}").all()
    customer_row_3_all = getattr(customers_row_3, f"field_{related_field.id}").all()

    assert customer_row_1_all.count() == 1
    assert customer_row_2_all.count() == 1
    assert customer_row_3_all.count() == 1

    customers_row_1_ids = [i.id for i in customer_row_1_all]
    customers_row_2_ids = [i.id for i in customer_row_2_all]
    customers_row_3_ids = [i.id for i in customer_row_3_all]

    assert row_2.id in customers_row_1_ids
    assert row_2.id in customers_row_2_ids
    assert row.id in customers_row_3_ids

    # When changing the link row table table all the existing relations should be
    # deleted.
    link_row_field = field_handler.update_field(
        user=user,
        field=link_row_field,
        type_name="link_row",
        link_row_table=users_table,
    )

    example_table.refresh_from_db()
    model = example_table.get_model()
    rows = model.objects.all()
    row = rows[0]
    row_2 = rows[1]

    assert getattr(row, f"field_{link_row_field.id}").all().count() == 0
    assert getattr(row_2, f"field_{link_row_field.id}").all().count() == 0

    # Just check if the field can be deleted can be deleted.
    field_handler.delete_field(user=user, field=link_row_field)
    # We expect only the primary field to be left.
    assert Field.objects.all().count() == 1
コード例 #26
0
def test_single_select_field_type_rows(data_fixture,
                                       django_assert_num_queries):
    user = data_fixture.create_user()
    database = data_fixture.create_database_application(user=user,
                                                        name='Placeholder')
    table = data_fixture.create_database_table(name='Example',
                                               database=database)
    other_select_option = data_fixture.create_select_option()

    field_handler = FieldHandler()
    row_handler = RowHandler()

    field = field_handler.create_field(user=user,
                                       table=table,
                                       type_name='single_select',
                                       select_options=[{
                                           'value': 'Option 1',
                                           'color': 'red'
                                       }, {
                                           'value': 'Option 2',
                                           'color': 'blue'
                                       }])

    with pytest.raises(ValidationError):
        row_handler.create_row(user=user,
                               table=table,
                               values={f'field_{field.id}': 999999})

    with pytest.raises(ValidationError):
        row_handler.create_row(
            user=user,
            table=table,
            values={f'field_{field.id}': other_select_option.id})

    select_options = field.select_options.all()
    row = row_handler.create_row(
        user=user,
        table=table,
        values={f'field_{field.id}': select_options[0].id})

    assert getattr(row, f'field_{field.id}').id == select_options[0].id
    assert getattr(row, f'field_{field.id}').value == select_options[0].value
    assert getattr(row, f'field_{field.id}').color == select_options[0].color
    assert getattr(row, f'field_{field.id}_id') == select_options[0].id

    field = field_handler.update_field(user=user,
                                       field=field,
                                       select_options=[
                                           {
                                               'value': 'Option 3',
                                               'color': 'orange'
                                           },
                                           {
                                               'value': 'Option 4',
                                               'color': 'purple'
                                           },
                                       ])

    select_options = field.select_options.all()
    row_2 = row_handler.create_row(
        user=user,
        table=table,
        values={f'field_{field.id}': select_options[0].id})
    assert getattr(row_2, f'field_{field.id}').id == select_options[0].id
    assert getattr(row_2, f'field_{field.id}').value == select_options[0].value
    assert getattr(row_2, f'field_{field.id}').color == select_options[0].color
    assert getattr(row_2, f'field_{field.id}_id') == select_options[0].id

    row_3 = row_handler.create_row(
        user=user,
        table=table,
        values={f'field_{field.id}': select_options[1].id})
    assert getattr(row_3, f'field_{field.id}').id == select_options[1].id
    assert getattr(row_3, f'field_{field.id}_id') == select_options[1].id

    row_4 = row_handler.create_row(
        user=user,
        table=table,
        values={f'field_{field.id}': select_options[0].id})
    assert getattr(row_4, f'field_{field.id}').id == select_options[0].id
    assert getattr(row_4, f'field_{field.id}_id') == select_options[0].id

    model = table.get_model()

    with django_assert_num_queries(2):
        rows = list(model.objects.all().enhance_by_fields())

    assert getattr(rows[0], f'field_{field.id}') is None
    assert getattr(rows[1], f'field_{field.id}').id == select_options[0].id
    assert getattr(rows[2], f'field_{field.id}').id == select_options[1].id
    assert getattr(rows[3], f'field_{field.id}').id == select_options[0].id

    row.refresh_from_db()
    assert getattr(row, f'field_{field.id}') is None
    assert getattr(row, f'field_{field.id}_id') is None

    field = field_handler.update_field(user=user,
                                       field=field,
                                       new_type_name='text')
    assert field.select_options.all().count() == 0
    model = table.get_model()
    rows = model.objects.all().enhance_by_fields()
    assert getattr(rows[0], f'field_{field.id}') is None
    assert getattr(rows[1], f'field_{field.id}') == 'Option 3'
    assert getattr(rows[2], f'field_{field.id}') == 'Option 4'
    assert getattr(rows[3], f'field_{field.id}') == 'Option 3'

    field = field_handler.update_field(user=user,
                                       field=field,
                                       new_type_name='single_select',
                                       select_options=[
                                           {
                                               'value': 'Option 2',
                                               'color': 'blue'
                                           },
                                           {
                                               'value': 'option 3',
                                               'color': 'purple'
                                           },
                                       ])
    assert field.select_options.all().count() == 2
    model = table.get_model()
    rows = model.objects.all().enhance_by_fields()
    select_options = field.select_options.all()
    assert getattr(rows[0], f'field_{field.id}') is None
    assert getattr(rows[1], f'field_{field.id}').id == select_options[1].id
    assert getattr(rows[2], f'field_{field.id}') is None
    assert getattr(rows[3], f'field_{field.id}').id == select_options[1].id

    row_4 = row_handler.update_row(user=user,
                                   table=table,
                                   row_id=row_4.id,
                                   values={f'field_{field.id}': None})
    assert getattr(row_4, f'field_{field.id}') is None
    assert getattr(row_4, f'field_{field.id}_id') is None

    field = field_handler.update_field(user=user,
                                       field=field,
                                       new_type_name='text')
    assert field.select_options.all().count() == 0
    model = table.get_model()
    rows = model.objects.all().enhance_by_fields()
    assert getattr(rows[0], f'field_{field.id}') is None
    assert getattr(rows[1], f'field_{field.id}') == 'option 3'
    assert getattr(rows[2], f'field_{field.id}') is None
    assert getattr(rows[3], f'field_{field.id}') is None

    field = field_handler.update_field(user=user,
                                       field=field,
                                       new_type_name='single_select')
    assert field.select_options.all().count() == 0
    model = table.get_model()
    rows = model.objects.all().enhance_by_fields()
    assert getattr(rows[0], f'field_{field.id}') is None
    assert getattr(rows[1], f'field_{field.id}') is None
    assert getattr(rows[2], f'field_{field.id}') is None
    assert getattr(rows[3], f'field_{field.id}') is None
コード例 #27
0
def test_link_row_field_type(data_fixture):
    user = data_fixture.create_user()
    database = data_fixture.create_database_application(user=user, name="Placeholder")
    table = data_fixture.create_database_table(name="Example", database=database)
    customers_table = data_fixture.create_database_table(
        name="Customers", database=database
    )
    cars_table = data_fixture.create_database_table(name="Cars", database=database)
    unrelated_table_1 = data_fixture.create_database_table(name="Unrelated")

    field_handler = FieldHandler()
    row_handler = RowHandler()

    # Create a primary field and some example data for the customers table.
    customers_primary_field = field_handler.create_field(
        user=user, table=customers_table, type_name="text", name="Name", primary=True
    )
    customers_row_1 = row_handler.create_row(
        user=user,
        table=customers_table,
        values={f"field_{customers_primary_field.id}": "John"},
    )
    customers_row_2 = row_handler.create_row(
        user=user,
        table=customers_table,
        values={f"field_{customers_primary_field.id}": "Jane"},
    )

    # Create a primary field and some example data for the cars table.
    cars_primary_field = field_handler.create_field(
        user=user, table=cars_table, type_name="text", name="Name", primary=True
    )
    row_handler.create_row(
        user=user, table=cars_table, values={f"field_{cars_primary_field.id}": "BMW"}
    )
    row_handler.create_row(
        user=user, table=cars_table, values={f"field_{cars_primary_field.id}": "Audi"}
    )

    with pytest.raises(LinkRowTableNotProvided):
        field_handler.create_field(
            user=user, table=table, type_name="link_row", name="Without table"
        )

    with pytest.raises(LinkRowTableNotInSameDatabase):
        field_handler.create_field(
            user=user,
            table=table,
            type_name="link_row",
            name="Unrelated",
            link_row_table=unrelated_table_1,
        )

    link_field_1 = field_handler.create_field(
        user=user,
        table=table,
        type_name="link_row",
        name="Customer",
        link_row_table=customers_table,
    )
    link_field_2 = field_handler.create_field(
        user=user,
        table=table,
        type_name="link_row",
        name="Customer",
        link_row_table=customers_table,
    )

    assert link_field_1.link_row_related_field.name == "Example"
    assert link_field_2.link_row_related_field.name == "Example"

    connection = connections["default"]
    tables = connection.introspection.table_names()

    assert (
        link_field_1.through_table_name
        == link_field_1.link_row_related_field.through_table_name
    )
    assert (
        link_field_2.through_table_name
        == link_field_2.link_row_related_field.through_table_name
    )

    assert link_field_1.through_table_name in tables
    assert link_field_2.through_table_name in tables

    model = table.get_model()
    table_row = model.objects.create()

    getattr(table_row, f"field_{link_field_1.id}").add(customers_row_1.id)
    results = getattr(table_row, f"field_{link_field_1.id}").all()
    assert len(results) == 1
    assert getattr(results[0], f"field_{customers_primary_field.id}") == "John"

    getattr(table_row, f"field_{link_field_2.id}").add(
        customers_row_1.id, customers_row_2.id
    )
    results = getattr(table_row, f"field_{link_field_2.id}").all()
    assert len(results) == 2
    assert getattr(results[0], f"field_{customers_primary_field.id}") == "John"
    assert getattr(results[1], f"field_{customers_primary_field.id}") == "Jane"

    table_row_2 = model.objects.create()
    getattr(table_row_2, f"field_{link_field_1.id}").add(customers_row_2.id)
    results = getattr(table_row_2, f"field_{link_field_1.id}").all()
    assert len(results) == 1
    assert getattr(results[0], f"field_{customers_primary_field.id}") == "Jane"

    # Going to change only the name of the field. This should not result in any errors
    # of schema changes.
    link_field_1 = field_handler.update_field(user, link_field_1, name="Customer 2")

    with pytest.raises(LinkRowTableNotInSameDatabase):
        field_handler.update_field(user, link_field_1, link_row_table=unrelated_table_1)

    model = table.get_model()
    assert model.objects.all().count() == 2

    # Change the table, this should destroy all relations.
    old_link_field_1_relation_id = link_field_1.link_row_relation_id
    link_field_1 = field_handler.update_field(
        user, link_field_1, link_row_table=cars_table
    )

    model = table.get_model()
    table_rows = model.objects.all()
    table_row = table_rows[0]
    table_row_2 = table_rows[1]

    assert link_field_1.link_row_table.id == cars_table.id
    assert link_field_1.link_row_relation_id == old_link_field_1_relation_id
    assert getattr(table_row, f"field_{link_field_1.id}").all().count() == 0
    assert getattr(table_row, f"field_{link_field_2.id}").all().count() == 2
    assert getattr(table_row_2, f"field_{link_field_1.id}").all().count() == 0
    assert getattr(table_row_2, f"field_{link_field_2.id}").all().count() == 0

    link_field_2 = field_handler.update_field(user, link_field_2, new_type_name="text")

    model = table.get_model()
    table_row = model.objects.all().first()

    assert getattr(table_row, f"field_{link_field_2.id}") is None
    assert LinkRowField.objects.all().count() == 2

    setattr(table_row, f"field_{link_field_2.id}", "Text value")
    table_row.save()
    assert getattr(table_row, f"field_{link_field_2.id}") == "Text value"

    # Delete the existing field. Alter that the related field should be deleted and
    # no table named _relation_ should exist.
    field_handler.delete_field(user, link_field_1)
    assert LinkRowField.objects.all().count() == 0
    for t in connection.introspection.table_names():
        if "_relation_" in t:
            assert False

    # Change a the text field back into a link row field.
    link_field_2 = field_handler.update_field(
        user, link_field_2, new_type_name="link_row", link_row_table=customers_table
    )

    assert link_field_2.link_row_related_field.name == "Example"
    assert (
        link_field_2.through_table_name
        == link_field_2.link_row_related_field.through_table_name
    )
    assert link_field_2.through_table_name in connection.introspection.table_names()
    assert LinkRowField.objects.all().count() == 2

    model = table.get_model()
    table_row = model.objects.all().first()

    getattr(table_row, f"field_{link_field_2.id}").add(
        customers_row_1.id, customers_row_2.id
    )
    results = getattr(table_row, f"field_{link_field_2.id}").all()
    assert len(results) == 2
    assert getattr(results[0], f"field_{customers_primary_field.id}") == "John"
    assert getattr(results[1], f"field_{customers_primary_field.id}") == "Jane"
コード例 #28
0
def test_date_field_type(data_fixture):
    user = data_fixture.create_user()
    table = data_fixture.create_database_table(user=user)

    field_handler = FieldHandler()
    row_handler = RowHandler()

    amsterdam = timezone("Europe/Amsterdam")
    utc = timezone("utc")

    date_field_1 = field_handler.create_field(user=user,
                                              table=table,
                                              type_name="date",
                                              name="Date")
    date_field_2 = field_handler.create_field(
        user=user,
        table=table,
        type_name="date",
        name="Datetime",
        date_include_time=True,
    )

    assert date_field_1.date_include_time is False
    assert date_field_2.date_include_time is True
    assert len(DateField.objects.all()) == 2

    model = table.get_model(attribute_names=True)

    row = row_handler.create_row(user=user,
                                 table=table,
                                 values={},
                                 model=model)
    assert row.date is None
    assert row.datetime is None

    row = row_handler.create_row(
        user=user,
        table=table,
        values={
            "date": "2020-4-1",
            "datetime": "2020-4-1 12:30:30"
        },
        model=model,
    )
    row.refresh_from_db()
    assert row.date == date(2020, 4, 1)
    assert row.datetime == datetime(2020, 4, 1, 12, 30, 30, tzinfo=utc)

    row = row_handler.create_row(
        user=user,
        table=table,
        values={
            "datetime": make_aware(datetime(2020, 4, 1, 12, 30, 30), amsterdam)
        },
        model=model,
    )
    row.refresh_from_db()
    assert row.date is None
    assert row.datetime == datetime(2020,
                                    4,
                                    1,
                                    10,
                                    30,
                                    30,
                                    tzinfo=timezone("UTC"))

    date_field_1 = field_handler.update_field(user=user,
                                              field=date_field_1,
                                              date_include_time=True)
    date_field_2 = field_handler.update_field(user=user,
                                              field=date_field_2,
                                              date_include_time=False)

    assert date_field_1.date_include_time is True
    assert date_field_2.date_include_time is False

    model = table.get_model(attribute_names=True)
    rows = model.objects.all()

    assert rows[0].date is None
    assert rows[0].datetime is None
    assert rows[1].date == datetime(2020, 4, 1, tzinfo=timezone("UTC"))
    assert rows[1].datetime == date(2020, 4, 1)
    assert rows[2].date is None
    assert rows[2].datetime == date(2020, 4, 1)

    field_handler.delete_field(user=user, field=date_field_1)
    field_handler.delete_field(user=user, field=date_field_2)

    assert len(DateField.objects.all()) == 0
コード例 #29
0
def test_import_export_link_row_field(data_fixture, user_tables_in_separate_db):
    user = data_fixture.create_user()
    imported_group = data_fixture.create_group(user=user)
    database = data_fixture.create_database_application(user=user, name="Placeholder")
    table = data_fixture.create_database_table(name="Example", database=database)
    customers_table = data_fixture.create_database_table(
        name="Customers", database=database
    )
    field_handler = FieldHandler()
    core_handler = CoreHandler()
    link_row_field = field_handler.create_field(
        user=user, table=table, type_name="link_row", link_row_table=customers_table
    )

    row_handler = RowHandler()
    c_row = row_handler.create_row(user=user, table=customers_table, values={})
    c_row_2 = row_handler.create_row(user=user, table=customers_table, values={})
    row = row_handler.create_row(
        user=user,
        table=table,
        values={f"field_{link_row_field.id}": [c_row.id, c_row_2.id]},
    )

    exported_applications = core_handler.export_group_applications(
        database.group, BytesIO()
    )
    imported_applications, id_mapping = core_handler.import_applications_to_group(
        imported_group, exported_applications, BytesIO(), None
    )
    imported_database = imported_applications[0]
    imported_tables = imported_database.table_set.all()
    imported_table = imported_tables[0]
    imported_customers_table = imported_tables[1]
    imported_link_row_field = imported_table.field_set.all().first().specific
    imported_link_row_relation_field = (
        imported_customers_table.field_set.all().first().specific
    )

    assert imported_table.id != table.id
    assert imported_table.name == table.name
    assert imported_customers_table.id != customers_table.id
    assert imported_customers_table.name == customers_table.name
    assert imported_link_row_field.id != link_row_field.id
    assert imported_link_row_field.name == link_row_field.name
    assert imported_link_row_field.link_row_table_id == imported_customers_table.id
    assert imported_link_row_relation_field.link_row_table_id == imported_table.id
    assert imported_link_row_field.link_row_relation_id == (
        imported_link_row_relation_field.link_row_relation_id
    )

    imported_c_row = row_handler.get_row(
        user=user, table=imported_customers_table, row_id=c_row.id
    )
    imported_c_row_2 = row_handler.get_row(
        user=user, table=imported_customers_table, row_id=c_row_2.id
    )
    imported_row = row_handler.get_row(user=user, table=imported_table, row_id=row.id)

    assert imported_row.id == row.id
    assert imported_c_row.id == c_row.id
    assert imported_c_row_2.id == c_row_2.id
    assert [
        r.id for r in getattr(imported_row, f"field_{imported_link_row_field.id}").all()
    ] == [imported_c_row.id, imported_c_row_2.id]
コード例 #30
0
def wide_test(data_fixture, storage_mock, expected, options):
    user = data_fixture.create_user()
    database = data_fixture.create_database_application(user=user)
    table = data_fixture.create_database_table(database=database, user=user)
    link_table = data_fixture.create_database_table(database=database,
                                                    user=user)
    handler = FieldHandler()
    row_handler = RowHandler()
    all_possible_kwargs_per_type = construct_all_possible_field_kwargs(
        link_table)
    name_to_field_id = {}
    i = 0
    for field_type_name, all_possible_kwargs in all_possible_kwargs_per_type.items(
    ):
        for kwargs in all_possible_kwargs:
            field = handler.create_field(
                user=user,
                table=table,
                type_name=field_type_name,
                order=i,
                **kwargs,
            )
            i += 1
            name_to_field_id[kwargs["name"]] = field.id
    grid_view = data_fixture.create_grid_view(table=table)
    row_handler = RowHandler()
    other_table_primary_text_field = data_fixture.create_text_field(
        table=link_table, name="text_field", primary=True)

    def add_linked_row(text):
        return row_handler.create_row(
            user=user,
            table=link_table,
            values={
                other_table_primary_text_field.id: text,
            },
        )

    model = table.get_model()

    # A dictionary of field names to a tuple of (value to create the row model with,
    # the expected value of this value after being exported to csv)
    assert expected.keys() == name_to_field_id.keys(), (
        "Please update the dictionary above with what your new field type should look "
        "like when serialized to csv. ")
    row_values = {}
    for field_type, val in expected.items():
        if isinstance(val, tuple):
            val = val[0]
        if callable(val):
            val = val()
        if val is not None:
            row_values[f"field_{name_to_field_id[field_type]}"] = val
    # Make a blank row to test empty field conversion also.
    model.objects.create(**{})
    row = model.objects.create(**row_values)
    linked_row_1 = add_linked_row("linked_row_1")
    linked_row_2 = add_linked_row("linked_row_2")
    linked_row_3 = add_linked_row(None)
    getattr(row, f"field_{name_to_field_id['link_row']}").add(
        linked_row_1.id, linked_row_2.id, linked_row_3.id)
    job, contents = run_export_job_with_mock_storage(table, grid_view,
                                                     storage_mock, user,
                                                     options)
    return contents