Skip to content

Commit

Permalink
feat(rm): new post_remove hook
Browse files Browse the repository at this point in the history
Provides an item after it has been removed from the library.
  • Loading branch information
jtpavlock committed Sep 7, 2022
1 parent e055237 commit 659ec7c
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 13 deletions.
5 changes: 5 additions & 0 deletions docs/developers/api/hooks.core.rst
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,8 @@ Import
------
.. autoclass:: moe.plugins.moe_import.import_core.Hooks
:members:

Remove
------
.. autoclass:: moe.plugins.remove.rm_core.Hooks
:members:
2 changes: 1 addition & 1 deletion moe/plugins/remove/rm_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,4 @@ def _parse_args(config: Config, args: argparse.Namespace):
raise SystemExit(1)

for item in items:
moe_rm.remove_item(item)
moe_rm.remove_item(config, item)
25 changes: 23 additions & 2 deletions moe/plugins/remove/rm_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,38 @@

import logging

from moe.config import MoeSession
import pluggy

import moe
from moe.config import Config, MoeSession
from moe.library.lib_item import LibItem

__all__ = ["remove_item"]

log = logging.getLogger("moe.remove")


def remove_item(item: LibItem):
class Hooks:
"""Remove plugin hook specifications."""

@staticmethod
@moe.hookspec
def post_remove(config: Config, item: LibItem):
"""Provides an item after it has been removed from the library."""


@moe.hookimpl
def add_hooks(plugin_manager: pluggy.manager.PluginManager):
"""Registers `add` hookspecs to Moe."""
from moe.plugins.remove.rm_core import Hooks

plugin_manager.add_hookspecs(Hooks)


def remove_item(config: Config, item: LibItem):
"""Removes an item from the library."""
session = MoeSession()

log.info(f"Removing '{item}' from the library.")
session.delete(item)
config.plugin_manager.hook.post_remove(config=config, item=item)
8 changes: 4 additions & 4 deletions tests/plugins/remove/test_rm_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def test_track(self, mock_track, mock_query, mock_rm, tmp_rm_config):
moe.cli.main(cli_args, tmp_rm_config)

mock_query.assert_called_once_with("*", query_type="track")
mock_rm.assert_called_once_with(mock_track)
mock_rm.assert_called_once_with(tmp_rm_config, mock_track)

def test_album(self, mock_album, mock_query, mock_rm, tmp_rm_config):
"""Albums are removed from the database with valid query."""
Expand All @@ -41,7 +41,7 @@ def test_album(self, mock_album, mock_query, mock_rm, tmp_rm_config):
moe.cli.main(cli_args, tmp_rm_config)

mock_query.assert_called_once_with("*", query_type="album")
mock_rm.assert_called_once_with(mock_album)
mock_rm.assert_called_once_with(tmp_rm_config, mock_album)

def test_extra(self, mock_extra, mock_query, mock_rm, tmp_rm_config):
"""Extras are removed from the database with valid query."""
Expand All @@ -51,7 +51,7 @@ def test_extra(self, mock_extra, mock_query, mock_rm, tmp_rm_config):
moe.cli.main(cli_args, tmp_rm_config)

mock_query.assert_called_once_with("*", query_type="extra")
mock_rm.assert_called_once_with(mock_extra)
mock_rm.assert_called_once_with(tmp_rm_config, mock_extra)

def test_multiple_items(
self, mock_track_factory, mock_query, mock_rm, tmp_rm_config
Expand All @@ -64,7 +64,7 @@ def test_multiple_items(
moe.cli.main(cli_args, tmp_rm_config)

for mock_track in mock_tracks:
mock_rm.assert_any_call(mock_track)
mock_rm.assert_any_call(tmp_rm_config, mock_track)
assert mock_rm.call_count == 2

def test_exit_code(self, mock_query, mock_rm, tmp_rm_config):
Expand Down
49 changes: 43 additions & 6 deletions tests/plugins/remove/test_rm_core.py
Original file line number Diff line number Diff line change
@@ -1,47 +1,84 @@
"""Test the core api of the ``remove`` plugin."""

import pytest

import moe
from moe.config import Config, ExtraPlugin
from moe.library.album import Album
from moe.library.extra import Extra
from moe.library.lib_item import LibItem
from moe.library.track import Track
from moe.plugins import remove as moe_rm


@pytest.fixture
def tmp_rm_config(tmp_config) -> Config:
"""A temporary config for the edit plugin with the cli."""
return tmp_config('default_plugins = ["remove"]', tmp_db=True)


class RemovePlugin:
"""Test plugin that implements the remove hookspecs."""

@staticmethod
@moe.hookimpl
def post_remove(config: Config, item: LibItem):
"""Apply the new title onto the old album."""
if isinstance(item, Track):
item.title = "removed"


class TestRemoveItem:
"""Tests `remove_item()`."""

def test_track(self, mock_track, tmp_session):
def test_track(self, mock_track, tmp_session, tmp_rm_config):
"""Tracks are removed from the database with valid query."""
tmp_session.add(mock_track)
tmp_session.flush()

moe_rm.remove_item(mock_track)
moe_rm.remove_item(tmp_rm_config, mock_track)

assert not tmp_session.query(Track).scalar()

def test_album(self, mock_album, tmp_session):
def test_album(self, mock_album, tmp_session, tmp_rm_config):
"""Albums are removed from the database with valid query.
Removing an album should also remove any associated tracks and extras.
"""
mock_album = tmp_session.merge(mock_album)
tmp_session.flush()

moe_rm.remove_item(mock_album)
moe_rm.remove_item(tmp_rm_config, mock_album)

assert not tmp_session.query(Album).scalar()
assert not tmp_session.query(Track).scalar()
assert not tmp_session.query(Extra).scalar()

def test_extra(self, mock_extra, tmp_session):
def test_extra(self, mock_extra, tmp_session, tmp_rm_config):
"""Extras are removed from the database with valid query."""
tmp_session.add(mock_extra)
tmp_session.flush()

moe_rm.remove_item(mock_extra)
moe_rm.remove_item(tmp_rm_config, mock_extra)

assert not tmp_session.query(Extra).scalar()


class TestPostRemove:
"""Test the `post_remove` hookspec."""

def test_post_add(self, mock_track, tmp_config):
"""Ensure plugins can implement the `pre_add` hook."""
config = tmp_config(
"default_plugins = ['remove']",
extra_plugins=[ExtraPlugin(RemovePlugin, "remove_plugin")],
)

config.plugin_manager.hook.post_remove(config=config, item=mock_track)

assert mock_track.title == "removed"


class TestPluginRegistration:
"""Test the `plugin_registration` hook implementation."""

Expand Down

0 comments on commit 659ec7c

Please sign in to comment.