question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Edge case when testing against local database

See original GitHub issue

Hi,

Firstly, I love the work done on this, it’s a really powerful tool.

I’m running into a problem when testing a salesforce database locally. I believe the tables in the local database has been generated with an integer type for the ID field

For example:

a = Account(id="abc123abc123abc", ...)
a.save()

Would fail, as id has a type mismatch, and is expecting an integer

I believe this is because the SalesforceAutoField, as given to the id field in the SalesforceModel has not overriden the get_internal_type() method, and is defaulting to the integer type, of the parent class AutoField

Doing the following fixed my errors, but I wanted to check with you all first to see if I’m doing something wrong here. or if this should be pull requested?

class SalesforceAutoField(fields.AutoField):
    """
    An AutoField that works with Salesforce primary keys.

    It is used by SalesforceModel as a custom primary key. It doesn't convert
    its value to int.
    """
    description = _("Text")

    def get_internal_type(self):
        return "TextField"

    default_error_messages = {
        'invalid': _('This value must be a valid Salesforce ID.'),
    }

    def to_python(self, value):
        ...

Thanks Elliot

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:11 (7 by maintainers)

github_iconTop GitHub Comments

1reaction
ElliotSalisburycommented, Jun 2, 2019

@thatguysimon Thanks for your input! 😃

In the end, I came up with a similar solution. Detecting when a test is running, and modifying the ID field type. I use the pytest_configure function in order to do this.

So within my tests folder, I have a conftest.py that looks like this:

import django

def pytest_configure():
    django.setup()

    # override a function in the ID field of the django-salesforce models
    # we only want to do this in a test runner, to avoid any issues with accessing the live salesforce database
    # the problem is that the autofield creates an 'int' id column, but salesforce id's should be a 'char' field
    # this isnt a problem in the live database, because its maintained by SF, but local copies used for testing
    # are generated incorrectly.
    from salesforce.fields import SalesforceAutoField
    SalesforceAutoField.get_internal_type = lambda s: "TextField"

In your solution, although this seems incredibly unlikely, and you might never run into it, it might be possible in your solution to generate 2 Account objects with the same ID, given that the ID is generated randomly. To avoid something like that, I generate my Accounts with a factory using a sequence:

def get_standardized_sf_id(sf_id):
    # ensure ID is salesforce 18 char case insensitive id
    # https://help.salesforce.com/articleView?id=000274977&type=1&language=en_US

    suffix = ""
    for i in range(3):
        loop = 0
        for position in range(5):
            current = sf_id[i * 5 + position]
            if current.isupper():
                loop += 1 << position
        suffix += "ABCDEFGHIJKLMNOPQRSTUVWXYZ012345"[loop]
    sf_id = sf_id[:15] + suffix
    return sf_id


class SFBaseFactory(factory.django.DjangoModelFactory):
    class Meta:
        abstract = True

    # creates id's that are incrementing integers, padded with 15 0's, and concatenated with the salesforce case insentive code.
    # e.g., "000000000000001AAA"
    id = factory.Sequence(lambda n: get_standardized_sf_id('%015d' % n))
    last_modified_date = factory.LazyFunction(timezone.now)
    ...
0reactions
hynekcercommented, Jun 5, 2019

That solution is in PR #237

Changelog:

  • Added: salesforce.models_extend module with SalesforceModel with varchar primary key that works also with default databases. Fixed methods for it: save() and bulk_create() to can create a new pk or to copy an object exactly. Fixed #231 (4d042e5, 79603b7)

The generator function for salesforce alternate primary key (default is uuid.uuid4().hex) is configurable by settings.SF_ALT_PK. This can be useful for your case if you want everything 15+3 chars.

Please try the new code.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Are these the sort of edge cases I should think of when using ...
Your tests seem OK, but the phrase "edge case" normally refers to the tests and checks you need to do around the limits...
Read more >
Testing against your Production Database System - EF Core
When using a cloud database, it's usually appropriate to test against a local version of the database, both to improve speed and to...
Read more >
Edge-case behavior of INSERT...ODKU - Percona
A few weeks back, I was working on a customer issue wherein they were observing database performance that dropped through the floor (to...
Read more >
Find, Prioritize and Test Edge Cases - Applause
How does a QA tester identify edge test cases, or find edge case defects? The best advice is you find edge cases by...
Read more >
Are (database) integration tests bad?
Write the smallest useful test you can. For this particular case, an in-memory database might help with that.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found