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
__all__ = (
'Stamper',
'UpdateStamper',
)
F = TypeVar('F', bound=Flavor)
class Stamper:
"""
Adds archive-related information to stories.
@ -62,3 +69,59 @@ class Stamper:
story: The story to stamp.
"""
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
import arrow
import pytest
from fimfarchive.stampers import Stamper
from fimfarchive.flavors import UpdateStatus
from fimfarchive.stampers import Stamper, UpdateStamper
class TestStamper:
@ -62,3 +65,125 @@ class TestStamper:
assert 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