Seed and bootstrap users via user_login.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
1 parent
4f0abceb20
commit
4eed6b2e87
9 files changed
+65
-43
No files matched your search
@@ -8,13 +8,13 @@ class ManagedByRequestTests(TestCase):
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.client = APIClient()
|
self.client = APIClient()
|
||||||
self.buh = User.objects.create_user(
|
self.buh = User.objects.create_user(
|
||||||
user_name="buh1", password="x", status=User.STATUS_BUH
|
user_login="buh1", password="x", status=User.STATUS_BUH
|
||||||
)
|
)
|
||||||
self.buh_other = User.objects.create_user(
|
self.buh_other = User.objects.create_user(
|
||||||
user_name="buh2", password="x", status=User.STATUS_BUH
|
user_login="buh2", password="x", status=User.STATUS_BUH
|
||||||
)
|
)
|
||||||
self.gm = User.objects.create_user(
|
self.gm = User.objects.create_user(
|
||||||
user_name="gm1", password="x", status=User.STATUS_GM
|
user_login="gm1", password="x", status=User.STATUS_GM
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_gm_requests_and_buh_approves(self):
|
def test_gm_requests_and_buh_approves(self):
|
||||||
@@ -60,7 +60,7 @@ class ManagedByRequestTests(TestCase):
|
|||||||
|
|
||||||
def test_gm_lists_buhs_only(self):
|
def test_gm_lists_buhs_only(self):
|
||||||
User.objects.create_user(
|
User.objects.create_user(
|
||||||
user_name="buadmin1", password="x", status=User.STATUS_BU_ADMIN
|
user_login="buadmin1", password="x", status=User.STATUS_BU_ADMIN
|
||||||
)
|
)
|
||||||
self.client.force_authenticate(self.gm)
|
self.client.force_authenticate(self.gm)
|
||||||
response = self.client.get("/api/v1/users/buhs/")
|
response = self.client.get("/api/v1/users/buhs/")
|
||||||
@@ -70,7 +70,7 @@ class ManagedByRequestTests(TestCase):
|
|||||||
|
|
||||||
def test_gm_admin_cannot_request_buh(self):
|
def test_gm_admin_cannot_request_buh(self):
|
||||||
gm_admin = User.objects.create_user(
|
gm_admin = User.objects.create_user(
|
||||||
user_name="gma1", password="x", status=User.STATUS_GM_ADMIN
|
user_login="gma1", password="x", status=User.STATUS_GM_ADMIN
|
||||||
)
|
)
|
||||||
self.client.force_authenticate(gm_admin)
|
self.client.force_authenticate(gm_admin)
|
||||||
response = self.client.post(
|
response = self.client.post(
|
||||||
@@ -80,7 +80,7 @@ class ManagedByRequestTests(TestCase):
|
|||||||
|
|
||||||
def test_gm_cannot_request_bu_admin(self):
|
def test_gm_cannot_request_bu_admin(self):
|
||||||
bu_admin = User.objects.create_user(
|
bu_admin = User.objects.create_user(
|
||||||
user_name="buadmin1", password="x", status=User.STATUS_BU_ADMIN
|
user_login="buadmin1", password="x", status=User.STATUS_BU_ADMIN
|
||||||
)
|
)
|
||||||
self.client.force_authenticate(self.gm)
|
self.client.force_authenticate(self.gm)
|
||||||
response = self.client.post(
|
response = self.client.post(
|
||||||
@@ -90,7 +90,7 @@ class ManagedByRequestTests(TestCase):
|
|||||||
|
|
||||||
def test_bu_admin_cannot_approve(self):
|
def test_bu_admin_cannot_approve(self):
|
||||||
bu_admin = User.objects.create_user(
|
bu_admin = User.objects.create_user(
|
||||||
user_name="buadmin1", password="x", status=User.STATUS_BU_ADMIN
|
user_login="buadmin1", password="x", status=User.STATUS_BU_ADMIN
|
||||||
)
|
)
|
||||||
self.gm.managed_by_pending = bu_admin
|
self.gm.managed_by_pending = bu_admin
|
||||||
self.gm.save(update_fields=["managed_by_pending", "updated_at"])
|
self.gm.save(update_fields=["managed_by_pending", "updated_at"])
|
||||||
|
|||||||
@@ -10,19 +10,19 @@ class VisibilityScopeTests(TestCase):
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.client = APIClient()
|
self.client = APIClient()
|
||||||
self.director = User.objects.create_user(
|
self.director = User.objects.create_user(
|
||||||
user_name="dir1", password="x", status=User.STATUS_DIRECTOR
|
user_login="dir1", password="x", status=User.STATUS_DIRECTOR
|
||||||
)
|
)
|
||||||
self.buh = User.objects.create_user(
|
self.buh = User.objects.create_user(
|
||||||
user_name="buh1", password="x", status=User.STATUS_BUH
|
user_login="buh1", password="x", status=User.STATUS_BUH
|
||||||
)
|
)
|
||||||
self.buh_other = User.objects.create_user(
|
self.buh_other = User.objects.create_user(
|
||||||
user_name="buh2", password="x", status=User.STATUS_BUH
|
user_login="buh2", password="x", status=User.STATUS_BUH
|
||||||
)
|
)
|
||||||
self.gm = User.objects.create_user(
|
self.gm = User.objects.create_user(
|
||||||
user_name="gm1", password="x", status=User.STATUS_GM, managed_by=self.buh
|
user_login="gm1", password="x", status=User.STATUS_GM, managed_by=self.buh
|
||||||
)
|
)
|
||||||
self.gm_other = User.objects.create_user(
|
self.gm_other = User.objects.create_user(
|
||||||
user_name="gm2",
|
user_login="gm2",
|
||||||
password="x",
|
password="x",
|
||||||
status=User.STATUS_GM,
|
status=User.STATUS_GM,
|
||||||
managed_by=self.buh_other,
|
managed_by=self.buh_other,
|
||||||
|
|||||||
+27
-14
@@ -7,18 +7,32 @@ from rest_framework.test import APIClient
|
|||||||
from apps.accounts.models import User
|
from apps.accounts.models import User
|
||||||
from apps.farms.models import Cycle, Flock, Kandang, Site
|
from apps.farms.models import Cycle, Flock, Kandang, Site
|
||||||
from apps.operations.models import FeedSacks, ManualInput
|
from apps.operations.models import FeedSacks, ManualInput
|
||||||
|
from apps.sync.models import CitySite
|
||||||
|
|
||||||
|
|
||||||
|
def _gm_visible_site(*, owner: User, site_name: str, code: str) -> Site:
|
||||||
|
"""GM scope only sees sites linked to an active CitySite they registered."""
|
||||||
|
city = CitySite.objects.create(
|
||||||
|
code=code,
|
||||||
|
name=site_name,
|
||||||
|
api_base_url=f"https://{code}.example/api/v1",
|
||||||
|
registered_by=owner,
|
||||||
|
)
|
||||||
|
return Site.objects.create(site_name=site_name, user=owner, city_site=city)
|
||||||
|
|
||||||
|
|
||||||
class FarmAPITests(TestCase):
|
class FarmAPITests(TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.user = User.objects.create_user(user_name="tester", password="secret")
|
self.user = User.objects.create_user(user_login="tester", password="secret")
|
||||||
self.admin = User.objects.create_user(
|
self.admin = User.objects.create_user(
|
||||||
user_name="admin",
|
user_login="admin",
|
||||||
password="secret",
|
password="secret",
|
||||||
status=User.STATUS_DIRECTOR_ADMIN,
|
status=User.STATUS_DIRECTOR_ADMIN,
|
||||||
)
|
)
|
||||||
self.client = APIClient()
|
self.client = APIClient()
|
||||||
self.site = Site.objects.create(site_name="Sukawarna", user=self.user)
|
self.site = _gm_visible_site(
|
||||||
|
owner=self.user, site_name="Sukawarna", code="sukawarna"
|
||||||
|
)
|
||||||
self.kandang = Kandang.objects.create(kandang_name="Kandang 1", site=self.site)
|
self.kandang = Kandang.objects.create(kandang_name="Kandang 1", site=self.site)
|
||||||
|
|
||||||
def test_create_flock_under_kandang_requires_director_admin(self):
|
def test_create_flock_under_kandang_requires_director_admin(self):
|
||||||
@@ -73,12 +87,9 @@ class FarmAPITests(TestCase):
|
|||||||
doc_in_count=9000,
|
doc_in_count=9000,
|
||||||
status=Cycle.STATUS_ACTIVE,
|
status=Cycle.STATUS_ACTIVE,
|
||||||
)
|
)
|
||||||
new_end = start + timedelta(days=39)
|
|
||||||
response = self.client.patch(
|
response = self.client.patch(
|
||||||
f"/api/v1/cycles/{cycle.pk}/",
|
f"/api/v1/cycles/{cycle.pk}/",
|
||||||
{
|
{
|
||||||
"end_date": new_end.isoformat(),
|
|
||||||
"total_days": 40,
|
|
||||||
"doc_in_count": 9500,
|
"doc_in_count": 9500,
|
||||||
"chick_in_weight": 42,
|
"chick_in_weight": 42,
|
||||||
},
|
},
|
||||||
@@ -86,8 +97,8 @@ class FarmAPITests(TestCase):
|
|||||||
)
|
)
|
||||||
self.assertEqual(response.status_code, 200, response.data)
|
self.assertEqual(response.status_code, 200, response.data)
|
||||||
cycle.refresh_from_db()
|
cycle.refresh_from_db()
|
||||||
self.assertEqual(cycle.end_date, new_end)
|
# end_date is not writable via PATCH (close flow uses approve-close).
|
||||||
self.assertEqual(cycle.total_days, 40)
|
self.assertEqual(cycle.end_date, start + timedelta(days=34))
|
||||||
self.assertEqual(cycle.doc_in_count, 9500)
|
self.assertEqual(cycle.doc_in_count, 9500)
|
||||||
self.assertEqual(cycle.doc_in_weight, 42)
|
self.assertEqual(cycle.doc_in_weight, 42)
|
||||||
|
|
||||||
@@ -113,8 +124,8 @@ class FarmAPITests(TestCase):
|
|||||||
self.assertEqual(cycle.status, Cycle.STATUS_ACTIVE)
|
self.assertEqual(cycle.status, Cycle.STATUS_ACTIVE)
|
||||||
|
|
||||||
def test_gm_can_approve_cycle_close(self):
|
def test_gm_can_approve_cycle_close(self):
|
||||||
gm = User.objects.create_user(user_name="gm_approver", password="x", status=User.STATUS_GM)
|
gm = User.objects.create_user(user_login="gm_approver", password="x", status=User.STATUS_GM)
|
||||||
site = Site.objects.create(site_name="GM Site", user=gm)
|
site = _gm_visible_site(owner=gm, site_name="GM Site", code="gm-approve")
|
||||||
kandang = Kandang.objects.create(kandang_name="Kandang GM", site=site)
|
kandang = Kandang.objects.create(kandang_name="Kandang GM", site=site)
|
||||||
self.client.force_authenticate(gm)
|
self.client.force_authenticate(gm)
|
||||||
start = date(2026, 8, 1)
|
start = date(2026, 8, 1)
|
||||||
@@ -143,8 +154,8 @@ class FarmAPITests(TestCase):
|
|||||||
self.assertEqual(cycle.end_date, proposed)
|
self.assertEqual(cycle.end_date, proposed)
|
||||||
|
|
||||||
def test_gm_can_reject_cycle_close(self):
|
def test_gm_can_reject_cycle_close(self):
|
||||||
gm = User.objects.create_user(user_name="gm_rejector", password="x", status=User.STATUS_GM)
|
gm = User.objects.create_user(user_login="gm_rejector", password="x", status=User.STATUS_GM)
|
||||||
site = Site.objects.create(site_name="GM Reject Site", user=gm)
|
site = _gm_visible_site(owner=gm, site_name="GM Reject Site", code="gm-reject")
|
||||||
kandang = Kandang.objects.create(kandang_name="Kandang R", site=site)
|
kandang = Kandang.objects.create(kandang_name="Kandang R", site=site)
|
||||||
self.client.force_authenticate(gm)
|
self.client.force_authenticate(gm)
|
||||||
start = date(2026, 8, 1)
|
start = date(2026, 8, 1)
|
||||||
@@ -170,9 +181,11 @@ class FarmAPITests(TestCase):
|
|||||||
|
|
||||||
def test_gm_admin_cannot_approve_cycle_close(self):
|
def test_gm_admin_cannot_approve_cycle_close(self):
|
||||||
gm_admin = User.objects.create_user(
|
gm_admin = User.objects.create_user(
|
||||||
user_name="gm_admin_user", password="x", status=User.STATUS_GM_ADMIN
|
user_login="gm_admin_user", password="x", status=User.STATUS_GM_ADMIN
|
||||||
|
)
|
||||||
|
site = _gm_visible_site(
|
||||||
|
owner=gm_admin, site_name="GM Admin Site", code="gm-admin-site"
|
||||||
)
|
)
|
||||||
site = Site.objects.create(site_name="GM Admin Site", user=gm_admin)
|
|
||||||
kandang = Kandang.objects.create(kandang_name="Kandang GMA", site=site)
|
kandang = Kandang.objects.create(kandang_name="Kandang GMA", site=site)
|
||||||
self.client.force_authenticate(gm_admin)
|
self.client.force_authenticate(gm_admin)
|
||||||
start = date(2026, 8, 1)
|
start = date(2026, 8, 1)
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ from apps.accounts.models import ApiKey, User
|
|||||||
|
|
||||||
def ensure_bootstrap_user(
|
def ensure_bootstrap_user(
|
||||||
*,
|
*,
|
||||||
user_name: str,
|
user_login: str,
|
||||||
password: str,
|
password: str,
|
||||||
status: str,
|
status: str,
|
||||||
is_superuser: bool,
|
is_superuser: bool,
|
||||||
@@ -15,8 +15,9 @@ def ensure_bootstrap_user(
|
|||||||
stdout,
|
stdout,
|
||||||
) -> User:
|
) -> User:
|
||||||
user, created = User.objects.get_or_create(
|
user, created = User.objects.get_or_create(
|
||||||
user_name=user_name,
|
user_login=user_login,
|
||||||
defaults={
|
defaults={
|
||||||
|
"user_name": user_login,
|
||||||
"status": status,
|
"status": status,
|
||||||
"is_superuser": is_superuser,
|
"is_superuser": is_superuser,
|
||||||
},
|
},
|
||||||
@@ -24,7 +25,7 @@ def ensure_bootstrap_user(
|
|||||||
|
|
||||||
if not created and user.status != status:
|
if not created and user.status != status:
|
||||||
stdout.write(
|
stdout.write(
|
||||||
f"Updating {user_name!r} status {user.status!r} → {status!r}"
|
f"Updating {user_login!r} status {user.status!r} → {status!r}"
|
||||||
)
|
)
|
||||||
|
|
||||||
should_set_password = created or not user.has_usable_password() or force_password
|
should_set_password = created or not user.has_usable_password() or force_password
|
||||||
@@ -34,12 +35,12 @@ def ensure_bootstrap_user(
|
|||||||
user.is_superuser = is_superuser
|
user.is_superuser = is_superuser
|
||||||
user.save()
|
user.save()
|
||||||
action = "Created" if created else "Updated password for"
|
action = "Created" if created else "Updated password for"
|
||||||
stdout.write(f"{action} {status} user {user_name}")
|
stdout.write(f"{action} {status} user {user_login}")
|
||||||
else:
|
else:
|
||||||
user.status = status
|
user.status = status
|
||||||
user.is_superuser = is_superuser
|
user.is_superuser = is_superuser
|
||||||
user.save(update_fields=["status", "is_superuser", "updated_at"])
|
user.save(update_fields=["status", "is_superuser", "updated_at"])
|
||||||
stdout.write(f"User {user_name} already exists (password unchanged)")
|
stdout.write(f"User {user_login} already exists (password unchanged)")
|
||||||
|
|
||||||
return user
|
return user
|
||||||
|
|
||||||
@@ -70,7 +71,7 @@ class Command(BaseCommand):
|
|||||||
)
|
)
|
||||||
|
|
||||||
admin = ensure_bootstrap_user(
|
admin = ensure_bootstrap_user(
|
||||||
user_name=admin_user_name,
|
user_login=admin_user_name,
|
||||||
password=admin_password,
|
password=admin_password,
|
||||||
status=User.STATUS_SUPERUSER,
|
status=User.STATUS_SUPERUSER,
|
||||||
is_superuser=True,
|
is_superuser=True,
|
||||||
@@ -90,7 +91,7 @@ class Command(BaseCommand):
|
|||||||
"BOOTSTRAP_STAFF_PASSWORD is required when BOOTSTRAP_STAFF_USER is set."
|
"BOOTSTRAP_STAFF_PASSWORD is required when BOOTSTRAP_STAFF_USER is set."
|
||||||
)
|
)
|
||||||
ensure_bootstrap_user(
|
ensure_bootstrap_user(
|
||||||
user_name=staff_user_name,
|
user_login=staff_user_name,
|
||||||
password=staff_password,
|
password=staff_password,
|
||||||
status=User.STATUS_GM,
|
status=User.STATUS_GM,
|
||||||
is_superuser=False,
|
is_superuser=False,
|
||||||
|
|||||||
@@ -75,8 +75,11 @@ class Command(BaseCommand):
|
|||||||
defaults["managed_by"] = managed_by
|
defaults["managed_by"] = managed_by
|
||||||
|
|
||||||
user, created = User.objects.get_or_create(
|
user, created = User.objects.get_or_create(
|
||||||
user_name=spec["user_name"],
|
user_login=spec["user_name"],
|
||||||
defaults=defaults,
|
defaults={
|
||||||
|
**defaults,
|
||||||
|
"user_name": spec["user_name"],
|
||||||
|
},
|
||||||
)
|
)
|
||||||
user.status = spec["status"]
|
user.status = spec["status"]
|
||||||
user.is_superuser = spec.get("is_superuser", False)
|
user.is_superuser = spec.get("is_superuser", False)
|
||||||
@@ -98,7 +101,10 @@ class Command(BaseCommand):
|
|||||||
return user
|
return user
|
||||||
|
|
||||||
def _remove_legacy_staff(self, gm: User) -> None:
|
def _remove_legacy_staff(self, gm: User) -> None:
|
||||||
staff = User.objects.filter(user_name="staff").first()
|
staff = (
|
||||||
|
User.objects.filter(user_login="staff").first()
|
||||||
|
or User.objects.filter(user_name="staff").first()
|
||||||
|
)
|
||||||
if not staff:
|
if not staff:
|
||||||
return
|
return
|
||||||
moved_sites = Site.objects.filter(user=staff).update(user=gm)
|
moved_sites = Site.objects.filter(user=staff).update(user=gm)
|
||||||
|
|||||||
@@ -15,7 +15,8 @@ from django.core.management import call_command
|
|||||||
class BootstrapAdminTests(TestCase):
|
class BootstrapAdminTests(TestCase):
|
||||||
def test_creates_break_glass_superuser_without_demo_data(self):
|
def test_creates_break_glass_superuser_without_demo_data(self):
|
||||||
call_command("bootstrap_admin")
|
call_command("bootstrap_admin")
|
||||||
user = User.objects.get(user_name="admin")
|
user = User.objects.get(user_login="admin")
|
||||||
|
self.assertEqual(user.user_name, "admin")
|
||||||
self.assertEqual(user.status, User.STATUS_SUPERUSER)
|
self.assertEqual(user.status, User.STATUS_SUPERUSER)
|
||||||
self.assertTrue(user.is_superuser)
|
self.assertTrue(user.is_superuser)
|
||||||
self.assertTrue(user.check_password("Pr04dm1n"))
|
self.assertTrue(user.check_password("Pr04dm1n"))
|
||||||
@@ -33,7 +34,8 @@ class BootstrapAdminTests(TestCase):
|
|||||||
)
|
)
|
||||||
def test_creates_gm_when_configured(self):
|
def test_creates_gm_when_configured(self):
|
||||||
call_command("bootstrap_admin")
|
call_command("bootstrap_admin")
|
||||||
staff = User.objects.get(user_name="staff")
|
staff = User.objects.get(user_login="staff")
|
||||||
|
self.assertEqual(staff.user_name, "staff")
|
||||||
self.assertEqual(staff.status, User.STATUS_GM)
|
self.assertEqual(staff.status, User.STATUS_GM)
|
||||||
self.assertFalse(staff.is_superuser)
|
self.assertFalse(staff.is_superuser)
|
||||||
self.assertTrue(staff.check_password("St4ff!"))
|
self.assertTrue(staff.check_password("St4ff!"))
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ from apps.operations.models import ChickenWeight, FeedSacks, IotPanel
|
|||||||
@override_settings(DASHBOARD_PUBLISH_HOUR=0)
|
@override_settings(DASHBOARD_PUBLISH_HOUR=0)
|
||||||
class OperationsAPITests(TestCase):
|
class OperationsAPITests(TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.user = User.objects.create_user(user_name="tester", password="secret")
|
self.user = User.objects.create_user(user_login="tester", password="secret")
|
||||||
self.client = APIClient()
|
self.client = APIClient()
|
||||||
self.client.force_authenticate(self.user)
|
self.client.force_authenticate(self.user)
|
||||||
site = Site.objects.create(site_name="Sukawarna", user=self.user)
|
site = Site.objects.create(site_name="Sukawarna", user=self.user)
|
||||||
@@ -311,7 +311,7 @@ class OperationsAPITests(TestCase):
|
|||||||
@override_settings(DASHBOARD_PUBLISH_HOUR=17, TIME_ZONE="Asia/Jakarta")
|
@override_settings(DASHBOARD_PUBLISH_HOUR=17, TIME_ZONE="Asia/Jakarta")
|
||||||
class DashboardVisibilityTests(TestCase):
|
class DashboardVisibilityTests(TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.user = User.objects.create_user(user_name="tester", password="secret")
|
self.user = User.objects.create_user(user_login="tester", password="secret")
|
||||||
self.client = APIClient()
|
self.client = APIClient()
|
||||||
self.client.force_authenticate(self.user)
|
self.client.force_authenticate(self.user)
|
||||||
site = Site.objects.create(site_name="Sukawarna", user=self.user)
|
site = Site.objects.create(site_name="Sukawarna", user=self.user)
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ class AggregationTests(TestCase):
|
|||||||
)
|
)
|
||||||
class SyncChickenCountingTests(TestCase):
|
class SyncChickenCountingTests(TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
user = User.objects.create_user(user_name="sync-user", password="secret")
|
user = User.objects.create_user(user_login="sync-user", password="secret")
|
||||||
site = Site.objects.create(site_name="Sukawarna", user=user)
|
site = Site.objects.create(site_name="Sukawarna", user=user)
|
||||||
self.kandang = Kandang.objects.create(kandang_name="Kandang 1", site=site)
|
self.kandang = Kandang.objects.create(kandang_name="Kandang 1", site=site)
|
||||||
self.cycle = Cycle.objects.create(
|
self.cycle = Cycle.objects.create(
|
||||||
@@ -130,7 +130,7 @@ class SyncChickenCountingTests(TestCase):
|
|||||||
)
|
)
|
||||||
class ChickenCountingSyncApiTests(TestCase):
|
class ChickenCountingSyncApiTests(TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.user = User.objects.create_user(user_name="tester", password="secret")
|
self.user = User.objects.create_user(user_login="tester", password="secret")
|
||||||
self.client = APIClient()
|
self.client = APIClient()
|
||||||
self.client.force_authenticate(self.user)
|
self.client.force_authenticate(self.user)
|
||||||
site = Site.objects.create(site_name="Sukawarna", user=self.user)
|
site = Site.objects.create(site_name="Sukawarna", user=self.user)
|
||||||
|
|||||||
@@ -156,7 +156,7 @@ class KarungWebCombinedTests(TestCase):
|
|||||||
@override_settings(KARUNG_WEB_ADMIN_BASE_URL="http://karung.internal")
|
@override_settings(KARUNG_WEB_ADMIN_BASE_URL="http://karung.internal")
|
||||||
class RequestKarungTests(TestCase):
|
class RequestKarungTests(TestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
user = User.objects.create_user(user_name="tester", password="secret")
|
user = User.objects.create_user(user_login="tester", password="secret")
|
||||||
site = Site.objects.create(site_name="Sukawarna", user=user)
|
site = Site.objects.create(site_name="Sukawarna", user=user)
|
||||||
self.kandang1 = Kandang.objects.create(kandang_name="Kandang 1", site=site)
|
self.kandang1 = Kandang.objects.create(kandang_name="Kandang 1", site=site)
|
||||||
self.kandang2 = Kandang.objects.create(kandang_name="Kandang 2", site=site)
|
self.kandang2 = Kandang.objects.create(kandang_name="Kandang 2", site=site)
|
||||||
|
|||||||
Reference in new issue
Block a user