Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #1018: Make project details editing work again #1019

Merged
merged 3 commits into from
Jan 9, 2017
Merged

Conversation

seav
Copy link
Contributor

@seav seav commented Dec 22, 2016

Proposed changes in this pull request

  • Fix Editing project details does not succeed #1018:
    • Corrected call to super().post().
    • Update unit tests. In particular, test_post_with_blocked_questionnaire_upload should have resulted in a successful form submission. Also, questionnaire is removed from the default post_data in order to simulate the missing questionnaire fields in the template if the project has records.

When should this PR be merged

Soon.

Risks

None foreseen.

Follow up actions

None.

Checklist (for reviewing)

General

  • Is this PR explained thoroughly? All code changes must be accounted for in the PR description.
  • Is the PR labeled correctly? It should have the migration label if a new migration is added.
  • Is the risk level assessment sufficient? The risks section should contain all risks that might be introduced with the PR and which actions we need to take to mitigate these risks. Possible risks are database migrations, new libraries that need to be installed or changes to deployment scripts.

Functionality

  • Are all requirements met? Compare implemented functionality with the requirements specification.
  • Does the UI work as expected? There should be no Javascript errors in the console; all resources should load. There should be no unexpected errors. Deliberately try to break the feature to find out if there are corner cases that are not handled.

Code

  • Do you fully understand the introduced changes to the code? If not ask for clarification, it might uncover ways to solve a problem in a more elegant and efficient way.
  • Does the PR introduce any inefficient database requests? Use the debug server to check for duplicate requests.
  • Are all necessary strings marked for translation? All strings that are exposed to users via the UI must be marked for translation.

Tests

  • Are there sufficient test cases? Ensure that all components are tested individually; models, forms, and serializers should be tested in isolation even if a test for a view covers these components.
  • If this is a bug fix, are tests for the issue in place There must be a test case for the bug to ensure the issue won’t regress. Make sure that the tests break without the new code to fix the issue.

Documentation

  • Are changes to the UI documented in the platform docs? If this PR introduces new platform site functionality or changes existing ones, the changes must be documented in the Cadasta Platform Documentation.
  • Are changes to the API documented in the API docs? If this PR introduces new API functionality or changes existing ones, the changes must be documented in the API docs.
  • Are reusable components documented? If this PR introduces components that are relevant to other developers (for instance a mixin for a view or a generic form) they should be documented in the Wiki.

@seav seav requested review from oliverroick and bjohare December 22, 2016 13:38
Copy link
Member

@oliverroick oliverroick left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your proposed solution solves only half the problem. Initially, I implemented this that way because I want to make sure, you can't change the questionnaire when there is data in the project (though my original solution is incredibly shortsighted). The reason I wanted to block changing questionnaires not only by hiding the form field in the template but also in the view was that I wanted to have several layers where this is checked and rejected.

I would suggest adding a check to the ProjectEditDetails form; for instance into the clean_questionnaire to raise a validation error. I won't have any effect on what it displayed to the user, but we will be on the safe side in case the form is reused at some point. I can't implement that and add it to your PR if you want (after all it's me who caused the issue).

@@ -652,7 +652,7 @@ def get_initial(self):

def post(self, *args, **kwargs):
if self.get_project().has_records:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The if condition is not necessary anymore. So I would get rid of it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe there can still be a use for this condition except that the super().post() should be outside. Right now, neither the form nor the view checks that the user has not attempted to update the questionnaire when there are already records.

So maybe the condition should be moved to the form and the form (save()) checks that the questionnaire is unchanged or is not provided in the POST data when the project has records.

@@ -934,7 +933,7 @@ class ProjectEditDetailsTest(ViewTestCase, UserTestCase,
}

def setup_models(self):
self.project = ProjectFactory.create(current_questionnaire='abc')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't agree with this. We should still test that the view does not update the questionnaire if the project has data. So we should write a test that rejects the update, even though with the current template it's not possible to upload a new questionnaire. My rationale behind it is that if we change the template for some reason and accidentally enable to update the questionnaire, the update will still be rejected from the view, no matter hat the template looks like.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This makes sense. But as I mentioned in another comment, neither the form nor the view does any rejection. So we would need to add that rejection functionality before we can test it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BTW, it seems that the original line of code (ProjectFactory.create(current_questionnaire='abc')) does not actually create a project with a valid questionnaire. We would need to create a Questionnaire instance too in setup_models.

@seav
Copy link
Contributor Author

seav commented Dec 22, 2016

Another code observation. Please refer to the following lines of code: https://github.com/Cadasta/cadasta-platform/blob/bugfix/%231018/cadasta/organization/forms.py#L353-L361

Given that the current template does not include the questionnaire form fields when there are records, new_form will be false. This would mean that self.instance.current_questionnaire = '' would be executed which implies that the questionnaire was removed. I think these lines of code need to be rethought.

@oliverroick
Copy link
Member

oliverroick commented Dec 22, 2016

I added necessary checks to the form also taking into account Eugene's remarks. Tests have both added to views and forms covering various scenarios. Adding @seav as reviewer for my changes.

Copy link
Contributor Author

@seav seav left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have left some change requests and comments.

@@ -357,7 +368,7 @@ def save(self, *args, **kwargs):
original_file=original_file,
project=self.instance
)
else:
elif not self.instance.has_records:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this condition really correct? This condition will be evaluated only if new_form is false which can be due to two things:

  1. There was an existing questionnaire but it was removed or it remained empty (questionnaire == '')
  2. The field was missing which implies that the questionnaire should remain unchanged (questionnaire == None).

Now the condition checks whether the project already has records and then clears out current_questionnaire when there are no records. I can only consider scenario 1 above to be valid in this case. For scenario 2, current_questionnaire should remain unchanged. I suggest adding an additional condition to check that new_form is not None.

@@ -933,7 +934,7 @@ class ProjectEditDetailsTest(ViewTestCase, UserTestCase,
}

def setup_models(self):
self.project = ProjectFactory.create()
self.project = ProjectFactory.create(current_questionnaire='abc')
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Take note that this project creation does not actually create any valid Questionnaire instances. This means that when the view's get_initial() method is executed, Questionnaire.DoesNotExist will be thrown and initial['questionnaire'] will never be populated. This may have an effect later on when the form is submitted and we are comparing new_form with current_form.

SpatialUnitFactory.create(project=self.project)
user = UserFactory.create()
assign_policies(user)
post_data = self.post_data.copy()
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You copied post_data here then deleted the questionnaire entry in the next line. But you never actually used this modified post_data in the request. Based on how I understand django-skivvy to work, the call to request() later on will still use the original self.post_data that still contains the questionnaire entry.

If I understand the test intent correctly, the idea is to try and submit a POST request which does not include the questionnaire field (questionnaire == None). This implies that the questionnaire should remain unchanged which is a valid scenario. Therefore the test should have checked for a 302 status with updated project details, not 200 and unchanged project details.

@oliverroick
Copy link
Member

Good points @seav. I addressed the issues in the latest commit.

Copy link
Contributor Author

@seav seav left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These latest changes are OK with me. The ball is now in @bjohare's court.

Copy link
Contributor

@linzjax linzjax left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Everything seems to be working.

@amplifi amplifi merged commit 28cf61e into master Jan 9, 2017
@amplifi amplifi deleted the bugfix/#1018 branch January 9, 2017 16:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Editing project details does not succeed
4 participants