Working with Django models

Step definitions and utilities for working with Django models.

aloe_django.steps.models.writes_models(model)

Register a model-specific create and update function.

This can then be accessed via the steps:

And I have foos in the database:
    | name | bar  |
    | Baz  | Quux |

And I update existing foos by pk in the database:
    | pk | name |
    | 1  | Bar  |

A method for a specific model can define a function write_badgers(data, field), which creates and updates the Badger model and decorating it with the writes_models(model_class) decorator:

@writes_models(Profile)
def write_profile(data, field):
    '''Creates a Profile model'''

    for hash_ in data:
        if field:
            profile = Profile.objects.get(**{field: hash_[field]})
        else:
            profile = Profile()

        ...

    reset_sequence(Profile)

The function must accept a list of data hashes and a field name. If field is not None, it is the field that must be used to get the existing objects out of the database to update them; otherwise, new objects must be created for each data hash.

Follow up model creation with a call to reset_sequence() to update the database sequences.

If you only want to modify the hash, you can make modifications and then pass it on to write_models().

@writes_models(Profile)
def write_profile(data, field):
    '''Creates a Profile model'''

    for hash_ in data:

        # modify hash

    return write_models(Profile, data, field)
aloe_django.steps.models.write_models(model, data, field)
Parameters:
  • model – a Django model class
  • data – a list of hashes to build models from
  • field – a field name to match models on, or None
Returns:

a list of models written

Create or update models for each data hash.

field is the field that is used to get the existing models out of the database to update them; otherwise, if field=None, new models are created.

Useful when registering custom tests with writes_models().

aloe_django.steps.models.tests_existence(model)

Register a model-specific existence test.

This can then be accessed via the steps:

Then foos should be present in the database:
    | name   | bar |
    | badger | baz |

Then foos should not be present in the database:
    | name   | bar |
    | badger | baz |

A method for a specific model can define a function test_badgers(queryset, data) and decorating it with the tests_existence(model_class) decorator:

@tests_existence(Profile)
def test_profile(queryset, data):
    '''Test a Profile model'''

    # modify data ...

    return test_existence(queryset, data)

If you only want to modify the hash, you can make modifications then pass it on to test_existence().

aloe_django.steps.models.test_existence(queryset, data)
Parameters:
  • queryset – a Django queryset
  • data – a single model to check for
Returns:

True if the model exists

Test existence of a given hash in a queryset (or among all model instances if a model is given).

Useful when registering custom tests with tests_existence().

aloe_django.steps.models.reset_sequence(model)

Reset the ID sequence for a model.

Step (?:Given|And|Then|When) ([A-Z][a-z0-9_ ]*) with ([a-z]+) "([^"]*)" is linked to ([A-Z][a-z0-9_ ]*) in the database:

Link many-to-many models together.

Syntax:

And model with fieldvalue” is linked to other model in the database:

Example:

And article with name "Guidelines" is linked to tags in the database:
    | name   |
    | coding |
    | style  |
Step (?:Given|And|Then|When) ([A-Z][a-z0-9_ ]*) with ([a-z]+) "([^"]*)" has(?: an?)? ([A-Z][a-z0-9_ ]*) in the database:

Create a new model linked to the given model.

Syntax:

And model with fieldvalue” has new model in the database:

Example:

And project with name "Ball Project" has goals in the database:
    | description                             |
    | To have fun playing with balls of twine |
Step There should be (d+) ([a-z][a-z0-9_ ]*) in the database

Count the number of models in the database.

Example:

Then there should be 0 goals in the database
Step (?:Given|And|Then|When) (?:an? )?([A-Z][a-z0-9_ ]*) should not be present in the database

Tests for the existence of a model matching the given data.

Column names are included in a query to the database. To check model attributes that are not database columns (i.e. properties). Prepend the column with an @ sign.

Example:

Then foos should not be present in the database:
    | name   | @bar |
    | badger | baz  |

See tests_existence().

Step (?:Given|And|Then|When) (?:an? )?([A-Z][a-z0-9_ ]*) should be present in the database

Test for the existence of a model matching the given data.

Column names are included in a query to the database. To check model attributes that are not database columns (i.e. properties) prepend the column with an @ sign.

Example:

Then foos should be present in the database:
    | name   | @bar |
    | badger | baz  |

See tests_existence().

Step I have(?: an?)? ([a-z][a-z0-9_ ]*) in the database:

Create models in the database.

Syntax:

I have model in the database:

Example:

And I have foos in the database:
    | name | bar  |
    | Baz  | Quux |

See writes_models().

Step I update(?: an?)? existing ([a-z][a-z0-9_ ]*) by ([a-z][a-z0-9_]*) in the database:

Update existing models in the database, specifying a column to match on.

Syntax:

I update model by key in the database:

Example:

And I update existing foos by pk in the database:
    | pk | name |
    | 1  | Bar  |

See writes_models().

Working with email

Step definitions for working with Django email.

Step (?:Given|And|Then|When) sending email does not work

Cause sending email to raise an exception.

This allows simulating email failure.

Example:

Given sending email does not work
Step (?:Given|And|Then|When) I clear my email outbox

Clear the email outbox.

Example:

Given I clear my email outbox
Step I have not sent any emails

Test no emails have been sent.

Example:

Then I have not sent any emails
Step (?:And|Then) I have not sent an email with "([^"]*)" in the (subject|body|from_email|to|bcc|cc)

Test an email does not contain (assert text not in) the given text in the relevant message part (accessible as an attribute on the email object).

This step strictly applies whitespace.

Syntax:

I have not sent an email with “text” in the part

Example:

Then I have not sent an email with "pandas" in the body
Step (?:And|Then) I have sent an email with the following HTML alternative:

Test that an email contains the HTML (assert HTML in) in the multiline as one of its MIME alternatives.

The HTML is normalised by passing through Django’s django.test.html.parse_html().

Example:

And I have sent an email with the following HTML alternative:
"""
<p><strong>Name:</strong> Sir Panda</p>
<p><strong>Phone:</strong> 0400000000</p>
<p><strong>Email:</strong> sir.panda@pand.as</p>
"""
Step (?:And|Then) I have sent an email with "([^"]*)" in the (subject|body|from_email|to|bcc|cc)

Test an email contains (assert text in) the given text in the relevant message part (accessible as an attribute on the email object).

This step strictly applies whitespace.

Syntax:

I have sent an email with “text” in the part

Example:

Then I have sent an email with "pandas" in the body
Step (?:And|Then) I have sent an email with the following in the body:

Test the body of an email contains (assert text in) the given multiline string.

This step strictly applies whitespace.

Example:

Then I have sent an email with the following in the body:
"""
Dear Mr. Panda,
"""
Step (?:And|Then) I have sent (d+) emails?

Test that count mails have been sent.

Syntax:

I have sent count emails

Example:

Then I have sent 2 emails