2009-02-19 07:52:18 +00:00
|
|
|
# -*- coding: utf8 -*-
|
|
|
|
|
|
|
|
import csv
|
|
|
|
import types
|
|
|
|
import cherrypy
|
|
|
|
from cStringIO import StringIO
|
|
|
|
from pysqlite2 import dbapi2 as sqlite
|
|
|
|
|
|
|
|
from model.User import User
|
|
|
|
from model.Note import Note
|
|
|
|
from model.Notebook import Notebook
|
|
|
|
from controller.Database import Database, Connection_wrapper
|
|
|
|
from controller.test.Stub_cache import Stub_cache
|
|
|
|
from plugins.Invoke import invoke
|
|
|
|
|
|
|
|
|
|
|
|
class Test_export_csv( object ):
|
|
|
|
def setUp( self ):
|
|
|
|
self.database = Database(
|
|
|
|
Connection_wrapper( sqlite.connect( ":memory:", detect_types = sqlite.PARSE_DECLTYPES, check_same_thread = False ) ),
|
|
|
|
cache = Stub_cache(),
|
|
|
|
)
|
|
|
|
self.database.execute_script( file( "model/schema.sqlite" ).read(), commit = True )
|
|
|
|
|
|
|
|
self.username = u"mulder"
|
|
|
|
self.password = u"trustno1"
|
|
|
|
self.email_address = u"outthere@example.com"
|
|
|
|
self.user = User.create( self.database.next_id( User ), self.username, self.password, self.email_address )
|
|
|
|
self.database.save( self.user, commit = False )
|
|
|
|
|
|
|
|
self.trash = Notebook.create( self.database.next_id( Notebook ), u"trash" )
|
|
|
|
self.database.save( self.trash, commit = False )
|
|
|
|
self.notebook = Notebook.create( self.database.next_id( Notebook ), u"notebook", self.trash.object_id, user_id = self.user.object_id )
|
|
|
|
self.database.save( self.notebook, commit = False )
|
|
|
|
|
|
|
|
note_id = self.database.next_id( Note )
|
|
|
|
self.note1 = Note.create( note_id, u"<h3>my title</h3>blah", notebook_id = self.notebook.object_id, startup = True, user_id = self.user.object_id )
|
|
|
|
self.database.save( self.note1, commit = False )
|
|
|
|
|
|
|
|
note_id = self.database.next_id( Note )
|
|
|
|
self.note2 = Note.create( note_id, u"<h3>other title</h3>whee", notebook_id = self.notebook.object_id, user_id = self.user.object_id )
|
|
|
|
self.database.save( self.note2, commit = False )
|
|
|
|
|
2009-02-20 23:22:23 +00:00
|
|
|
def test_export_csv( self, note_contents = None, expected_contents = None ):
|
2009-02-19 07:52:18 +00:00
|
|
|
if not note_contents:
|
|
|
|
note_contents = u"<h3>blah</h3>foo"
|
|
|
|
|
|
|
|
note3 = Note.create( self.database.next_id( Note ), note_contents, notebook_id = self.notebook.object_id, user_id = self.user.object_id )
|
|
|
|
self.database.save( note3 )
|
|
|
|
response_headers = {}
|
|
|
|
expected_notes = ( self.note1, self.note2, note3 )
|
|
|
|
|
|
|
|
result = invoke(
|
|
|
|
"export",
|
|
|
|
"csv",
|
|
|
|
self.database,
|
|
|
|
self.notebook,
|
|
|
|
expected_notes,
|
|
|
|
response_headers,
|
|
|
|
)
|
|
|
|
|
|
|
|
assert response_headers
|
|
|
|
assert response_headers[ u"Content-Type" ] == u"text/csv;charset=utf-8"
|
|
|
|
assert response_headers[ u"Content-Disposition" ] == 'attachment; filename=%s.csv' % self.notebook.friendly_id
|
|
|
|
|
|
|
|
assert isinstance( result, types.GeneratorType )
|
|
|
|
pieces = []
|
|
|
|
|
|
|
|
for piece in result:
|
|
|
|
pieces.append( piece )
|
|
|
|
|
|
|
|
csv_data = "".join( pieces )
|
|
|
|
reader = csv.reader( StringIO( csv_data ) )
|
|
|
|
|
|
|
|
row = reader.next()
|
|
|
|
expected_header = [ u"contents", u"title", u"note_id", u"startup", u"username", u"revision_date" ]
|
|
|
|
assert row == expected_header
|
|
|
|
|
|
|
|
note_count = 0
|
|
|
|
|
|
|
|
# assert that startup notes come first, then normal notes in descending revision order
|
|
|
|
for row in reader:
|
|
|
|
assert len( row ) == len( expected_header )
|
|
|
|
( contents, title, note_id, startup, username, revision_date ) = row
|
|
|
|
|
|
|
|
assert note_count < len( expected_notes )
|
|
|
|
expected_note = expected_notes[ note_count ]
|
|
|
|
|
|
|
|
assert expected_note
|
2009-02-20 23:22:23 +00:00
|
|
|
if expected_contents and note_id == note3.object_id:
|
|
|
|
assert contents.decode( "utf8" ) == expected_contents.replace( "\n", " " ).strip()
|
|
|
|
else:
|
|
|
|
assert contents.decode( "utf8" ) == expected_note.contents.replace( "\n", " " ).strip()
|
2009-02-19 07:52:18 +00:00
|
|
|
|
|
|
|
if expected_note.title:
|
|
|
|
assert title.decode( "utf8" ) == expected_note.title.strip()
|
|
|
|
else:
|
|
|
|
assert not title
|
|
|
|
|
|
|
|
assert note_id.decode( "utf8" ) == expected_note.object_id
|
|
|
|
assert startup.decode( "utf8" ) == expected_note.startup and u"1" or "0"
|
|
|
|
assert username.decode( "utf8" ) == ( expected_note.user_id and self.user.username or u"" )
|
|
|
|
assert revision_date.decode( "utf8" ) == unicode( expected_note.revision )
|
|
|
|
|
|
|
|
note_count += 1
|
|
|
|
|
|
|
|
assert note_count == len( expected_notes )
|
|
|
|
|
|
|
|
def test_export_csv_with_unicode( self ):
|
|
|
|
self.test_export_csv( note_contents = u"<h3>blah</h3>ümlaut.png" )
|
|
|
|
|
|
|
|
def test_export_csv_without_note_title( self ):
|
|
|
|
self.test_export_csv( note_contents = u"there's no title" )
|
|
|
|
|
|
|
|
def test_export_csv_with_trailing_newline_in_title( self ):
|
|
|
|
self.test_export_csv( note_contents = u"<h3>blah\n</h3>foo" )
|
|
|
|
|
|
|
|
def test_export_csv_with_trailing_newline_in_contents( self ):
|
|
|
|
self.test_export_csv( note_contents = u"<h3>blah</h3>foo\n" )
|
|
|
|
|
2009-02-20 23:22:23 +00:00
|
|
|
def test_export_csv_with_file_attachment_in_contents( self ):
|
|
|
|
self.test_export_csv(
|
|
|
|
note_contents = u"<h3>blah</h3>foo<a href=\"/files/download?file_id=blah"e_filename=False\">file</a>",
|
|
|
|
expected_contents = "<h3>blah</h3>foo<a>file</a>",
|
|
|
|
)
|
|
|
|
|
|
|
|
def test_export_csv_with_image_in_contents( self ):
|
|
|
|
self.test_export_csv(
|
|
|
|
note_contents = u"<h3>blah</h3>foo<a href=\"/files/download?file_id=blah"e_filename=False\"><img src=\"whee.png\" /></a>",
|
|
|
|
expected_contents = "<h3>blah</h3>foo<a></a>",
|
|
|
|
)
|
|
|
|
|
2009-02-19 07:52:18 +00:00
|
|
|
def test_export_csv_with_blank_username( self ):
|
|
|
|
self.user._User__username = None
|
|
|
|
self.database.save( self.user )
|
|
|
|
|
|
|
|
self.test_export_csv( note_contents = u"<h3>blah</h3>foo" )
|