Test the storage
================

Imports
    >>> from ftw.publisher.sender.persistence import Job
    >>> from datetime import datetime

Create some stuff for testing
    >>> self.folder.invokeFactory('Folder', 'foo', title='Foo')
    'foo'
    >>> foo = self.folder.get('foo')
    >>> foo
    <ATFolder at /plone/Members/test_user_1_/foo>

    >>> from ftw.publisher.sender.interfaces import IQueue
    >>> queue = IQueue(self.portal)

Queue is empty by default
    >>> queue.countJobs()
    0

    >>> queue.get_executed_jobs_length()
    0

We should be able to get it:
    >>> tuple(queue.get_executed_jobs())
    ()

Add a job for the folder
    >>> queue.createJob('push', foo, 'user')
    <ftw.publisher.sender.persistence.Job object at ...>
    >>> queue.countJobs()
    1
    >>> queue.getJobs()
    [<ftw.publisher.sender.persistence.Job object at ...>]

Act as we just published the job
    >>> job = queue.popJob()
    >>> job
    <ftw.publisher.sender.persistence.Job object at ...>
    >>> key = queue.append_executed_job(job)
    >>> key
    1
    >>> queue.countJobs()
    0
    >>> queue.get_executed_jobs_length()
    1
    >>> list(queue.get_executed_jobs())
    [(1, <ftw.publisher.sender.persistence.Job object at ...>)]
    >>> queue.remove_executed_job(key)
    <ftw.publisher.sender.persistence.Job object at ...>
    >>> list(queue.get_executed_jobs())
    []

Let's add some more objects to the executed jobs list and try to
get them in a batch. The key is generated with auto-increment, so
we start at key "2" now since we already had a "1" earlier in this
test.
    >>> for i in range(10):
    ...     key = queue.append_executed_job('obj %i' % i)
    >>> queue.get_executed_jobs_length()
    10
    >>> list(queue.get_executed_jobs(start=0, end=2))
    [(2, 'obj 0'), (3, 'obj 1')]
    >>> list(queue.get_executed_jobs(start=4, end=5))
    [(6, 'obj 4')]

And we should be able to get a specific job by key.
    >>> queue.get_executed_job_by_key(6)
    'obj 4'
    >>> queue.get_executed_job_by_key(1000)
    Traceback (most recent call last):
    ...
    KeyError: 1000

Cleanup the storage:
    >>> for key, obj in tuple(queue.get_executed_jobs()):
    ...     obj = queue.remove_executed_job(key)
    >>> queue.get_executed_jobs_length()
    0

Add some Job objects with dates for testing date stuff.
    >>> for day in range(1, 20):
    ...     job = Job('push', foo, 'user')
    ...     date = datetime(year=2000, month=1, day=day, hour=12)
    ...     job.executed_with_states({'date':date,})
    ...     key = queue.append_executed_job(job)
    >>> queue.get_executed_jobs_length()
    19

Lets remove all old jobs (including the one from 2010-02-10)
    >>> tenth = datetime(year=2000, month=1, day=10, hour=23)
    >>> queue.remove_executed_jobs_older_than(tenth)
    >>> queue.get_executed_jobs_length()
    9

Test the `remove_jobs_by_filter` method:
    >>> entry_to_delete = tuple(queue.get_executed_jobs())[2]
    >>> queue.remove_jobs_by_filter(lambda *params: params == entry_to_delete)
    >>> queue.get_executed_jobs_length()
    8
    >>> entry_to_delete not in tuple(queue.get_executed_jobs())
    True

Then remove all jobs:
    >>> queue.clear_executed_jobs()
    >>> tuple(queue.get_executed_jobs())
    ()

If we have a empty storage and we calculate some batching we may get
the jobs like this:
    >>> tuple(queue.get_executed_jobs(0, 0))
    ()

It also should return a empty tuple when we make illogical query:
    >>> tuple(queue.get_executed_jobs(10, 2))
    ()
