Repository: safe-global/safe-config-service

Issue:
Bootstrap database with default data for the /safe-apps endpoint 
When the database is created and the service is running, we should offer the option/utility to bootstrap it with the default list of safe-apps.

Default database should contain the following data: https://github.com/gnosis/safe-apps-list/blob/development/public/gnosis-default.applist.json


Discussion:

Resolving patch:
diff --git a/src/safe_apps/migrations/0001_initial.py b/src/safe_apps/migrations/0001_initial.py
--- a/src/safe_apps/migrations/0001_initial.py
+++ b/src/safe_apps/migrations/0001_initial.py
@@ -1,4 +1,4 @@
-# Generated by Django 3.2 on 2021-04-16 14:52
+# Generated by Django 3.2 on 2021-04-28 13:39
 
 import django.contrib.postgres.fields
 from django.db import migrations, models
@@ -15,8 +15,7 @@ class Migration(migrations.Migration):
         migrations.CreateModel(
             name='SafeApp',
             fields=[
-                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
-                ('url', models.URLField()),
+                ('url', models.URLField(primary_key=True, serialize=False)),
                 ('name', models.CharField(max_length=200)),
                 ('icon_url', models.URLField()),
                 ('description', models.CharField(max_length=200)),
diff --git a/src/safe_apps/models.py b/src/safe_apps/models.py
--- a/src/safe_apps/models.py
+++ b/src/safe_apps/models.py
@@ -3,7 +3,7 @@
 
 
 class SafeApp(models.Model):
-    url = models.URLField()
+    url = models.URLField(primary_key=True)
     name = models.CharField(max_length=200)
     icon_url = models.URLField()
     description = models.CharField(max_length=200)


Test patch:
diff --git a/src/safe_apps/tests/test_views.py b/src/safe_apps/tests/test_views.py
--- a/src/safe_apps/tests/test_views.py
+++ b/src/safe_apps/tests/test_views.py
@@ -47,7 +47,7 @@ class FilterSafeAppListViewTests(APITestCase):
 
     def setUp(self) -> None:
         SafeApp.objects.create(
-            url="https://example.com",
+            url="https://example.com/1",
             name="test_safe_app_1",
             icon_url="https://example.com/icon",
             description="safe_app_description_1",
@@ -55,7 +55,7 @@ def setUp(self) -> None:
         )
 
         SafeApp.objects.create(
-            url="https://example.com",
+            url="https://example.com/2",
             name="test_safe_app_2",
             icon_url="https://example.com/icon",
             description="safe_app_description_2",
@@ -63,7 +63,7 @@ def setUp(self) -> None:
         )
 
         SafeApp.objects.create(
-            url="https://example.com",
+            url="https://example.com/3",
             name="test_safe_app_3",
             icon_url="https://example.com/icon",
             description="safe_app_description_3",
@@ -73,21 +73,21 @@ def setUp(self) -> None:
     def test_all_safes_returned(self):
         json_response = [
             {
-                'url': 'https://example.com',
+                'url': 'https://example.com/1',
                 'name': 'test_safe_app_1',
                 'icon_url': 'https://example.com/icon',
                 'description': 'safe_app_description_1',
                 'networks': [1]
             },
             {
-                'url': 'https://example.com',
+                'url': 'https://example.com/2',
                 'name': 'test_safe_app_2',
                 'icon_url': 'https://example.com/icon',
                 'description': 'safe_app_description_2',
                 'networks': [1]
             },
             {
-                'url': 'https://example.com',
+                'url': 'https://example.com/3',
                 'name': 'test_safe_app_3',
                 'icon_url': 'https://example.com/icon',
                 'description': 'safe_app_description_3',
@@ -104,21 +104,21 @@ def test_all_safes_returned(self):
     def test_all_apps_returned_on_empty_network_value(self):
         json_response = [
             {
-                'url': 'https://example.com',
+                'url': 'https://example.com/1',
                 'name': 'test_safe_app_1',
                 'icon_url': 'https://example.com/icon',
                 'description': 'safe_app_description_1',
                 'networks': [1]
             },
             {
-                'url': 'https://example.com',
+                'url': 'https://example.com/2',
                 'name': 'test_safe_app_2',
                 'icon_url': 'https://example.com/icon',
                 'description': 'safe_app_description_2',
                 'networks': [1]
             },
             {
-                'url': 'https://example.com',
+                'url': 'https://example.com/3',
                 'name': 'test_safe_app_3',
                 'icon_url': 'https://example.com/icon',
                 'description': 'safe_app_description_3',
@@ -135,14 +135,14 @@ def test_all_apps_returned_on_empty_network_value(self):
     def test_apps_returned_on_filtered_network(self):
         json_response = [
             {
-                'url': 'https://example.com',
+                'url': 'https://example.com/1',
                 'name': 'test_safe_app_1',
                 'icon_url': 'https://example.com/icon',
                 'description': 'safe_app_description_1',
                 'networks': [1]
             },
             {
-                'url': 'https://example.com',
+                'url': 'https://example.com/2',
                 'name': 'test_safe_app_2',
                 'icon_url': 'https://example.com/icon',
                 'description': 'safe_app_description_2',
@@ -168,14 +168,14 @@ def test_apps_returned_on_unexisting_network(self):
     def test_apps_returned_on_same_key_pair(self):
         json_response = [
             {
-                'url': 'https://example.com',
+                'url': 'https://example.com/1',
                 'name': 'test_safe_app_1',
                 'icon_url': 'https://example.com/icon',
                 'description': 'safe_app_description_1',
                 'networks': [1]
             },
             {
-                'url': 'https://example.com',
+                'url': 'https://example.com/2',
                 'name': 'test_safe_app_2',
                 'icon_url': 'https://example.com/icon',
                 'description': 'safe_app_description_2',