# Path: fimfarchive/tasks/build.py
# class BuildTask:
#     def __init__(
#             self,
#             output: PathArg,
#             upcoming: Iterable[Story],
#             previous: Fetcher = None,
#             extras: PathArg = None,
#             ) -> None:
#     def get_output(self, directory: PathArg) -> Path:
#     def get_extras(
#             self,
#             directory: Optional[PathArg]
#             ) -> Iterator[Tuple[str, bytes]]:
#     def revive(self, story: Story) -> Story:
#     def resolve(self, story: Story) -> Story:
#     def generate(self) -> Iterator[Story]:
#     def run(self):
# 
# Path: fimfarchive/utils.py
# AUTHOR_BLACKLIST: Set[int] = {
#     33094,
#     135140,
#     242007,
# }
# 
# Path: tests/tasks/conftest.py
# class DummyConverer(Converter):
#     """
#     Converter that increments a counter.
#     """
# 
#     def __call__(self, story: Story) -> Story:
#         meta = deepcopy(story.meta)
#         meta['conversions'] += 1
# 
#         return story.merge(meta=meta)
# 
# class DummyFetcher(Fetcher):
#     """
#     Fetcher with local instance storage.
#     """
# 
#     def __init__(self):
#         """
#         Constructor.
#         """
#         self.stories: Dict[int, Story] = dict()
# 
#     def add(self, key, date, flavors=(), data=Empty):
#         """
#         Adds a story to the fetcher.
#         """
#         meta = {
#             'id': key,
#             'title': f't{key}',
#             'date_modified': date,
#             'conversions': 0,
#             'author': {
#                 'id': key,
#                 'name': f'n{key}'
#             },
#             'chapters': [
#                 {'id': key},
#             ],
#         }
# 
#         if data is Empty:
#             text = f'd{key}'
#             data = text.encode()
# 
#         story = Story(
#             key=key,
#             fetcher=self,
#             meta=meta,
#             data=data,
#             flavors=flavors,
#         )
# 
#         self.stories[key] = story
# 
#         return story
# 
#     def fetch(self, key, prefetch_meta=None, prefetch_data=None):
#         """
#         Returns a previously stored story.
#         """
#         try:
#             return self.stories[key]
#         except KeyError:
#             raise InvalidStoryError()
# 
#     def fetch_data(self, key):
#         """
#         Raises exception for missing data.
#         """
#         raise InvalidStoryError()
# 
#     def fetch_meta(self, key):
#         """
#         Raises exception for missing meta.
#         """
#         raise InvalidStoryError()
# 
#     def __iter__(self):
#         """
#         Yields all previously stored stories.
#         """
#         for key in sorted(self.stories.keys()):
#             yield self.stories[key]


from pathlib import Path
from unittest.mock import call, patch, MagicMock
from fimfarchive.tasks import build, BuildTask
from fimfarchive.utils import AUTHOR_BLACKLIST
from .conftest import DummyConverer, DummyFetcher
import arrow
import pytest
            ('alpaca.txt', b"Alpacas are floofy!"),
            ('pegasus.bin', b"\xF1u\xffy ponies!"),
        ]

    @pytest.fixture
    def extras_path(self, tmp_path, extras_data):
        """
        Returns the extras path.
        """
        extras = tmp_path / 'extras'
        extras.mkdir()

        for name, data in extras_data:
            path = extras / name
            path.write_bytes(data)

        return Path(extras)

    @pytest.fixture
    def task(self, output, upcoming, previous, extras_path):
        """
        Returns a `BuildTask` instance.
        """
        task = BuildTask(
            output=output,
            upcoming=upcoming,
            previous=previous,
            extras=extras_path,
        )


# Path: fimfarchive/tasks/build.py
# class BuildTask:
#     def __init__(
#             self,
#             output: PathArg,
#             upcoming: Iterable[Story],
#             previous: Fetcher = None,
#             extras: PathArg = None,
#             ) -> None:
#     def get_output(self, directory: PathArg) -> Path:
#     def get_extras(
#             self,
#             directory: Optional[PathArg]
#             ) -> Iterator[Tuple[str, bytes]]:
#     def revive(self, story: Story) -> Story:
#     def resolve(self, story: Story) -> Story:
#     def generate(self) -> Iterator[Story]:
#     def run(self):
# 
# Path: fimfarchive/utils.py
# AUTHOR_BLACKLIST: Set[int] = {
#     33094,
#     135140,
#     242007,
# }
# 
# Path: tests/tasks/conftest.py
# class DummyConverer(Converter):
#     """
#     Converter that increments a counter.
#     """
# 
#     def __call__(self, story: Story) -> Story:
#         meta = deepcopy(story.meta)
#         meta['conversions'] += 1
# 
#         return story.merge(meta=meta)
# 
# class DummyFetcher(Fetcher):
#     """
#     Fetcher with local instance storage.
#     """
# 
#     def __init__(self):
#         """
#         Constructor.
#         """
#         self.stories: Dict[int, Story] = dict()
# 
#     def add(self, key, date, flavors=(), data=Empty):
#         """
#         Adds a story to the fetcher.
#         """
#         meta = {
#             'id': key,
#             'title': f't{key}',
#             'date_modified': date,
#             'conversions': 0,
#             'author': {
#                 'id': key,
#                 'name': f'n{key}'
#             },
#             'chapters': [
#                 {'id': key},
#             ],
#         }
# 
#         if data is Empty:
#             text = f'd{key}'
#             data = text.encode()
# 
#         story = Story(
#             key=key,
#             fetcher=self,
#             meta=meta,
#             data=data,
#             flavors=flavors,
#         )
# 
#         self.stories[key] = story
# 
#         return story
# 
#     def fetch(self, key, prefetch_meta=None, prefetch_data=None):
#         """
#         Returns a previously stored story.
#         """
#         try:
#             return self.stories[key]
#         except KeyError:
#             raise InvalidStoryError()
# 
#     def fetch_data(self, key):
#         """
#         Raises exception for missing data.
#         """
#         raise InvalidStoryError()
# 
#     def fetch_meta(self, key):
#         """
#         Raises exception for missing meta.
#         """
#         raise InvalidStoryError()
# 
#     def __iter__(self):
#         """
#         Yields all previously stored stories.
#         """
#         for key in sorted(self.stories.keys()):
#             yield self.stories[key]


# Path: tests/tasks/test_build.py
from pathlib import Path
from unittest.mock import call, patch, MagicMock
from fimfarchive.tasks import build, BuildTask
from fimfarchive.utils import AUTHOR_BLACKLIST
from .conftest import DummyConverer, DummyFetcher
import arrow
import pytest

            ('alpaca.txt', b"Alpacas are floofy!"),
            ('pegasus.bin', b"\xF1u\xffy ponies!"),
        ]

    @pytest.fixture
    def extras_path(self, tmp_path, extras_data):
        """
        Returns the extras path.
        """
        extras = tmp_path / 'extras'
        extras.mkdir()

        for name, data in extras_data:
            path = extras / name
            path.write_bytes(data)

        return Path(extras)

    @pytest.fixture
    def task(self, output, upcoming, previous, extras_path):
        """
        Returns a `BuildTask` instance.
        """
        task = BuildTask(
            output=output,
            upcoming=upcoming,
            previous=previous,
            extras=extras_path,
        )


        with patch.object(task, 'convert', DummyConverer()):