##// END OF EJS Templates
Added a generator for the 'get' request for sync
neko259 -
r810:6bdf5d6a decentral
parent child Browse files
Show More
@@ -0,0 +1,56 b''
1 import xml.etree.ElementTree as et
2
3 TAG_MODEL = 'model'
4 TAG_REQUEST = 'request'
5 TAG_ID = 'id'
6
7 TYPE_GET = 'get'
8
9 ATTR_VERSION = 'version'
10 ATTR_TYPE = 'type'
11 ATTR_NAME = 'name'
12 ATTR_KEY = 'key'
13 ATTR_KEY_TYPE = 'type'
14 ATTR_LOCAL_ID = 'local-id'
15
16
17 class ModelId:
18 """
19 Model ID describes a global ID that consists of sender's key (with the key
20 type) and local ID on the sender node.
21 """
22
23 def __init__(self, key, key_type, local_id):
24 self.key = key
25 self.key_type = key_type
26 self.local_id = local_id
27
28
29 def respond_pull(request):
30 pass
31
32
33 def respond_get(request):
34 pass
35
36
37 def generate_request_get(id_list: list):
38 """
39 Form a get request from a list of ModelId objects.
40 """
41
42 request = et.Element(TAG_REQUEST)
43 request.set(ATTR_TYPE, TYPE_GET)
44 request.set(ATTR_VERSION, '1.0')
45
46 model = et.SubElement(request, TAG_MODEL)
47 model.set(ATTR_VERSION, '1.0')
48 model.set(ATTR_NAME, 'post')
49
50 for model_id in id_list:
51 tag_id = et.SubElement(model, TAG_ID)
52 tag_id.set(ATTR_KEY, model_id.key)
53 tag_id.set(ATTR_KEY_TYPE, model_id.key_type)
54 tag_id.set(ATTR_LOCAL_ID, model_id.local_id)
55
56 return et.tostring(request, 'unicode') No newline at end of file
@@ -1,338 +1,347 b''
1 # coding=utf-8
1 # coding=utf-8
2 import time
2 import time
3 import logging
3 import logging
4 import simplejson
4 import simplejson
5 from django.core.paginator import Paginator
5 from django.core.paginator import Paginator
6
6
7 from django.test import TestCase
7 from django.test import TestCase
8 from django.test.client import Client
8 from django.test.client import Client
9 from django.core.urlresolvers import reverse, NoReverseMatch
9 from django.core.urlresolvers import reverse, NoReverseMatch
10 from boards.abstracts.settingsmanager import get_settings_manager
10 from boards.abstracts.settingsmanager import get_settings_manager
11
11
12 from boards.models import Post, Tag, Thread, KeyPair
12 from boards.models import Post, Tag, Thread, KeyPair
13 from boards import urls
13 from boards import urls
14 from boards import settings
14 from boards import settings
15 from boards.views.api import api_get_threaddiff
15 from boards.views.api import api_get_threaddiff
16 from boards.utils import datetime_to_epoch
16 from boards.utils import datetime_to_epoch
17 from boards.views.sync import ModelId, generate_request_get
17 import neboard
18 import neboard
18
19
19 TEST_TAG = 'test_tag'
20 TEST_TAG = 'test_tag'
20
21
21 PAGE_404 = 'boards/404.html'
22 PAGE_404 = 'boards/404.html'
22
23
23 TEST_TEXT = 'test text'
24 TEST_TEXT = 'test text'
24
25
25 NEW_THREAD_PAGE = '/'
26 NEW_THREAD_PAGE = '/'
26 THREAD_PAGE_ONE = '/thread/1/'
27 THREAD_PAGE_ONE = '/thread/1/'
27 THREAD_PAGE = '/thread/'
28 THREAD_PAGE = '/thread/'
28 TAG_PAGE = '/tag/'
29 TAG_PAGE = '/tag/'
29 HTTP_CODE_REDIRECT = 302
30 HTTP_CODE_REDIRECT = 302
30 HTTP_CODE_OK = 200
31 HTTP_CODE_OK = 200
31 HTTP_CODE_NOT_FOUND = 404
32 HTTP_CODE_NOT_FOUND = 404
32
33
33 logger = logging.getLogger(__name__)
34 logger = logging.getLogger(__name__)
34
35
35
36
36 class PostTests(TestCase):
37 class PostTests(TestCase):
37
38
38 def _create_post(self):
39 def _create_post(self):
39 tag = Tag.objects.create(name=TEST_TAG)
40 tag = Tag.objects.create(name=TEST_TAG)
40 return Post.objects.create_post(title='title', text='text',
41 return Post.objects.create_post(title='title', text='text',
41 tags=[tag])
42 tags=[tag])
42
43
43 def test_post_add(self):
44 def test_post_add(self):
44 """Test adding post"""
45 """Test adding post"""
45
46
46 post = self._create_post()
47 post = self._create_post()
47
48
48 self.assertIsNotNone(post, 'No post was created.')
49 self.assertIsNotNone(post, 'No post was created.')
49 self.assertEqual(TEST_TAG, post.get_thread().tags.all()[0].name,
50 self.assertEqual(TEST_TAG, post.get_thread().tags.all()[0].name,
50 'No tags were added to the post.')
51 'No tags were added to the post.')
51
52
52 def test_delete_post(self):
53 def test_delete_post(self):
53 """Test post deletion"""
54 """Test post deletion"""
54
55
55 post = self._create_post()
56 post = self._create_post()
56 post_id = post.id
57 post_id = post.id
57
58
58 Post.objects.delete_post(post)
59 Post.objects.delete_post(post)
59
60
60 self.assertFalse(Post.objects.filter(id=post_id).exists())
61 self.assertFalse(Post.objects.filter(id=post_id).exists())
61
62
62 def test_delete_thread(self):
63 def test_delete_thread(self):
63 """Test thread deletion"""
64 """Test thread deletion"""
64
65
65 opening_post = self._create_post()
66 opening_post = self._create_post()
66 thread = opening_post.get_thread()
67 thread = opening_post.get_thread()
67 reply = Post.objects.create_post("", "", thread=thread)
68 reply = Post.objects.create_post("", "", thread=thread)
68
69
69 thread.delete()
70 thread.delete()
70
71
71 self.assertFalse(Post.objects.filter(id=reply.id).exists())
72 self.assertFalse(Post.objects.filter(id=reply.id).exists())
72
73
73 def test_post_to_thread(self):
74 def test_post_to_thread(self):
74 """Test adding post to a thread"""
75 """Test adding post to a thread"""
75
76
76 op = self._create_post()
77 op = self._create_post()
77 post = Post.objects.create_post("", "", thread=op.get_thread())
78 post = Post.objects.create_post("", "", thread=op.get_thread())
78
79
79 self.assertIsNotNone(post, 'Reply to thread wasn\'t created')
80 self.assertIsNotNone(post, 'Reply to thread wasn\'t created')
80 self.assertEqual(op.get_thread().last_edit_time, post.pub_time,
81 self.assertEqual(op.get_thread().last_edit_time, post.pub_time,
81 'Post\'s create time doesn\'t match thread last edit'
82 'Post\'s create time doesn\'t match thread last edit'
82 ' time')
83 ' time')
83
84
84 def test_delete_posts_by_ip(self):
85 def test_delete_posts_by_ip(self):
85 """Test deleting posts with the given ip"""
86 """Test deleting posts with the given ip"""
86
87
87 post = self._create_post()
88 post = self._create_post()
88 post_id = post.id
89 post_id = post.id
89
90
90 Post.objects.delete_posts_by_ip('0.0.0.0')
91 Post.objects.delete_posts_by_ip('0.0.0.0')
91
92
92 self.assertFalse(Post.objects.filter(id=post_id).exists())
93 self.assertFalse(Post.objects.filter(id=post_id).exists())
93
94
94 def test_get_thread(self):
95 def test_get_thread(self):
95 """Test getting all posts of a thread"""
96 """Test getting all posts of a thread"""
96
97
97 opening_post = self._create_post()
98 opening_post = self._create_post()
98
99
99 for i in range(0, 2):
100 for i in range(0, 2):
100 Post.objects.create_post('title', 'text',
101 Post.objects.create_post('title', 'text',
101 thread=opening_post.get_thread())
102 thread=opening_post.get_thread())
102
103
103 thread = opening_post.get_thread()
104 thread = opening_post.get_thread()
104
105
105 self.assertEqual(3, thread.replies.count())
106 self.assertEqual(3, thread.replies.count())
106
107
107 def test_create_post_with_tag(self):
108 def test_create_post_with_tag(self):
108 """Test adding tag to post"""
109 """Test adding tag to post"""
109
110
110 tag = Tag.objects.create(name='test_tag')
111 tag = Tag.objects.create(name='test_tag')
111 post = Post.objects.create_post(title='title', text='text', tags=[tag])
112 post = Post.objects.create_post(title='title', text='text', tags=[tag])
112
113
113 thread = post.get_thread()
114 thread = post.get_thread()
114 self.assertIsNotNone(post, 'Post not created')
115 self.assertIsNotNone(post, 'Post not created')
115 self.assertTrue(tag in thread.tags.all(), 'Tag not added to thread')
116 self.assertTrue(tag in thread.tags.all(), 'Tag not added to thread')
116 self.assertTrue(thread in tag.threads.all(), 'Thread not added to tag')
117 self.assertTrue(thread in tag.threads.all(), 'Thread not added to tag')
117
118
118 def test_thread_max_count(self):
119 def test_thread_max_count(self):
119 """Test deletion of old posts when the max thread count is reached"""
120 """Test deletion of old posts when the max thread count is reached"""
120
121
121 for i in range(settings.MAX_THREAD_COUNT + 1):
122 for i in range(settings.MAX_THREAD_COUNT + 1):
122 self._create_post()
123 self._create_post()
123
124
124 self.assertEqual(settings.MAX_THREAD_COUNT,
125 self.assertEqual(settings.MAX_THREAD_COUNT,
125 len(Thread.objects.filter(archived=False)))
126 len(Thread.objects.filter(archived=False)))
126
127
127 def test_pages(self):
128 def test_pages(self):
128 """Test that the thread list is properly split into pages"""
129 """Test that the thread list is properly split into pages"""
129
130
130 for i in range(settings.MAX_THREAD_COUNT):
131 for i in range(settings.MAX_THREAD_COUNT):
131 self._create_post()
132 self._create_post()
132
133
133 all_threads = Thread.objects.filter(archived=False)
134 all_threads = Thread.objects.filter(archived=False)
134
135
135 paginator = Paginator(Thread.objects.filter(archived=False),
136 paginator = Paginator(Thread.objects.filter(archived=False),
136 settings.THREADS_PER_PAGE)
137 settings.THREADS_PER_PAGE)
137 posts_in_second_page = paginator.page(2).object_list
138 posts_in_second_page = paginator.page(2).object_list
138 first_post = posts_in_second_page[0]
139 first_post = posts_in_second_page[0]
139
140
140 self.assertEqual(all_threads[settings.THREADS_PER_PAGE].id,
141 self.assertEqual(all_threads[settings.THREADS_PER_PAGE].id,
141 first_post.id)
142 first_post.id)
142
143
143
144
144 class PagesTest(TestCase):
145 class PagesTest(TestCase):
145
146
146 def test_404(self):
147 def test_404(self):
147 """Test receiving error 404 when opening a non-existent page"""
148 """Test receiving error 404 when opening a non-existent page"""
148
149
149 tag_name = u'test_tag'
150 tag_name = 'test_tag'
150 tag = Tag.objects.create(name=tag_name)
151 tag = Tag.objects.create(name=tag_name)
151 client = Client()
152 client = Client()
152
153
153 Post.objects.create_post('title', TEST_TEXT, tags=[tag])
154 Post.objects.create_post('title', TEST_TEXT, tags=[tag])
154
155
155 existing_post_id = Post.objects.all()[0].id
156 existing_post_id = Post.objects.all()[0].id
156 response_existing = client.get(THREAD_PAGE + str(existing_post_id) +
157 response_existing = client.get(THREAD_PAGE + str(existing_post_id) +
157 '/')
158 '/')
158 self.assertEqual(HTTP_CODE_OK, response_existing.status_code,
159 self.assertEqual(HTTP_CODE_OK, response_existing.status_code,
159 u'Cannot open existing thread')
160 'Cannot open existing thread')
160
161
161 response_not_existing = client.get(THREAD_PAGE + str(
162 response_not_existing = client.get(THREAD_PAGE + str(
162 existing_post_id + 1) + '/')
163 existing_post_id + 1) + '/')
163 self.assertEqual(PAGE_404, response_not_existing.templates[0].name,
164 self.assertEqual(PAGE_404, response_not_existing.templates[0].name,
164 u'Not existing thread is opened')
165 'Not existing thread is opened')
165
166
166 response_existing = client.get(TAG_PAGE + tag_name + '/')
167 response_existing = client.get(TAG_PAGE + tag_name + '/')
167 self.assertEqual(HTTP_CODE_OK,
168 self.assertEqual(HTTP_CODE_OK,
168 response_existing.status_code,
169 response_existing.status_code,
169 u'Cannot open existing tag')
170 'Cannot open existing tag')
170
171
171 response_not_existing = client.get(TAG_PAGE + u'not_tag' + '/')
172 response_not_existing = client.get(TAG_PAGE + 'not_tag' + '/')
172 self.assertEqual(PAGE_404,
173 self.assertEqual(PAGE_404,
173 response_not_existing.templates[0].name,
174 response_not_existing.templates[0].name,
174 u'Not existing tag is opened')
175 'Not existing tag is opened')
175
176
176 reply_id = Post.objects.create_post('', TEST_TEXT,
177 reply_id = Post.objects.create_post('', TEST_TEXT,
177 thread=Post.objects.all()[0]
178 thread=Post.objects.all()[0]
178 .get_thread())
179 .get_thread())
179 response_not_existing = client.get(THREAD_PAGE + str(
180 response_not_existing = client.get(THREAD_PAGE + str(
180 reply_id) + '/')
181 reply_id) + '/')
181 self.assertEqual(PAGE_404,
182 self.assertEqual(PAGE_404,
182 response_not_existing.templates[0].name,
183 response_not_existing.templates[0].name,
183 u'Reply is opened as a thread')
184 'Reply is opened as a thread')
184
185
185
186
186 class FormTest(TestCase):
187 class FormTest(TestCase):
187 def test_post_validation(self):
188 def test_post_validation(self):
188 client = Client()
189 client = Client()
189
190
190 valid_tags = u'tag1 tag_2 тег_3'
191 valid_tags = 'tag1 tag_2 тег_3'
191 invalid_tags = u'$%_356 ---'
192 invalid_tags = '$%_356 ---'
192
193
193 response = client.post(NEW_THREAD_PAGE, {'title': 'test title',
194 response = client.post(NEW_THREAD_PAGE, {'title': 'test title',
194 'text': TEST_TEXT,
195 'text': TEST_TEXT,
195 'tags': valid_tags})
196 'tags': valid_tags})
196 self.assertEqual(response.status_code, HTTP_CODE_REDIRECT,
197 self.assertEqual(response.status_code, HTTP_CODE_REDIRECT,
197 msg='Posting new message failed: got code ' +
198 msg='Posting new message failed: got code ' +
198 str(response.status_code))
199 str(response.status_code))
199
200
200 self.assertEqual(1, Post.objects.count(),
201 self.assertEqual(1, Post.objects.count(),
201 msg='No posts were created')
202 msg='No posts were created')
202
203
203 client.post(NEW_THREAD_PAGE, {'text': TEST_TEXT,
204 client.post(NEW_THREAD_PAGE, {'text': TEST_TEXT,
204 'tags': invalid_tags})
205 'tags': invalid_tags})
205 self.assertEqual(1, Post.objects.count(), msg='The validation passed '
206 self.assertEqual(1, Post.objects.count(), msg='The validation passed '
206 'where it should fail')
207 'where it should fail')
207
208
208 # Change posting delay so we don't have to wait for 30 seconds or more
209 # Change posting delay so we don't have to wait for 30 seconds or more
209 old_posting_delay = neboard.settings.POSTING_DELAY
210 old_posting_delay = neboard.settings.POSTING_DELAY
210 # Wait for the posting delay or we won't be able to post
211 # Wait for the posting delay or we won't be able to post
211 neboard.settings.POSTING_DELAY = 1
212 neboard.settings.POSTING_DELAY = 1
212 time.sleep(neboard.settings.POSTING_DELAY + 1)
213 time.sleep(neboard.settings.POSTING_DELAY + 1)
213 response = client.post(THREAD_PAGE_ONE, {'text': TEST_TEXT,
214 response = client.post(THREAD_PAGE_ONE, {'text': TEST_TEXT,
214 'tags': valid_tags})
215 'tags': valid_tags})
215 self.assertEqual(HTTP_CODE_REDIRECT, response.status_code,
216 self.assertEqual(HTTP_CODE_REDIRECT, response.status_code,
216 msg=u'Posting new message failed: got code ' +
217 msg='Posting new message failed: got code ' +
217 str(response.status_code))
218 str(response.status_code))
218 # Restore posting delay
219 # Restore posting delay
219 neboard.settings.POSTING_DELAY = old_posting_delay
220 neboard.settings.POSTING_DELAY = old_posting_delay
220
221
221 self.assertEqual(2, Post.objects.count(),
222 self.assertEqual(2, Post.objects.count(),
222 msg=u'No posts were created')
223 msg='No posts were created')
223
224
224
225
225 class ViewTest(TestCase):
226 class ViewTest(TestCase):
226
227
227 def test_all_views(self):
228 def test_all_views(self):
228 """
229 """
229 Try opening all views defined in ulrs.py that don't need additional
230 Try opening all views defined in ulrs.py that don't need additional
230 parameters
231 parameters
231 """
232 """
232
233
233 client = Client()
234 client = Client()
234 for url in urls.urlpatterns:
235 for url in urls.urlpatterns:
235 try:
236 try:
236 view_name = url.name
237 view_name = url.name
237 logger.debug('Testing view %s' % view_name)
238 logger.debug('Testing view %s' % view_name)
238
239
239 try:
240 try:
240 response = client.get(reverse(view_name))
241 response = client.get(reverse(view_name))
241
242
242 self.assertEqual(HTTP_CODE_OK, response.status_code,
243 self.assertEqual(HTTP_CODE_OK, response.status_code,
243 '%s view not opened' % view_name)
244 '%s view not opened' % view_name)
244 except NoReverseMatch:
245 except NoReverseMatch:
245 # This view just needs additional arguments
246 # This view just needs additional arguments
246 pass
247 pass
247 except Exception as e:
248 except Exception as e:
248 self.fail('Got exception %s at %s view' % (e, view_name))
249 self.fail('Got exception %s at %s view' % (e, view_name))
249 except AttributeError:
250 except AttributeError:
250 # This is normal, some views do not have names
251 # This is normal, some views do not have names
251 pass
252 pass
252
253
253
254
254 class AbstractTest(TestCase):
255 class AbstractTest(TestCase):
255 def test_settings_manager(self):
256 def test_settings_manager(self):
256 request = MockRequest()
257 request = MockRequest()
257 settings_manager = get_settings_manager(request)
258 settings_manager = get_settings_manager(request)
258
259
259 settings_manager.set_setting('test_setting', 'test_value')
260 settings_manager.set_setting('test_setting', 'test_value')
260 self.assertEqual('test_value', settings_manager.get_setting(
261 self.assertEqual('test_value', settings_manager.get_setting(
261 'test_setting'), u'Setting update failed.')
262 'test_setting'), 'Setting update failed.')
262
263
263
264
264 class MockRequest:
265 class MockRequest:
265 def __init__(self):
266 def __init__(self):
266 self.session = dict()
267 self.session = dict()
267 self.GET = dict()
268 self.GET = dict()
268 self.POST = dict()
269 self.POST = dict()
269
270
270
271
271 class KeyTest(TestCase):
272 class KeyTest(TestCase):
272 def test_create_key(self):
273 def test_create_key(self):
273 key = KeyPair.objects.generate_key('ecdsa')
274 key = KeyPair.objects.generate_key('ecdsa')
274
275
275 self.assertIsNotNone(key, 'The key was not created.')
276 self.assertIsNotNone(key, 'The key was not created.')
276
277
277 def test_validation(self):
278 def test_validation(self):
278 key = KeyPair.objects.generate_key(key_type='ecdsa')
279 key = KeyPair.objects.generate_key(key_type='ecdsa')
279 message = 'msg'
280 message = 'msg'
280 signature = key.sign(message)
281 signature = key.sign(message)
281 valid = KeyPair.objects.verify(key.public_key, message, signature,
282 valid = KeyPair.objects.verify(key.public_key, message, signature,
282 key_type='ecdsa')
283 key_type='ecdsa')
283
284
284 self.assertTrue(valid, 'Message verification failed.')
285 self.assertTrue(valid, 'Message verification failed.')
285
286
286 def test_primary_constraint(self):
287 def test_primary_constraint(self):
287 KeyPair.objects.generate_key(key_type='ecdsa', primary=True)
288 KeyPair.objects.generate_key(key_type='ecdsa', primary=True)
288
289
289 try:
290 try:
290 KeyPair.objects.generate_key(key_type='ecdsa', primary=True)
291 KeyPair.objects.generate_key(key_type='ecdsa', primary=True)
291 self.fail('Exception should be thrown indicating there can be only'
292 self.fail('Exception should be thrown indicating there can be only'
292 ' one primary key.')
293 ' one primary key.')
293 except Exception:
294 except Exception:
294 pass
295 pass
295
296
297 def test_request_get(self):
298 model_id = ModelId('111', '222', '333')
299 self.assertTrue('<request type="get" version="1.0"><model '
300 'name="post" version="1.0"><id key="111" '
301 'local-id="333" type="222" /></model></request>' in
302 generate_request_get([model_id]),
303 'Wrong XML generated for the GET request.')
304
296
305
297 class ApiTest(TestCase):
306 class ApiTest(TestCase):
298 def test_thread_diff(self):
307 def test_thread_diff(self):
299 tag = Tag.objects.create(name=TEST_TAG)
308 tag = Tag.objects.create(name=TEST_TAG)
300 opening_post = Post.objects.create_post(title='title', text='text',
309 opening_post = Post.objects.create_post(title='title', text='text',
301 tags=[tag])
310 tags=[tag])
302
311
303 last_edit_time = datetime_to_epoch(opening_post.last_edit_time)
312 last_edit_time = datetime_to_epoch(opening_post.last_edit_time)
304
313
305 # Check the exact timestamp post was added
314 # Check the exact timestamp post was added
306 empty_response = api_get_threaddiff(MockRequest(),
315 empty_response = api_get_threaddiff(MockRequest(),
307 str(opening_post.thread_new.id),
316 str(opening_post.thread_new.id),
308 str(last_edit_time))
317 str(last_edit_time))
309 diff = simplejson.loads(empty_response.content)
318 diff = simplejson.loads(empty_response.content)
310 self.assertEqual(0, len(diff['added']),
319 self.assertEqual(0, len(diff['added']),
311 'There must be no added posts in the diff.')
320 'There must be no added posts in the diff.')
312 self.assertEqual(0, len(diff['updated']),
321 self.assertEqual(0, len(diff['updated']),
313 'There must be no updated posts in the diff.')
322 'There must be no updated posts in the diff.')
314
323
315 reply = Post.objects.create_post(title='',
324 reply = Post.objects.create_post(title='',
316 text='[post]%d[/post]\ntext' % opening_post.id,
325 text='[post]%d[/post]\ntext' % opening_post.id,
317 thread=opening_post.thread_new)
326 thread=opening_post.thread_new)
318
327
319 # Check the timestamp before post was added
328 # Check the timestamp before post was added
320 response = api_get_threaddiff(MockRequest(),
329 response = api_get_threaddiff(MockRequest(),
321 str(opening_post.thread_new.id),
330 str(opening_post.thread_new.id),
322 str(last_edit_time))
331 str(last_edit_time))
323 diff = simplejson.loads(response.content)
332 diff = simplejson.loads(response.content)
324 self.assertEqual(1, len(diff['added']),
333 self.assertEqual(1, len(diff['added']),
325 'There must be 1 added posts in the diff.')
334 'There must be 1 added posts in the diff.')
326 self.assertEqual(1, len(diff['updated']),
335 self.assertEqual(1, len(diff['updated']),
327 'There must be 1 updated posts in the diff.')
336 'There must be 1 updated posts in the diff.')
328
337
329 empty_response = api_get_threaddiff(MockRequest(),
338 empty_response = api_get_threaddiff(MockRequest(),
330 str(opening_post.thread_new.id),
339 str(opening_post.thread_new.id),
331 str(datetime_to_epoch(
340 str(datetime_to_epoch(
332 reply.last_edit_time)))
341 reply.last_edit_time)))
333 diff = simplejson.loads(empty_response.content)
342 diff = simplejson.loads(empty_response.content)
334 self.assertEqual(0, len(diff['added']),
343 self.assertEqual(0, len(diff['added']),
335 'There must be no added posts in the diff.')
344 'There must be no added posts in the diff.')
336 self.assertEqual(0, len(diff['updated']),
345 self.assertEqual(0, len(diff['updated']),
337 'There must be no updated posts in the diff.')
346 'There must be no updated posts in the diff.')
338
347
@@ -1,7 +1,7 b''
1 <?xml version="1.1" encoding="UTF-8" ?>
1 <?xml version="1.1" encoding="UTF-8" ?>
2 <request version="1.0" type="get">
2 <request version="1.0" type="get">
3 <model version="1.0" name="post">
3 <model version="1.0" name="post">
4 <id key="id1" local-id="1" />
4 <id key="id1" type="ecdsa" local-id="1" />
5 <id key="id1" local-id="2" />
5 <id key="id1" type="ecdsa" local-id="2" />
6 </model>
6 </model>
7 </request>
7 </request>
@@ -1,10 +1,10 b''
1 <?xml version="1.1" encoding="UTF-8" ?>
1 <?xml version="1.1" encoding="UTF-8" ?>
2 <response>
2 <response>
3 <status>success</status>
3 <status>success</status>
4 <models>
4 <models>
5 <id key="id1" local-id="1" />
5 <id key="id1" type="ecdsa" local-id="1" />
6 <id key="id1" local-id="2" />
6 <id key="id1" type="ecdsa" local-id="2" />
7 <id key="id2" local-id="1" />
7 <id key="id2" type="ecdsa" local-id="1" />
8 <id key="id2" local-id="5" />
8 <id key="id2" type="ecdsa" local-id="5" />
9 </models>
9 </models>
10 </response>
10 </response>
@@ -1,8 +1,9 b''
1 simplejson
1 south>=0.8.4
2 south>=0.8.4
2 haystack
3 haystack
3 pillow
4 pillow
4 django>=1.6
5 django>=1.6
5 django_cleanup
6 django_cleanup
6 django-markupfield
7 django-markupfield
7 bbcode
8 bbcode
8 ecdsa
9 ecdsa
General Comments 0
You need to be logged in to leave comments. Login now