Skip to content

Commit 0197980

Browse files
committed
tests: Add integration tests for import/export
1 parent 5050c2c commit 0197980

File tree

1 file changed

+190
-0
lines changed

1 file changed

+190
-0
lines changed

tests/test_commands.py

Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
from datetime import datetime
2+
import json
3+
import os
4+
5+
from silicon import page
6+
from silicon.related import add as add_related
7+
from silicon.related import get as get_related
8+
9+
# TODO: 'timestamp' in the JSONS needs to be 'revision' to match our
10+
# existing model.
11+
12+
13+
def test_export_command(app, runner):
14+
"""
15+
Tests the basic functionality of the 'export' command.
16+
It creates a page, runs export, and verifies the output file.
17+
"""
18+
revision = datetime.now().isoformat()
19+
with app.app_context():
20+
page.write('export_page', 'This is the body.', revision=revision)
21+
add_related('export_page', 'related_page_a')
22+
add_related('export_page', 'related_page_b')
23+
result = runner.invoke(args=['export'])
24+
assert result.exit_code == 0, result.output
25+
26+
export_dir = os.path.join(app.instance_path, 'export')
27+
exported_file = os.path.join(export_dir, 'export_page.json')
28+
assert os.path.exists(exported_file)
29+
30+
with open(exported_file) as f:
31+
data = json.load(f)
32+
33+
assert data['title'] == 'export_page'
34+
assert len(data['revisions']) == 1
35+
assert data['revisions'][0]['body'] == 'This is the body.'
36+
assert data['revisions'][0]['revision'] == revision
37+
assert 'related_page_a' in data['attributes']['related']
38+
assert 'related_page_b' in data['attributes']['related']
39+
40+
41+
def test_import_fails_if_db_exists_without_force(app, runner):
42+
"""
43+
Tests that import command fails if the database exists
44+
and --force is not used.
45+
"""
46+
export_dir = os.path.join(app.instance_path, 'export')
47+
os.makedirs(export_dir, exist_ok=True)
48+
import_file = os.path.join(export_dir, 'dummy.json')
49+
with open(import_file, 'w') as f:
50+
json.dump({"title": "dummy", "revisions": []}, f)
51+
52+
result = runner.invoke(args=['import'])
53+
assert result.exit_code != 0
54+
55+
56+
def test_import_command(app, runner):
57+
"""
58+
Tests the basic functionality of the 'import' command.
59+
It creates a JSON file and runs import, then verifies the page was created.
60+
"""
61+
export_dir = os.path.join(app.instance_path, 'export')
62+
os.makedirs(export_dir, exist_ok=True)
63+
import_file = os.path.join(export_dir, 'import_page.json')
64+
revision = datetime.now().isoformat()
65+
66+
import_data = {
67+
'title': 'import_page',
68+
'attributes': {
69+
'related': ['related_page_a', 'related_page_b']
70+
},
71+
'revisions': [
72+
{
73+
'revision': revision,
74+
'body': 'Imported body.'
75+
}
76+
]
77+
}
78+
with open(import_file, 'w') as f:
79+
json.dump(import_data, f)
80+
81+
with app.app_context():
82+
result = runner.invoke(args=['import', '--force'])
83+
assert result.exit_code == 0, result.output
84+
imported_page = page.read('import_page')
85+
related = get_related('import_page')
86+
87+
assert imported_page['title'] == 'import_page'
88+
assert imported_page['body'] == 'Imported body.'
89+
assert imported_page['revision'] == revision
90+
assert 'related_page_a' in related
91+
assert 'related_page_b' in related
92+
93+
94+
def test_round_trip(app, runner):
95+
"""
96+
Tests that exporting and then importing a page preserves its content,
97+
especially with tricky characters.
98+
"""
99+
title = 'tricky_content_page'
100+
body = """
101+
Here's some "tricky" content.
102+
'Single quotes' are here.
103+
<Tags> and [brackets] and {braces}.
104+
Unicode: \u2603 SNOWMAN
105+
106+
Leading and trailing whitespace.
107+
108+
"""
109+
revision = datetime.now().isoformat()
110+
111+
with app.app_context():
112+
page.write(title, body, revision=revision)
113+
original_page = page.read(title)
114+
result = runner.invoke(args=['export'])
115+
assert result.exit_code == 0, result.output
116+
117+
os.remove(os.path.join(app.instance_path, 'silicon.sqlite'))
118+
119+
with app.app_context():
120+
result = runner.invoke(args=['import'])
121+
assert result.exit_code == 0, result.output
122+
round_tripped_page = page.read(title)
123+
124+
assert round_tripped_page['title'] == original_page['title']
125+
assert round_tripped_page['body'] == original_page['body']
126+
assert round_tripped_page['revision'] == original_page['revision']
127+
128+
129+
def test_import_upsert(app, runner):
130+
"""
131+
Tests that importing a page with two identical revision strings works, and
132+
uses the most recent body version presented. (This tests the upsert
133+
functionality in page.py.)
134+
"""
135+
export_dir = os.path.join(app.instance_path, 'export')
136+
os.makedirs(export_dir, exist_ok=True)
137+
import_file = os.path.join(export_dir, 'import_page.json')
138+
revision = datetime.now().isoformat()
139+
140+
import_data = {
141+
'title': 'import_page',
142+
'revisions': [
143+
{
144+
'revision': revision,
145+
'body': 'First imported body.'
146+
},
147+
{
148+
'revision': revision,
149+
'body': 'Second imported body.'
150+
}
151+
]
152+
}
153+
with open(import_file, 'w') as f:
154+
json.dump(import_data, f)
155+
156+
with app.app_context():
157+
result = runner.invoke(args=['import', '--force'])
158+
assert result.exit_code == 0, result.output
159+
imported_page = page.read('import_page')
160+
161+
assert imported_page['title'] == 'import_page'
162+
assert imported_page['body'] == 'Second imported body.'
163+
assert imported_page['revision'] == revision
164+
165+
166+
def test_export_fails_if_no_db(app, runner):
167+
"""Tests that export command fails if the database does not exist."""
168+
db_path = os.path.join(app.instance_path, 'silicon.sqlite')
169+
if os.path.exists(db_path):
170+
os.remove(db_path)
171+
172+
result = runner.invoke(args=['export'])
173+
assert result.exit_code != 0
174+
175+
176+
def test_import_with_malformed_json(app, runner):
177+
"""Tests that import command handles malformed JSON files gracefully."""
178+
export_dir = os.path.join(app.instance_path, 'export')
179+
os.makedirs(export_dir, exist_ok=True)
180+
import_file = os.path.join(export_dir, 'malformed.json')
181+
182+
with open(import_file, 'w') as f:
183+
f.write('{"title": "malformed", "revisions": [') # Incomplete JSON
184+
185+
db_path = os.path.join(app.instance_path, 'silicon.sqlite')
186+
if os.path.exists(db_path):
187+
os.remove(db_path)
188+
189+
result = runner.invoke(args=['import'])
190+
assert result.exit_code != 0

0 commit comments

Comments
 (0)