Ensure mocked User.get_profile is removed by @ensure_user_profile

Review Request #8869 — Created April 3, 2017 and submitted — Latest diff uploaded

Information

Djblets
release-0.10.x
837fc77...

Reviewers

The @ensure_user_profile decorator ensures that User.get_profile
exists because it has been removed in Django 1.7+. For compatability,
some functionality (and therefore unit tests) require it to exist
(i.e., be on Django 1.6 or have it added by a third party).

One issue is that when using this in conjunction with KGB to replace the
definition of get_profile that the profile will not be deleted, as
SpyAgency.tear_down will execute after require_user_profile has
finished, which results in the original method not being deleted.
Furthermore, the mock method we add will stick around as
SpyAgency.tear_down restores it.

To combat this issue, we now check to see if the function has been
replaced by a FunctionSpy and unspy on it if that is the case. That
will result in SpyAgency not modifying the User object during
tear_down.

Additionally, we were comparing User.get_profile to our mock method,
which will never be equal because User.get_profile will be an unbound
method and not the original function. We now compare to the underlying
function instead.

Ran unit tests on Django 1.6 and 1.8.