@@ -260,6 +260,20 @@ been passed an error variable, and if so, we do this:
260
260
((("form control classes (Bootstrap)")))
261
261
Take a look at the https://getbootstrap.com/docs/5.3/forms/validation/#server-side[Bootstrap docs] for more
262
262
info on form controls.
263
+ footnote:[... and ignore their advice to prefer client-side validation.
264
+ Ideally, having both server- and client-side validation is the best.
265
+ If you can't do both, then server-side validation is the one you really can't do
266
+ without.
267
+ Check the
268
+ https://owasp.org/www-project-secure-coding-practices-quick-reference-guide/stable-en/02-checklist/05-checklist.html[OWASP checklist],
269
+ if you are not convinced yet.
270
+ Client-side validation will provide faster feedback on the UI, but
271
+ https://cheatsheetseries.owasp.org/cheatsheets/Input_Validation_Cheat_Sheet.html#client-side-vs-server-side-validation[it is not a security measure.]
272
+ Server-side validation is indispensable for handling any input
273
+ that gets processed by the server--and it will also provide albeit slower,
274
+ feedback for the client side.]
275
+
276
+
263
277
// CSANAD: these are the new docs for Bootstrap, but for some reason they begin
264
278
// with saying "We recommend client-side validation" which is bad.
265
279
// Client side validation is fine for faster UI aesthetics, sure. But they are
@@ -578,6 +592,45 @@ $ *git commit -am "Adjust new list view to do model validation"*
578
592
----
579
593
580
594
595
+ Let's put an early return in the FT to separate
596
+ what we got working from those that still need to be dealt with:
597
+
598
+ [role="sourcecode"]
599
+ .src/functional_tests/test_list_item_validation.py (ch13l???)
600
+ ====
601
+ [source,python]
602
+ ----
603
+ class ItemValidationTest(FunctionalTest):
604
+ def test_cannot_add_empty_list_items(self):
605
+ [...]
606
+ self.browser.find_element(By.ID, "id_new_item").send_keys(Keys.ENTER)
607
+ self.wait_for_row_in_list_table("1: Buy milk")
608
+
609
+ return
610
+ # TODO fix the remaining test scenarios
611
+
612
+ # Perversely, she now decides to submit a second blank list item
613
+ self.browser.find_element(By.ID, "id_new_item").send_keys(Keys.ENTER)
614
+ [...]
615
+ ----
616
+ ====
617
+
618
+
619
+ We should also remind ourselves not to forget to remove this early return:
620
+
621
+
622
+ [role="scratchpad"]
623
+ *****
624
+ * 'Remove hardcoded URLs from views.py'
625
+ * 'Remove the early return from the FT'
626
+ *****
627
+
628
+ And now, we can focus on making our code a little neater.
629
+
630
+ TIP: When working on a new feature, it's common to realize partway through that
631
+ a refactor of the application is needed. Adding an early return to the FT
632
+ you're currently working on allows you to perform this refactor against
633
+ passing FTs, even while the feature is still in progress.
581
634
582
635
583
636
@@ -628,6 +681,7 @@ and while we're thinking about it, there's one in 'home.html' too:
628
681
[role="scratchpad"]
629
682
*****
630
683
* 'Remove hardcoded URLs from views.py'
684
+ * 'Remove the early return from the FT'
631
685
* 'Remove hardcoded URL from forms in list.html and home.html'
632
686
*****
633
687
@@ -777,29 +831,21 @@ urlpatterns = [
777
831
----
778
832
====
779
833
780
- And that gets us to the `OK` .
834
+ And that gets us to the green on the unit tests .
781
835
782
836
----
783
837
OK
784
838
----
785
839
786
840
787
- Let's try a full FT run:
841
+ Let's try a full FT run: they're all passing!
788
842
789
-
790
- [subs="specialcharacters,quotes"]
791
843
----
792
- $ *python src/manage.py test functional_tests*
793
- [...]
794
- ERROR: test_cannot_add_empty_list_items (functional_tests.test_list_item_valida
795
- tion.ItemValidationTest.test_cannot_add_empty_list_items)
796
- [...]
844
+ Ran 4 tests in 20 s
797
845
798
- Ran 4 tests in 15.276s
799
- FAILED (errors=1)
846
+ OK
800
847
----
801
848
802
- We're back to the one failure in our new functional test.
803
849
Our refactor of the `add_item` functionality is complete.
804
850
We should commit there:
805
851
@@ -808,16 +854,33 @@ We should commit there:
808
854
$ *git commit -am "Refactor list view to handle new item POSTs"*
809
855
----
810
856
811
- NOTE: So did I break the rule about never refactoring against failing tests?
812
- In this case, it's allowed, because the refactor is required
813
- to get our new functionality to work.
814
- You should definitely never refactor against failing _unit_ tests.
815
- But in my book it's OK for the FT for the current story you're working on
816
- to be failing.footnote:[
817
- If you really want a "clean" test run, you could add a skip or an early return
818
- to the current FT, but you'd need to make sure you didn't accidentally forget it.]
857
+
858
+ We can remove the early return
859
+ now.
860
+
861
+ [role="scratchpad"]
862
+ *****
863
+ * 'Remove hardcoded URLs from views.py'
864
+ * '[strikethrough line-through]#Remove the early return from the FT#'
865
+ * 'Remove hardcoded URL from forms in list.html and home.html'
866
+ *****
867
+
868
+ Run the FTs again to see what's still there that needs to be fixed:
819
869
820
870
871
+ [subs="specialcharacters,quotes"]
872
+ ----
873
+ $ *python src/manage.py test functional_tests*
874
+ [...]
875
+ ERROR: test_cannot_add_empty_list_items (functional_tests.test_list_item_valida
876
+ tion.ItemValidationTest.test_cannot_add_empty_list_items)
877
+ [...]
878
+
879
+ Ran 4 tests in 15.276s
880
+ FAILED (errors=1)
881
+ ----
882
+
883
+ We're back to the one failure in our new functional test.
821
884
822
885
823
886
@@ -901,6 +964,7 @@ We'll just add it to our scratchpad for now:
901
964
[role="scratchpad"]
902
965
*****
903
966
* 'Remove hardcoded URLs from views.py'
967
+ * '[strikethrough line-through]#Remove the early return from the FT#'
904
968
* 'Remove hardcoded URL from forms in list.html and home.html'
905
969
* 'Remove duplication of validation logic in views'
906
970
*****
@@ -1015,6 +1079,7 @@ $ *git commit -am "Refactor hard-coded URLs out of templates"*
1015
1079
[role="scratchpad"]
1016
1080
*****
1017
1081
* 'Remove hardcoded URLs from views.py'
1082
+ * '[strikethrough line-through]#Remove the early return from the FT#'
1018
1083
* '[strikethrough line-through]#Remove hardcoded URL from forms in list.html and home.html#'
1019
1084
* 'Remove duplication of validation logic in views'
1020
1085
*****
@@ -1148,6 +1213,7 @@ Cross off our to-dos...
1148
1213
[role="scratchpad"]
1149
1214
*****
1150
1215
* '[strikethrough line-through]#Remove hardcoded URLs from views.py#'
1216
+ * '[strikethrough line-through]#Remove the early return from the FT#'
1151
1217
* '[strikethrough line-through]#Remove hardcoded URL from forms in list.html and home.html#'
1152
1218
* 'Remove duplication of validation logic in views'
1153
1219
*****
0 commit comments