Skip to content

Conversation

ozer550
Copy link
Member

@ozer550 ozer550 commented May 29, 2025

Summary

  • Add the all_objects manager class for FacilityUsers.
  • Implement all_objects call in bulk import.
  • Unit tests.

References

closes #13376

Reviewer guidance

  • We would want to confirm that all the existing features for bulkImport work as expected.
  • Especially need to test that the soft deleted user is undeleted when we import it using the csv.
    Steps to Reciprocate:
  • unzip the sqlite file in KOLIBRI_HOME folder. (This has soft deleted user a)
  • Restore the users using the linked csv.
  • check that user "a" is restored.
    db_with_deleted_users.zip
    ozer_2420_users.csv

@github-actions github-actions bot added SIZE: small DEV: backend Python, databases, networking, filesystem... labels May 29, 2025
Copy link
Contributor

github-actions bot commented May 29, 2025

Copy link
Member

@nucleogenesis nucleogenesis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good so far although it may require some coordination with Alex's .objects PR.

password=make_password("password"),
facility=self.facility,
)
deleted_user.delete()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.delete here will actually remove the user from the db rather than "soft-deleting" them. If you want to soft-delete the user you'll need to set its date_deleted field to a date.

)
deleted_user.delete()

self.assertEqual(FacilityUser.objects.count(), 1)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line won't work until Alex's PR changing the .objects queryset is merged.

@ozer550 ozer550 force-pushed the implement-all-objects-manager-class branch from e9d5f4f to b553c3b Compare June 2, 2025 17:27
@ozer550 ozer550 force-pushed the implement-all-objects-manager-class branch from b553c3b to 4c08b3e Compare June 3, 2025 05:57
@ozer550 ozer550 marked this pull request as ready for review June 3, 2025 10:46
@ozer550 ozer550 changed the title implemented all_objects manager class Implement all_objects manager class in FacilityUser Jun 3, 2025
@ozer550
Copy link
Member Author

ozer550 commented Jun 3, 2025

Would need QA on this @pcenov @radinamatic specifically on bulkUserImport features and the feature that import from csv undeletes soft deleted_user.

@ozer550 ozer550 requested a review from nucleogenesis June 3, 2025 11:14
@LianaHarris360 LianaHarris360 self-assigned this Jun 3, 2025
Copy link
Member

@LianaHarris360 LianaHarris360 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changes in the models file look good, I just had a few thoughts on the updated tests.

self.facility = Facility.objects.create(name="My Facility")

def test_all_objects_manager_returns_all_users(self):
deleted_user = FacilityUser.objects.create(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just noting that you can set the date_deleted field when the user is initially created as well. Then you wouldn't have to set it below and save the change separately.

def test_all_objects_manager_returns_all_users(self):
deleted_user = FacilityUser.objects.create(
username="deleted_user",
password=make_password("password"),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a particular reason to use Django's make_password for password hashing here? Mostly wondering because the other passwords in this file are just set as "password".

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ahh seems like this was a co-pilot tab complete that I overlooked.

@@ -662,6 +663,28 @@ def test_default_facility_returns_none_when_no_settings(self):


class FacilityUserTestCase(TestCase):
def setUp(self):
self.facility = Facility.objects.create(name="My Facility")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it makes sense to create the facility in a setup function when that facility is expected to be reused, but in this case, it should be fine to follow the pattern of the other functions below and use the line self.facility = Facility.objects.create() directly within test_all_objects_manager_returns_all_users()

@ozer550 ozer550 requested a review from LianaHarris360 June 4, 2025 06:32
@pcenov
Copy link
Member

pcenov commented Jun 4, 2025

Hi @ozer550 I am getting the following error when I try to start Kolibri after having replaced the db.sqlite3 file with the one provided in the PR:

osboxes@osboxes:~$ kolibri start
INFO     2025-06-04 15:33:38,064 Option DEBUG in section [Server] being overridden by environment variable KOLIBRI_DEBUG
INFO     2025-06-04 15:33:38,065 Option DEBUG_LOG_DATABASE in section [Server] being overridden by environment variable KOLIBRI_DEBUG_LOG_DATABASE
INFO     2025-06-04 15:33:38,065 Option RUN_MODE in section [Deployment] being overridden by environment variable KOLIBRI_RUN_MODE
Error: Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/kolibri/utils/cli.py", line 199, in invoke
    initialize(**get_initialize_params())
  File "/usr/lib/python3/dist-packages/kolibri/utils/main.py", line 317, in initialize
    _upgrades_before_django_setup(updated, version)
  File "/usr/lib/python3/dist-packages/kolibri/utils/main.py", line 237, in _upgrades_before_django_setup
    sqlite_check_foreign_keys()
  File "/usr/lib/python3/dist-packages/kolibri/utils/main.py", line 196, in sqlite_check_foreign_keys
    cursor.execute("PRAGMA foreign_key_check;")
sqlite3.DatabaseError: database disk image is malformed

Could you have a look and let me know how we can proceed? Thanks!

@radinamatic
Copy link
Member

@pcenov Could you try following these steps from our user docs, and see if with them you manage to fix the malformed DB?

https://kolibri.readthedocs.io/en/latest/manage/get_support.html#malformed-database

@pcenov
Copy link
Member

pcenov commented Jun 4, 2025

The steps in https://kolibri.readthedocs.io/en/latest/manage/get_support.html#malformed-database are not working for this case where we are intentionally replacing the DB with the one provided in the PR.
Hopefully @ozer550 will provide more clarity on the matter, any additional points for the manual QA required here will be greatly appreciated too!

@LianaHarris360
Copy link
Member

LianaHarris360 commented Jun 4, 2025

I had the same problem as Peter. Do we maybe need the entire KOLIBRI_HOME folder instead of only the sqlite file?
I was able to restore a "soft" deleted user using a CSV import, it required writing some python code within the terminal. I can confirm that the all_objects call in bulk import works as expected.

@ozer550
Copy link
Member Author

ozer550 commented Jun 4, 2025

Hi @pcenov and @radinamatic it seems like its a little more complicated then just sharing the database file to reciprocate the state of my kolibri. I synced up with @LianaHarris360 and specifically walked her thorough regression testing the restoration of soft deleted user. So I think if @pcenov can now regression test on other features related with bulk import, we would be quite sure that we have whats expected.

@ozer550
Copy link
Member Author

ozer550 commented Jun 4, 2025

To clarify more, the only way to currently soft delete the user is to log in thru shell and then run a query to soft delete the user. I thought that sharing the database file would actually replicate the soft deleted user for you and you would not need to run those queries, but seems like it doesn't work that way. If we would want to document exact steps on how I regression tested this, I could write some docs if that would be helpful.

@pcenov
Copy link
Member

pcenov commented Jun 9, 2025

Thanks @ozer550 - no regressions observed while manually testing the bulk import.

Copy link
Member

@LianaHarris360 LianaHarris360 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be good to merge in now!

@LianaHarris360 LianaHarris360 merged commit c4ca571 into learningequality:develop Jun 9, 2025
51 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
DEV: backend Python, databases, networking, filesystem... SIZE: medium SIZE: small
Projects
None yet
Development

Successfully merging this pull request may close these issues.

FacilityUser: Add new all_objects manager class
5 participants