Add update stamper

This commit is contained in:
Joakim Soderlund 2017-11-04 16:30:41 +01:00
parent 0a862abcd0
commit 81c4346f10
2 changed files with 190 additions and 2 deletions

View file

@ -22,16 +22,23 @@ Stampers for Fimfarchive.
# #
from typing import Any, Dict from typing import Any, Dict, Optional, Set, Type, TypeVar
import arrow
from fimfarchive.flavors import Flavor, UpdateStatus
from fimfarchive.stories import Story from fimfarchive.stories import Story
__all__ = ( __all__ = (
'Stamper', 'Stamper',
'UpdateStamper',
) )
F = TypeVar('F', bound=Flavor)
class Stamper: class Stamper:
""" """
Adds archive-related information to stories. Adds archive-related information to stories.
@ -62,3 +69,59 @@ class Stamper:
story: The story to stamp. story: The story to stamp.
""" """
raise NotImplementedError() raise NotImplementedError()
class UpdateStamper(Stamper):
"""
Adds modification dates to stories.
"""
spec: Dict[str, Set[UpdateStatus]] = {
'date_created': {
UpdateStatus.CREATED,
},
'date_fetched': {
UpdateStatus.CREATED,
UpdateStatus.REVIVED,
UpdateStatus.UPDATED,
},
'date_updated': {
UpdateStatus.CREATED,
UpdateStatus.UPDATED,
},
}
def find_flavor(self, story: Story, flavor: Type[F]) -> Optional[F]:
"""
Searches for a flavor of a specific type.
Args:
story: The story to search in.
flavor: The flavor type to find.
Returns:
A flavor of the desired type, or None.
"""
for current in story.flavors:
if isinstance(current, flavor):
return current
return None
def __call__(self, story: Story) -> None:
"""
Applies modification dates to a story.
Args:
story: The story to stamp.
"""
timestamp = arrow.utcnow().isoformat()
flavor = self.find_flavor(story, UpdateStatus)
archive = self.get_archive(story)
archive['date_checked'] = timestamp
for key, value in self.spec.items():
if flavor in value:
archive[key] = timestamp
elif key not in archive:
archive[key] = None

View file

@ -22,11 +22,14 @@ Stamper tests.
# #
from unittest.mock import patch
from typing import Dict from typing import Dict
import arrow
import pytest import pytest
from fimfarchive.stampers import Stamper from fimfarchive.flavors import UpdateStatus
from fimfarchive.stampers import Stamper, UpdateStamper
class TestStamper: class TestStamper:
@ -62,3 +65,125 @@ class TestStamper:
assert archive is original assert archive is original
assert meta['archive'] is original assert meta['archive'] is original
class TestUpdateStamper:
"""
UpdateStamper tests.
"""
@pytest.fixture
def time(self):
"""
Returns a timestamp for the mocked utcnow.
"""
stamp = arrow.get(1)
with patch('arrow.utcnow') as m:
m.return_value = stamp
yield stamp.isoformat()
@pytest.fixture
def stamper(self, time):
"""
Returns an update stamper instance.
"""
return UpdateStamper()
def test_created_story(self, stamper, story, time):
"""
Tests timestamps are added for created stories.
"""
story.flavors.add(UpdateStatus.CREATED)
stamper(story)
archive = story.meta['archive']
assert archive['date_checked'] == time
assert archive['date_created'] == time
assert archive['date_fetched'] == time
assert archive['date_updated'] == time
def test_updated_story(self, stamper, story, time):
"""
Tests timestamps are added for updated stories.
"""
story.flavors.add(UpdateStatus.UPDATED)
stamper(story)
archive = story.meta['archive']
assert archive['date_checked'] == time
assert archive['date_created'] is None
assert archive['date_fetched'] == time
assert archive['date_updated'] == time
def test_revived_story(self, stamper, story, time):
"""
Tests timestamps are added for revived stories.
"""
story.flavors.add(UpdateStatus.REVIVED)
stamper(story)
archive = story.meta['archive']
assert archive['date_checked'] == time
assert archive['date_created'] is None
assert archive['date_fetched'] == time
assert archive['date_updated'] is None
def test_deleted_story(self, stamper, story, time):
"""
Tests timestamps are added for deleted stories.
"""
story.flavors.add(UpdateStatus.DELETED)
stamper(story)
archive = story.meta['archive']
assert archive['date_checked'] == time
assert archive['date_created'] is None
assert archive['date_fetched'] is None
assert archive['date_updated'] is None
def test_created_modification(self, stamper, story, time):
"""
Tests existing timestamps are replaced for created stories.
"""
story.flavors.add(UpdateStatus.CREATED)
prev = arrow.get(-1).isoformat()
story.meta['archive'] = {
'date_checked': prev,
'date_created': prev,
'date_fetched': prev,
'date_updated': prev,
}
stamper(story)
assert prev != time
archive = story.meta['archive']
assert archive['date_checked'] == time
assert archive['date_created'] == time
assert archive['date_fetched'] == time
assert archive['date_updated'] == time
def test_deleted_modification(self, stamper, story, time):
"""
Tests existing timestamps are kept for deleted stories.
"""
story.flavors.add(UpdateStatus.DELETED)
prev = arrow.get(-1).isoformat()
story.meta['archive'] = {
'date_checked': prev,
'date_created': prev,
'date_fetched': prev,
'date_updated': prev,
}
stamper(story)
assert prev != time
archive = story.meta['archive']
assert archive['date_checked'] == time
assert archive['date_created'] == prev
assert archive['date_fetched'] == prev
assert archive['date_updated'] == prev