Repository: oppia/oppia

Issue:
Schema validation error for old explorations that contain params
<!--
  - Before filing a new issue, please do a quick search to check that it hasn't
  - already been filed on the [issue tracker](https://github.com/oppia/oppia/issues)._
  -->

This error occurred recently in production

```
Traceback (most recent call last):
  File "/workspace/core/controllers/base.py", line 323, in dispatch
    self.validate_and_normalize_args()
  File "/workspace/core/controllers/base.py", line 454, in validate_and_normalize_args
    raise self.InvalidInputException('\n'.join(errors))
core.controllers.base.UserFacingExceptions.InvalidInputException: Schema validation for 'params' failed: Missing keys: [], Extra keys: ['XXX']
```

### Screen capture

https://user-images.githubusercontent.com/11008603/150235192-e7d5975e-25ef-43db-80e2-efdca9930443.mp4



### Steps to reproduce locally
1. Undo changes in https://github.com/oppia/oppia/pull/11513 (ignore spec file.)
2. Start server.
3. Create an exploration and enable parameters in the settings tab in the editor.
4. Add a few params in the exploration.
5. Go to the `/explore` page.
6. See error.

### Proposed solution
Update schema for the relevant handlers to allow string keys for parameters and add tests to catch any regressions in the future.

Schema validation error for old explorations that contain params
<!--
  - Before filing a new issue, please do a quick search to check that it hasn't
  - already been filed on the [issue tracker](https://github.com/oppia/oppia/issues)._
  -->

This error occurred recently in production

```
Traceback (most recent call last):
  File "/workspace/core/controllers/base.py", line 323, in dispatch
    self.validate_and_normalize_args()
  File "/workspace/core/controllers/base.py", line 454, in validate_and_normalize_args
    raise self.InvalidInputException('\n'.join(errors))
core.controllers.base.UserFacingExceptions.InvalidInputException: Schema validation for 'params' failed: Missing keys: [], Extra keys: ['XXX']
```

### Screen capture

https://user-images.githubusercontent.com/11008603/150235192-e7d5975e-25ef-43db-80e2-efdca9930443.mp4



### Steps to reproduce locally
1. Undo changes in https://github.com/oppia/oppia/pull/11513 (ignore spec file.)
2. Start server.
3. Create an exploration and enable parameters in the settings tab in the editor.
4. Add a few params in the exploration.
5. Go to the `/explore` page.
6. See error.

### Proposed solution
Update schema for the relevant handlers to allow string keys for parameters and add tests to catch any regressions in the future.



Discussion:
/cc @vojtechjelinek 
/cc @vojtechjelinek 

Resolving patch:
diff --git a/core/controllers/reader.py b/core/controllers/reader.py
--- a/core/controllers/reader.py
+++ b/core/controllers/reader.py
@@ -617,8 +617,9 @@ class ExplorationStartEventHandler(base.BaseHandler):
         'POST': {
             'params': {
                 'schema': {
-                    'type': 'dict',
-                    'properties': []
+                    'type': 'object_dict',
+                    'validation_method': (
+                        domain_objects_validator.validate_params_dict),
                 }
             },
             'session_id': {


Test patch:
diff --git a/core/controllers/reader_test.py b/core/controllers/reader_test.py
--- a/core/controllers/reader_test.py
+++ b/core/controllers/reader_test.py
@@ -2202,7 +2202,9 @@ def test_starting_a_state(self):
             {
                 'state_name': 'state_name',
                 'version': version,
-                'params': {},
+                'params': {
+                    'test_param1': 1
+                },
                 'session_id': 'session_id'
             }
         )
@@ -2217,7 +2219,9 @@ def test_starting_a_state(self):
         self.assertEqual(model.state_name, 'state_name')
         self.assertEqual(model.session_id, 'session_id')
         self.assertEqual(model.exploration_version, version)
-        self.assertEqual(model.params, {})
+        self.assertEqual(model.params, {
+            'test_param1': 1
+        })
         self.assertEqual(model.play_type, feconf.PLAY_TYPE_NORMAL)
 
         self.logout()