Repository: learningequality/kolibri

Issue:
new accounts are seemingly created in the wrong facility

### Observed behavior

Accounts created in one facility seem to actually get created in another facility.

### Expected behavior

Facility should be correct. Might be related to #5812, so we should address that issue at the same time.

### User-facing consequences

Users cannot log in

### Errors and logs
<!--
Relevant logs from:
 * the command line
 * ~/.kolibri/logs/kolibri.txt
 * the browser console

Please wrap errors in triple backticks for clean formatting like this:
```
01:10 info: something happened
01:12 error: something bad happened
```
-->

…

### Steps to reproduce

* Navigate to https://mexico.unwomendemo.learningequality.org
* Select facility 'Nueva York'
* Go to the account creation page
* Re-select facility 'Nueva York' (#5812) and create a test account
* Log out
* Navigate back to https://mexico.unwomendemo.learningequality.org
* Select facility 'Nueva York'
* Try to log in - it doesn't work
* Reload page
* Select facility 'No pertenezco a ningún centro'
* Try to log in - it works

### Context

0.12.7



Discussion:
I think it's because the passed-in facility ID is being ignored. The `create` method for the SignUpSerializer just ignores the facility ID that's passed into the payload.

https://github.com/learningequality/kolibri/blob/f22b5a7b084de69110d8ee42aafe38b876acd89e/kolibri/core/auth/api.py#L294-L301

@ralphiee22 Just change that one line to actually use what's in `request.data`?
That certainly seems like the issue - I imagine it is set to the default facility for safety, maybe change it to:
`"facility": request.data.get("facility", Facility.get_default_facility().id),`

Resolving patch:
diff --git a/kolibri/core/auth/api.py b/kolibri/core/auth/api.py
--- a/kolibri/core/auth/api.py
+++ b/kolibri/core/auth/api.py
@@ -296,7 +296,9 @@ def extract_request_data(self, request):
             "username": request.data.get("username", ""),
             "full_name": request.data.get("full_name", ""),
             "password": request.data.get("password", ""),
-            "facility": Facility.get_default_facility().id,
+            "facility": request.data.get(
+                "facility", Facility.get_default_facility().id
+            ),
         }
 
     def create(self, request):


Test patch:
diff --git a/kolibri/core/auth/test/test_api.py b/kolibri/core/auth/test/test_api.py
--- a/kolibri/core/auth/test/test_api.py
+++ b/kolibri/core/auth/test/test_api.py
@@ -7,7 +7,6 @@
 from importlib import import_module
 
 import factory
-import mock
 from django.conf import settings
 from django.core.urlresolvers import reverse
 from rest_framework import status
@@ -612,72 +611,80 @@ def setUp(self):
         self.facility = FacilityFactory.create()
         provision_device()
 
+    def post_to_sign_up(self, data):
+        return self.client.post(reverse("kolibri:core:signup-list"), data=data)
+
     def test_anon_sign_up_creates_user(self):
