Expose GET/POST /api/v1/export/ for server dumps and add import UI for relations (CSV/JSON) plus remote backup controls. Co-authored-by: Cursor <cursoragent@cursor.com>
95 lines
3.2 KiB
Python
95 lines
3.2 KiB
Python
import pytest
|
|
|
|
from contacts.models import Contact, NetworkMap, NetworkMapMembership, NetworkMapType, Relation
|
|
|
|
|
|
@pytest.mark.django_db
|
|
def test_export_dump_empty(api_client):
|
|
response = api_client.get('/api/v1/export/')
|
|
assert response.status_code == 200
|
|
data = response.json()
|
|
assert data['version'] == 2
|
|
assert data['contacts'] == []
|
|
assert data['relations'] == []
|
|
assert isinstance(data['networkMapTypes'], list)
|
|
assert isinstance(data['networkMaps'], list)
|
|
assert isinstance(data['networkMapMemberships'], list)
|
|
|
|
|
|
@pytest.mark.django_db
|
|
def test_export_dump_with_data(api_client, two_contacts, sample_relation):
|
|
response = api_client.get('/api/v1/export/')
|
|
assert response.status_code == 200
|
|
data = response.json()
|
|
assert len(data['contacts']) == 2
|
|
assert len(data['relations']) == 1
|
|
assert data['relations'][0]['source'] == sample_relation.source_id
|
|
assert data['relations'][0]['target'] == sample_relation.target_id
|
|
|
|
|
|
@pytest.mark.django_db
|
|
def test_import_dump_replace(api_client, two_contacts, sample_relation):
|
|
export_response = api_client.get('/api/v1/export/')
|
|
dump = export_response.json()
|
|
assert len(dump['contacts']) == 2
|
|
|
|
Contact.objects.all().delete()
|
|
assert Contact.objects.count() == 0
|
|
|
|
import_response = api_client.post('/api/v1/export/?replace=true', dump, format='json')
|
|
assert import_response.status_code == 200
|
|
result = import_response.json()
|
|
assert result['importedContacts'] == 2
|
|
assert result['importedRelations'] == 1
|
|
assert Contact.objects.count() == 2
|
|
assert Relation.objects.count() == 1
|
|
|
|
|
|
@pytest.mark.django_db
|
|
def test_import_dump_invalid(api_client):
|
|
response = api_client.post('/api/v1/export/', {'contacts': []}, format='json')
|
|
assert response.status_code == 400
|
|
assert 'error' in response.json()
|
|
|
|
|
|
@pytest.mark.django_db
|
|
def test_import_dump_with_maps(api_client, db):
|
|
NetworkMapMembership.objects.all().delete()
|
|
NetworkMap.objects.all().delete()
|
|
NetworkMapType.objects.all().delete()
|
|
|
|
map_type = NetworkMapType.objects.create(
|
|
name='Базовый',
|
|
sectors=[{'id': 'work', 'label': 'Работа'}],
|
|
circles=[{'id': 'close', 'label': 'Близкий'}],
|
|
is_default=True,
|
|
)
|
|
contact = Contact.objects.create(name='Алиса')
|
|
network_map = NetworkMap.objects.create(
|
|
name='Основная',
|
|
description='Тест',
|
|
map_type=map_type,
|
|
)
|
|
network_map.memberships.create(
|
|
contact=contact,
|
|
life_sphere='work',
|
|
network_circle='close',
|
|
importance=4,
|
|
)
|
|
|
|
dump = api_client.get('/api/v1/export/').json()
|
|
assert len(dump['contacts']) == 1
|
|
assert len(dump['networkMaps']) == 1
|
|
assert len(dump['networkMapMemberships']) == 1
|
|
|
|
Contact.objects.all().delete()
|
|
NetworkMap.objects.all().delete()
|
|
NetworkMapType.objects.all().delete()
|
|
|
|
result = api_client.post('/api/v1/export/?replace=true', dump, format='json').json()
|
|
assert result['importedContacts'] == 1
|
|
assert result['importedMaps'] == 1
|
|
assert result['importedMemberships'] == 1
|
|
assert NetworkMapType.objects.count() == 1
|
|
assert NetworkMap.objects.count() == 1
|