wrolpi/modules/videos/video/test/test_api.py
Roland 03a2df217d
Zim/Kiwix (Wikipedia) feature
* A new zim module has been added, this module allows several things to interact with Zim files.
  * Allow searching of Zim files using libzim.
  * Allow downloading of Kiwix projects (wikipedia, wikibooks, etc) on a schedule which replaces the outdated files.
  * Creation of a new zim docker container which allows viewing of the Zim file contents.

* This commit also adds move/rename/mkdir features in the File Browser.
  * File tags are preserved when moving/renaming.
2023-07-10 21:30:40 -06:00

165 lines
7.2 KiB
Python

import json
from datetime import timedelta
from http import HTTPStatus
from json import dumps
import pytest
from modules.videos.models import Video
from modules.videos.video.lib import get_video_for_app
from wrolpi.dates import now
from wrolpi.errors import API_ERRORS, WROLModeEnabled
def test_get_video_prev_next(test_session, channel_factory, video_factory):
"""
Test that the previous and next videos will be retrieved when fetching a video.
"""
channel1, channel2, channel3, channel4 = channel_factory(), channel_factory(), channel_factory(), channel_factory()
now_ = now()
second = timedelta(seconds=1)
# The upload_date decides the order of the prev/next videos.
video_factory(title='vid1', channel_id=channel1.id, upload_date=now_)
video_factory(title='vid2', channel_id=channel1.id, upload_date=now_ + second)
video_factory(title='vid3', channel_id=channel2.id, upload_date=now_ + (second * 4))
video_factory(title='vid4', channel_id=channel1.id, upload_date=now_ + (second * 3))
video_factory(title='vid5', channel_id=channel2.id, upload_date=now_ + (second * 2))
video_factory(title='vid6', channel_id=channel2.id, upload_date=now_ + (second * 5))
video_factory(title='vid7', channel_id=channel1.id)
video_factory(title='vid8', channel_id=channel2.id, upload_date=now_ + (second * 7))
video_factory(title='vid9', channel_id=channel3.id, upload_date=now_ + (second * 8))
# Videos without an upload date can't be placed.
video_factory(title='vid10', channel_id=channel4.id)
video_factory(title='vid11', channel_id=channel4.id)
test_session.commit()
tests = [
# Channel 1's videos were inserted in upload_date order.
(1, (None, 'vid2')),
(2, ('vid1', 'vid4')),
(4, ('vid2', None)), # 7 has no upload_date, so it doesn't come after 4.
(7, (None, None)), # 7 has no upload_date, so we don't know the order of it.
# Channel 3 has only one video.
(9, (None, None)),
# Channel 2 was inserted out of order.
(5, (None, 'vid3')),
(3, ('vid5', 'vid6')),
(8, ('vid6', None)),
# Channel 4's videos have no upload date, so we don't know what is previous/next.
(10, (None, None)),
]
for id_, (prev_title, next_title) in tests:
video = test_session.query(Video).filter_by(id=id_).one()
prev_video, next_video = video.get_surrounding_videos()
try:
if prev_title is None:
assert prev_video is None
else:
assert prev_video and prev_video.file_group.title == prev_title
if next_title is None:
assert next_video is None
else:
assert next_video and next_video.file_group.title == next_title
except AssertionError as e:
raise AssertionError(f'Assert failed for {id_=} {prev_title=} {next_title=}') from e
def test_get_video_for_app(test_session, simple_channel, simple_video):
vid, prev, next_ = get_video_for_app(simple_video.id)
assert vid['id'] == simple_video.id
@pytest.mark.asyncio
def test_video_delete(test_client, test_session, test_directory, channel_factory, video_factory):
"""Video.delete() removes the video's files, but leave the DB record."""
channel1, channel2 = channel_factory(), channel_factory()
vid1 = video_factory(channel_id=channel1.id, with_video_file=True, with_caption_file=True)
vid2 = video_factory(channel_id=channel2.id, with_video_file=True, with_info_json=True)
test_session.commit()
assert test_session.query(Video).count() == 2
vid1_video_path, vid1_caption_path = vid1.video_path, vid1.caption_paths[0]
vid2_video_path, vid2_info_json_path = vid2.video_path, vid2.info_json_path
# No videos have been deleted yet.
assert vid1_video_path.is_file() and vid1_caption_path.is_file()
assert vid2_video_path.is_file() and vid2_info_json_path.is_file()
assert channel1.skip_download_videos is None
assert channel2.skip_download_videos is None
request, response = test_client.delete(f'/api/videos/video/{vid1.id}')
assert response.status_code == HTTPStatus.NO_CONTENT
# Video was added to skip list.
assert len(channel1.skip_download_videos) == 1
# Video was deleted.
assert test_session.query(Video).count() == 1
assert vid1_video_path.is_file() is False and vid1_caption_path.is_file() is False
assert vid2_video_path.is_file() and vid2_info_json_path.is_file()
request, response = test_client.delete(f'/api/videos/video/{vid2.id}')
assert response.status_code == HTTPStatus.NO_CONTENT
assert test_session.query(Video).count() == 0
assert vid1_video_path.is_file() is False and vid1_caption_path.is_file() is False
assert vid2_video_path.is_file() is False and vid2_info_json_path.is_file() is False
# 3 does not exist.
request, response = test_client.delete(f'/api/videos/video/3')
assert response.status_code == HTTPStatus.NOT_FOUND
# Can't parse the ids.
request, response = test_client.delete(f'/api/videos/video/3,')
assert response.status_code == HTTPStatus.BAD_REQUEST
@pytest.mark.asyncio
async def test_wrol_mode(test_async_client, test_directory, simple_channel, simple_video, wrol_mode_fixture,
test_download_manager,
tag_factory):
"""Many methods are blocked when WROL Mode is enabled."""
channel = dumps(dict(name=simple_channel.name, directory=str(simple_channel.directory)))
tag = tag_factory()
wrol_mode_fixture(True)
# Can't create, update, or delete a channel.
_, resp = await test_async_client.post('/api/videos/channels', content=channel)
assert resp.status_code == HTTPStatus.FORBIDDEN
assert resp.json['code'] == API_ERRORS[WROLModeEnabled]['code']
_, resp = await test_async_client.put(f'/api/videos/channels/{simple_channel.id}', content=channel)
assert resp.status_code == HTTPStatus.FORBIDDEN
assert resp.json['code'] == API_ERRORS[WROLModeEnabled]['code']
_, resp = await test_async_client.delete(f'/api/videos/channels/{simple_channel.id}')
assert resp.status_code == HTTPStatus.FORBIDDEN
assert resp.json['code'] == API_ERRORS[WROLModeEnabled]['code']
# Can't delete a video
_, resp = await test_async_client.delete(f'/api/videos/video/{simple_video.id}')
assert resp.status_code == HTTPStatus.FORBIDDEN
assert resp.json['code'] == API_ERRORS[WROLModeEnabled]['code']
# Can't refresh or download
_, resp = await test_async_client.post('/api/files/refresh')
assert resp.status_code == HTTPStatus.FORBIDDEN
assert resp.json['code'] == API_ERRORS[WROLModeEnabled]['code']
_, resp = await test_async_client.post(f'/api/videos/channels/download/{simple_channel.id}')
assert resp.status_code == HTTPStatus.FORBIDDEN
assert resp.json['code'] == API_ERRORS[WROLModeEnabled]['code']
# THE REST OF THESE METHODS ARE ALLOWED
content = dict(video_id=simple_video.id, tag_name=tag.name)
_, resp = await test_async_client.post('/api/videos/tag', content=json.dumps(content))
assert resp.status_code == HTTPStatus.NO_CONTENT
assert test_download_manager.stopped.is_set()
wrol_mode_fixture(False)
assert not test_download_manager.stopped.is_set()