-        response = self.client.post(
-            reverse("kolibri:core:signup-list"),
-            data={"username": "user", "password": DUMMY_PASSWORD},
+        response = self.post_to_sign_up(
+            {"username": "user", "password": DUMMY_PASSWORD}
         )
         self.assertEqual(response.status_code, status.HTTP_201_CREATED)
         self.assertTrue(models.FacilityUser.objects.all())
 
     def test_anon_sign_up_returns_user(self):
         full_name = "Bob Lee"
-        response = self.client.post(
-            reverse("kolibri:core:signup-list"),
-            data={
-                "full_name": full_name,
-                "username": "user",
-                "password": DUMMY_PASSWORD,
-            },
+        response = self.post_to_sign_up(
+            {"full_name": full_name, "username": "user", "password": DUMMY_PASSWORD}
         )
         self.assertEqual(response.data["username"], "user")
         self.assertEqual(response.data["full_name"], full_name)
 
     def test_create_user_with_same_username_case_insensitive_fails(self):
         FacilityUserFactory.create(username="bob", facility=self.facility)
-        response = self.client.post(
-            reverse("kolibri:core:signup-list"),
-            data={"username": "BOB", "password": DUMMY_PASSWORD},
-        )
+        response = self.post_to_sign_up({"username": "BOB", "password": DUMMY_PASSWORD})
         self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
         self.assertEqual(len(models.FacilityUser.objects.all()), 1)
 
     def test_create_user_with_same_username_other_facility(self):
         user = FacilityUserFactory.create(username="bob")
         other_facility = models.Facility.objects.exclude(id=user.facility.id)[0]
-        with mock.patch(
-            "kolibri.core.auth.models.Facility.get_default_facility",
-            return_value=other_facility,
-        ):
-            response = self.client.post(
-                reverse("kolibri:core:signup-list"),
-                data={"username": "bob", "password": DUMMY_PASSWORD},
-            )
+        response = self.post_to_sign_up(
+            {
+                "username": "bob",
+                "password": DUMMY_PASSWORD,
+                "facility": other_facility.id,
+            }
+        )
         self.assertEqual(response.status_code, status.HTTP_201_CREATED)
-        self.assertEqual(len(models.FacilityUser.objects.all()), 2)
+        self.assertEqual(
+            models.FacilityUser.objects.filter(facility=self.facility.id).count(), 1
+        )
+        self.assertEqual(
+            models.FacilityUser.objects.filter(facility=other_facility.id).count(), 1
+        )
+
+    def test_create_user_for_specific_facility(self):
+        other_facility = FacilityFactory.create()
+        response = self.post_to_sign_up(
+            {
+                "username": "bob",
+                "password": DUMMY_PASSWORD,
+                "facility": other_facility.id,
+            }
+        )
+        user_id = response.data["id"]
+        self.assertEqual(
+            models.FacilityUser.objects.get(id=user_id).facility.id, other_facility.id
+        )
+        self.assertTrue(other_facility.get_members().filter(id=user_id).exists())
 
     def test_create_bad_username_fails(self):
-        response = self.client.post(
-            reverse("kolibri:core:signup-list"),
-            data={"username": "(***)", "password": DUMMY_PASSWORD},
+        response = self.post_to_sign_up(
+            {"username": "(***)", "password": DUMMY_PASSWORD}
         )
         self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
         self.assertFalse(models.FacilityUser.objects.all())
 
     def test_sign_up_also_logs_in_user(self):
         session_key = self.client.session.session_key
-        self.client.post(
-            reverse("kolibri:core:signup-list"),
-            data={"username": "user", "password": DUMMY_PASSWORD},
-        )
+        self.post_to_sign_up({"username": "user", "password": DUMMY_PASSWORD})
         self.assertNotEqual(session_key, self.client.session.session_key)
 
     def test_sign_up_able_no_guest_access(self):
         self.facility.dataset.allow_guest_access = False
         self.facility.dataset.save()
-        response = self.client.post(
-            reverse("kolibri:core:signup-list"),
-            data={"username": "user", "password": DUMMY_PASSWORD},
+        response = self.post_to_sign_up(
+            {"username": "user", "password": DUMMY_PASSWORD}
         )
         self.assertEqual(response.status_code, status.HTTP_201_CREATED)
         self.assertTrue(models.FacilityUser.objects.all())
diff --git a/kolibri/plugins/user/assets/test/views/sign-up-page.spec.js b/kolibri/plugins/user/assets/test/views/sign-up-page.spec.js
--- a/kolibri/plugins/user/assets/test/views/sign-up-page.spec.js
+++ b/kolibri/plugins/user/assets/test/views/sign-up-page.spec.js
@@ -4,8 +4,10 @@ import SignUpPage from '../../src/views/SignUpPage';
 import makeStore from '../makeStore';
 
 function makeWrapper() {
+  const store = makeStore();
+  store.state.core.facilities = [{ id: 1, name: 'facility' }];
   return mount(SignUpPage, {
-    store: makeStore(),
+    store,
     router: new VueRouter({
       routes: [{ name: 'SIGN_IN', path: '/signin' }],
     }),