Import and Export CSV
This commit is contained in:
38
backend/core/management/commands/export_risks.py
Normal file
38
backend/core/management/commands/export_risks.py
Normal file
@@ -0,0 +1,38 @@
|
||||
import csv
|
||||
from django.core.management.base import BaseCommand
|
||||
from backend.core.models import Risk
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = "Export risks to a CSV file"
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument('csv_file', type=str, help="The CSV file to export risks to")
|
||||
|
||||
def handle(self, *args, **options):
|
||||
csv_file_path = options['csv_file']
|
||||
|
||||
with open(csv_file_path, mode="w", newline="") as csv_file:
|
||||
fieldnames = [
|
||||
'Risk ID','Category','Risk Name', 'Primary Impact', 'Secondary Impact',
|
||||
'Tertiary Impact', 'Detection Difficulty', 'Recovery Complexity',
|
||||
'Business Impact Severity'
|
||||
|
||||
]
|
||||
writer = csv.DictWriter(csv_file, fieldnames=fieldnames)
|
||||
|
||||
writer.writeheader()
|
||||
for risk in Risk.objects.all():
|
||||
writer.writerow({
|
||||
'Risk ID': risk.risk_id,
|
||||
'Category': risk.category,
|
||||
'Risk Name': risk.risk_name,
|
||||
'Primary Impact': risk.primary_impact,
|
||||
'Secondary Impact': risk.secondary_impact,
|
||||
'Tertiary Impact': risk.tretiary_impact,
|
||||
'Detection Difficulty': risk.detection_difficulty,
|
||||
'Recovery Complexity': risk.recovery_complexity,
|
||||
'Business Impact Severity': risk.businnes_impact_severity,
|
||||
|
||||
})
|
||||
self.stdout.write(self.style.SUCCESS('Risks exported successfully'))
|
||||
32
backend/core/management/commands/import_risks.py
Normal file
32
backend/core/management/commands/import_risks.py
Normal file
@@ -0,0 +1,32 @@
|
||||
import csv
|
||||
from django.core.management.base import BaseCommand , CommandError
|
||||
from backend.core.models import Risk
|
||||
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = "Import risks from CSV file"
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument('csv_file',type=str, help="CSV file to import risks from")
|
||||
|
||||
def handle(self, *args, **options):
|
||||
csv_file_path = options['csv_file']
|
||||
|
||||
with open(csv_file_path, mode="r") as csv_file:
|
||||
reader = csv.DictReader(csv_file)
|
||||
for row in reader:
|
||||
Risk.objects.update_or_create(
|
||||
risk_id=row["Risk ID"],
|
||||
defaults = {
|
||||
'category':row['Category'],
|
||||
'risk_name': row['Risk Name'],
|
||||
'primary_impact': row['Primary Impact'],
|
||||
'secondary_impact': row['Secondary Impact'],
|
||||
'tretiary_impact':row['Tertiary Impact'],
|
||||
'detection_difficulty': row['Detection Difficulty'],
|
||||
'recovery_complexity':row['Recovery Complexity'],
|
||||
'businnes_impact_severity': row['Business Impact Severity']
|
||||
}
|
||||
)
|
||||
self.stdout.write(self.style.SUCCESS('Risks imported successfully'))
|
||||
0
backend/core/management/commands/tests/__init__.py
Normal file
0
backend/core/management/commands/tests/__init__.py
Normal file
61
backend/core/management/commands/tests/test_export_risks.py
Normal file
61
backend/core/management/commands/tests/test_export_risks.py
Normal file
@@ -0,0 +1,61 @@
|
||||
import os
|
||||
import csv
|
||||
from django.core.management import call_command
|
||||
from django.test import TestCase
|
||||
from django.conf import settings
|
||||
from backend.core.models import Risk
|
||||
|
||||
class ExportRisksCommandTest(TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.risk = Risk.objects.create(
|
||||
risk_id="1",
|
||||
category="Security",
|
||||
risk_name="Data Breach",
|
||||
primary_impact="High",
|
||||
secondary_impact="Medium",
|
||||
tretiary_impact="Low",
|
||||
detection_difficulty="High",
|
||||
recovery_complexity="Medium",
|
||||
businnes_impact_severity="High"
|
||||
)
|
||||
self.csv_file_path = os.path.join(settings.BASE_DIR, "test_risks.csv")
|
||||
|
||||
def tearDown(self):
|
||||
if os.path.exists(self.csv_file_path):
|
||||
os.remove(self.csv_file_path)
|
||||
|
||||
def test_export_risks_to_csv(self):
|
||||
call_command('export_risks', self.csv_file_path)
|
||||
|
||||
self.assertTrue(os.path.exists(self.csv_file_path))
|
||||
|
||||
with open(self.csv_file_path, mode='r') as csv_file:
|
||||
reader = csv.DictReader(csv_file)
|
||||
rows = list(reader)
|
||||
|
||||
self.assertEqual(len(rows), 1)
|
||||
|
||||
row = rows[0]
|
||||
self.assertEqual(row['Risk ID'], self.risk.risk_id)
|
||||
self.assertEqual(row['Category'], self.risk.category)
|
||||
self.assertEqual(row['Risk Name'], self.risk.risk_name)
|
||||
self.assertEqual(row['Primary Impact'], self.risk.primary_impact)
|
||||
self.assertEqual(row['Secondary Impact'], self.risk.secondary_impact)
|
||||
self.assertEqual(row['Tertiary Impact'], self.risk.tretiary_impact)
|
||||
self.assertEqual(row['Detection Difficulty'], self.risk.detection_difficulty)
|
||||
self.assertEqual(row['Recovery Complexity'], self.risk.recovery_complexity)
|
||||
self.assertEqual(row['Business Impact Severity'], self.risk.businnes_impact_severity)
|
||||
|
||||
def test_no_risks_in_db(self):
|
||||
Risk.objects.all().delete()
|
||||
|
||||
call_command('export_risks', self.csv_file_path)
|
||||
|
||||
self.assertTrue(os.path.exists(self.csv_file_path))
|
||||
|
||||
with open(self.csv_file_path, mode='r') as csv_file:
|
||||
reader = csv.DictReader(csv_file)
|
||||
rows = list(reader)
|
||||
|
||||
self.assertEqual(len(rows), 0)
|
||||
54
backend/core/management/commands/tests/test_import_risks.py
Normal file
54
backend/core/management/commands/tests/test_import_risks.py
Normal file
@@ -0,0 +1,54 @@
|
||||
import os
|
||||
import csv
|
||||
import tempfile
|
||||
from django.core.management import call_command
|
||||
from django.test import TestCase
|
||||
from backend.core.models import Risk
|
||||
|
||||
class ImportRisksCommandTest(TestCase):
|
||||
|
||||
def setUp(self):
|
||||
"""Create a temporary CSV file with test risk data"""
|
||||
self.temp_csv = tempfile.NamedTemporaryFile(mode="w", delete=False, newline='', encoding='utf-8')
|
||||
fieldnames = [
|
||||
"Risk ID", "Category", "Risk Name", "Primary Impact",
|
||||
"Secondary Impact", "Tertiary Impact", "Detection Difficulty",
|
||||
"Recovery Complexity", "Business Impact Severity"
|
||||
]
|
||||
|
||||
writer = csv.DictWriter(self.temp_csv, fieldnames=fieldnames)
|
||||
writer.writeheader()
|
||||
writer.writerow({
|
||||
"Risk ID": "1",
|
||||
"Category": "Operational",
|
||||
"Risk Name": "Data Loss",
|
||||
"Primary Impact": "High",
|
||||
"Secondary Impact": "Medium",
|
||||
"Tertiary Impact": "Low",
|
||||
"Detection Difficulty": "Hard",
|
||||
"Recovery Complexity": "Complex",
|
||||
"Business Impact Severity": "Severe"
|
||||
})
|
||||
self.temp_csv.close()
|
||||
|
||||
def test_import_risks_command(self):
|
||||
"""Test importing risks from a CSV file"""
|
||||
# Ensure no risks exist before import
|
||||
self.assertEqual(Risk.objects.count(), 0)
|
||||
|
||||
# Run the import command
|
||||
call_command('import_risks', self.temp_csv.name)
|
||||
|
||||
# Check if the risk has been imported
|
||||
self.assertEqual(Risk.objects.count(), 1)
|
||||
risk = Risk.objects.get(risk_id="1")
|
||||
self.assertEqual(risk.category, "Operational")
|
||||
self.assertEqual(risk.risk_name, "Data Loss")
|
||||
self.assertEqual(risk.primary_impact, "High")
|
||||
self.assertEqual(risk.secondary_impact, "Medium")
|
||||
self.assertEqual(risk.tretiary_impact, "Low") # Corrected spelling
|
||||
self.assertEqual(risk.businnes_impact_severity, "Severe") # Corrected spelling
|
||||
|
||||
def tearDown(self):
|
||||
"""Remove temporary CSV file after test"""
|
||||
os.remove(self.temp_csv.name)
|
||||
@@ -0,0 +1,52 @@
|
||||
# Generated by Django 5.1.3 on 2025-02-07 13:44
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('core', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Risk',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('risk_id', models.IntegerField(unique=True)),
|
||||
('category', models.CharField(max_length=255)),
|
||||
('risk_name', models.CharField(max_length=255)),
|
||||
('primary_impact', models.TextField()),
|
||||
('secondary_impact', models.TextField()),
|
||||
('tretiary_impact', models.TextField()),
|
||||
('detection_difficulty', models.CharField(max_length=255)),
|
||||
('recovery_complexity', models.CharField(max_length=255)),
|
||||
('businnes_impact_severity', models.CharField(max_length=255)),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='Document',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||
('modified_at', models.DateTimeField(auto_now=True)),
|
||||
('organization', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='documents', to='core.organization')),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='DocumentSegment',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('segment_type', models.CharField(choices=[('title', 'Title'), ('subtitle', 'Subtitle'), ('h1', 'Header 1'), ('h2', 'Header 2'), ('h3', 'Header 3'), ('body', 'Body Text'), ('quote', 'Quote')], max_length=20)),
|
||||
('content', models.TextField()),
|
||||
('order', models.PositiveIntegerField()),
|
||||
('modified_at', models.DateTimeField(auto_now=True)),
|
||||
('document', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='segments', to='core.document')),
|
||||
],
|
||||
options={
|
||||
'ordering': ['order'],
|
||||
},
|
||||
),
|
||||
]
|
||||
@@ -123,4 +123,18 @@ class Document(models.Model):
|
||||
)
|
||||
|
||||
|
||||
class Risk(models.Model):
|
||||
risk_id = models.IntegerField(unique=True)
|
||||
category = models.CharField(max_length=255)
|
||||
risk_name = models.CharField(max_length=255)
|
||||
primary_impact = models.TextField()
|
||||
secondary_impact = models.TextField()
|
||||
tretiary_impact = models.TextField()
|
||||
detection_difficulty = models.CharField(max_length=255)
|
||||
recovery_complexity = models.CharField(max_length=255)
|
||||
businnes_impact_severity = models.CharField(max_length=255)
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.risk_id} - {self.risk_name}"
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user