Repository: learningequality/kolibri

Issue:
Setup Wizard -> Personal -- Creates the facility as "nonformal" - should be "informal"
<!--
Instructions:
 * Fill out the sections below, replace …'s with information about your issue
 * Use the 'preview' function above this text box to verify formatting before submitting
-->

### Observed behavior
<!--
Description of the behavior that was observed, including screenshots or other references when applicable
-->

I created a new KOLIBRI_HOME and went through the setup wizard and selected "Personal" to test the Sign In Page work I'm doing for the Personal version.

When I got through with the Setup Wizard, it was created as `nonformal` rather than `informal`. I checked in Vuex and the database and it was created incorrectly.

### Expected behavior
<!--
Description of what behavior was expected but did not occur
-->

In Setup Wizard:

Personal -> creates an `informal` facility
Advanced -> gives user the option to create a `formal` or `nonformal` facility

### User-facing consequences
<!--
Implications and real-world consequences for learners, coaches, admins, and other users of the application
-->

Features we have for "Personal" devices/facilities will not be displayed properly.

### Context
<!--
Tell us about your environment, including:
 * Kolibri version
 * Operating system
 * Browser
-->

0.14-beta9
Debian 10
Chrome



Discussion:
Did you see the `preset: nonformal` state in Vuex while doing a Quick Start? When I go immediately from "Pick Language" -> "Quick start", I do see the expected `preset: informal`.

It's happened before where if you go some steps into an "advanced" setup and move backwards, some of that state doesn't get reset when you take a different setup after backtracking. 

It's also possible that the correct `informal` preset is getting set on the client, but the `create` method on the ProvisionDeviceSerializer is doing something wrong, giving you a facility dataset with the wrong preset.
I didn't move throughout the options at all and went straight through the Personal flow because that's what I was trying to test.

I didn't look at Vuex until after I finished provisioning so I'd have to go back to try and replicate it. Can do tomorrow.
Yeah, I just reproduced this too.

Weirdly, the `preset` field on the `dataset` object in Vuex says `nonformal`, but the actual settings reflect the `informal` preset, specifically where two differ (`learner_can_sign_up: false` is correct for `informal` setups).

I also confirmed that the `facilitydataset` record has the wrong preset, so I think this might be happening at the DeviceProvisioning endpoint, where it's somehow getting the `preset` field wrong, but setting the correct default settings.

![CleanShot 2020-07-14 at 16 50 31@2x](https://user-images.githubusercontent.com/10248067/87487340-3e86ca80-c5f2-11ea-97c1-4ce7fcf0e345.png)

Yeah, I think what's happening is that we're not actually updating the `preset` field here

https://github.com/learningequality/kolibri/blob/efd4153decbc7663faed501260c76939ddffc764/kolibri/core/device/serializers.py#L81-L86

And the default preset is `nonformal`.

So we're getting the right settings for the preset, but the wrong name of the preset.

It looks like we do the same thing for the `provisiondevice` management command

https://github.com/learningequality/kolibri/blob/c0e59cc470921985a8fde87e7b0a2bcec02f2d6a/kolibri/core/device/management/commands/provisiondevice.py#L62-L68
An issue I just found is that this `preset` value is not used for resetting Facility settings to their defaults. It's just this default that we have here:

https://github.com/learningequality/kolibri/blob/efd4153decbc7663faed501260c76939ddffc764/kolibri/plugins/facility/assets/src/modules/facilityConfig/actions.js#L47-L59

I think this is the only place on the UI where having the correct `preset` field is actually important, since I believe the intention is that when we "reset to default", we want to reset to the defaults for the original preset.

Resolving patch:
diff --git a/kolibri/core/device/management/commands/provisiondevice.py b/kolibri/core/device/management/commands/provisiondevice.py
--- a/kolibri/core/device/management/commands/provisiondevice.py
+++ b/kolibri/core/device/management/commands/provisiondevice.py
@@ -71,7 +71,7 @@ def get_user_response(prompt, valid_answers=None):
 def create_facility(facility_name=None, preset=None, interactive=False):
     if facility_name is None and interactive:
         answer = get_user_response(
-            "Do you wish to create a facility? [yn] ", ["y", "n"]
+            "Do you wish to create a facility? [y/n] ", ["y", "n"]
         )
         if answer == "y":
             facility_name = get_user_response(
@@ -94,7 +94,7 @@ def create_facility(facility_name=None, preset=None, interactive=False):
         if preset is None and interactive:
             preset = get_user_response(
                 "Which preset do you wish to use? [{presets}]: ".format(
-                    presets=",".join(presets.keys())
+                    presets="/".join(presets.keys())
                 ),
                 valid_answers=presets,
             )
@@ -102,6 +102,7 @@ def create_facility(facility_name=None, preset=None, interactive=False):
         # Only set preset data if we have created the facility, otherwise leave previous data intact
         if preset:
             dataset_data = mappings[preset]
+            facility.dataset.preset = preset
             for key, value in dataset_data.items():
                 check_facility_setting(key)
                 setattr(facility.dataset, key, value)
diff --git a/kolibri/core/device/serializers.py b/kolibri/core/device/serializers.py
--- a/kolibri/core/device/serializers.py
+++ b/kolibri/core/device/serializers.py
@@ -75,6 +75,7 @@ def create(self, validated_data):
             facility = Facility.objects.create(**validated_data.pop("facility"))
             preset = validated_data.pop("preset")
             dataset_data = mappings[preset]
+            facility.dataset.preset = preset
             for key, value in dataset_data.items():
                 setattr(facility.dataset, key, value)
             # overwrite the settings in dataset_data with validated_data.settings


Test patch: