@@ -801,4 +801,111 @@ public function test_update_option_with_autoload_change_yes_to_no() {
801801 delete_option ( 'foo ' );
802802 $ this ->assertFalse ( get_option ( 'foo ' ) );
803803 }
804+
805+ /**
806+ * Test cases for testing whether update_option() will add a non-existent option.
807+ */
808+ public function data_option_values () {
809+ return array (
810+ array ( '1 ' ),
811+ array ( 1 ),
812+ array ( 1.0 ),
813+ array ( true ),
814+ array ( 'true ' ),
815+ array ( '0 ' ),
816+ array ( 0 ),
817+ array ( 0.0 ),
818+ array ( false ),
819+ array ( '' ),
820+ array ( null ),
821+ array ( array () ),
822+ );
823+ }
824+
825+ /**
826+ * Tests that a non-existent option is added only when the pre-filter matches the default 'false'.
827+ *
828+ * @ticket 22192
829+ * @dataProvider data_option_values
830+ *
831+ * @covers ::update_option
832+ */
833+ public function test_update_option_with_false_pre_filter_adds_missing_option ( $ option ) {
834+ // Filter the old option value to `false`.
835+ add_filter ( 'pre_option_foo ' , '__return_false ' );
836+
837+ /*
838+ * When the option is equal to the filtered version, update option will bail early.
839+ * Otherwise, The pre-filter will make the old option `false`, which is equal to the
840+ * default value. This causes an add_option() to be triggered.
841+ */
842+ if ( false === $ option ) {
843+ $ this ->assertFalse ( update_option ( 'foo ' , $ option ) );
844+ } else {
845+ $ this ->assertTrue ( update_option ( 'foo ' , $ option ) );
846+ }
847+ }
848+
849+ /**
850+ * Tests that a non-existent option is never added when the pre-filter is not 'false'.
851+ *
852+ * @ticket 22192
853+ * @dataProvider data_option_values
854+ *
855+ * @covers ::update_option
856+ */
857+ public function test_update_option_with_truthy_pre_filter_does_not_add_missing_option ( $ option ) {
858+ // Filter the old option value to `true`.
859+ add_filter ( 'pre_option_foo ' , '__return_true ' );
860+
861+ $ this ->assertFalse ( update_option ( 'foo ' , $ option ) );
862+ }
863+
864+ /**
865+ * Tests that an existing option is updated even when its pre filter returns the same value.
866+ *
867+ * @ticket 22192
868+ * @dataProvider data_option_values
869+ *
870+ * @covers ::update_option
871+ */
872+ public function test_update_option_with_false_pre_filter_updates_option ( $ option ) {
873+ // Add the option with a value that is different than any updated.
874+ add_option ( 'foo ' , 'bar ' );
875+
876+ // Force a return value of false.
877+ add_filter ( 'pre_option_foo ' , '__return_false ' );
878+
879+ /*
880+ * This should succeed, since the 'foo' option has a value of 0 in the database.
881+ * Therefore it differs from true and should be updated.
882+ */
883+ $ this ->assertTrue ( update_option ( 'foo ' , $ option ) );
884+ }
885+
886+ /**
887+ * Tests that an existing option is updated even when its pre filter returns the same value.
888+ *
889+ * @ticket 22192
890+ * @dataProvider data_option_values
891+ *
892+ * @covers ::update_option
893+ */
894+ public function test_update_option_with_true_pre_filter_updates_option ( $ option ) {
895+ // Add the option with a value that is different than any updated.
896+ add_option ( 'foo ' , 'bar ' );
897+
898+ // Force a return value of true.
899+ add_filter ( 'pre_option_foo ' , '__return_true ' );
900+
901+ /*
902+ * Option `true` is the same as the filtered old value, so it will fail.
903+ * All other options should update.
904+ */
905+ if ( true === $ option ) {
906+ $ this ->assertFalse ( update_option ( 'foo ' , $ option ) );
907+ } else {
908+ $ this ->assertTrue ( update_option ( 'foo ' , $ option ) );
909+ }
910+ }
804911}
0 commit comments