hydrus/include/TestClientAPI.py

559 lines
18 KiB
Python
Raw Normal View History

2019-02-13 22:26:43 +00:00
from . import ClientConstants as CC
from . import ClientAPI
from . import ClientLocalServer
from . import ClientServices
from . import ClientTags
import http.client
from . import HydrusConstants as HC
from . import HydrusText
import json
import os
import time
import unittest
import urllib
from twisted.internet import reactor
from . import HydrusData
from . import HydrusGlobals as HG
class TestClientAPI( unittest.TestCase ):
@classmethod
def setUpClass( cls ):
cls._client_api = ClientServices.GenerateService( CC.CLIENT_API_SERVICE_KEY, HC.CLIENT_API_SERVICE, 'client api' )
def TWISTEDSetup():
reactor.listenTCP( 45869, ClientLocalServer.HydrusServiceClientAPI( cls._client_api, allow_non_local_connections = False ) )
reactor.callFromThread( TWISTEDSetup )
time.sleep( 1 )
def _test_basics( self, connection ):
#
connection.request( 'GET', '/' )
response = connection.getresponse()
data = response.read()
self.assertEqual( response.status, 200 )
#
with open( os.path.join( HC.STATIC_DIR, 'hydrus.ico' ), 'rb' ) as f:
favicon = f.read()
connection.request( 'GET', '/favicon.ico' )
response = connection.getresponse()
data = response.read()
self.assertEqual( data, favicon )
def _test_client_api_basics( self, connection ):
# /api_version
connection.request( 'GET', '/api_version' )
response = connection.getresponse()
data = response.read()
text = str( data, 'utf-8' )
response_json = json.loads( text )
self.assertEqual( response_json[ 'version' ], HC.CLIENT_API_VERSION )
# /request_new_permissions
def format_request_new_permissions_query( name, basic_permissions ):
return '/request_new_permissions?name={}&basic_permissions={}'.format( urllib.parse.quote( name ), urllib.parse.quote( json.dumps( basic_permissions ) ) )
# fail
ClientAPI.api_request_dialog_open = False
connection.request( 'GET', format_request_new_permissions_query( 'test', [ ClientAPI.CLIENT_API_PERMISSION_ADD_FILES ] ) )
response = connection.getresponse()
data = response.read()
text = str( data, 'utf-8' )
self.assertIn( 'dialog', text )
self.assertEqual( response.status, 403 )
# success
permissions_to_set_up = []
permissions_to_set_up.append( ( 'everything', list( ClientAPI.ALLOWED_PERMISSIONS ) ) )
permissions_to_set_up.append( ( 'add_files', [ ClientAPI.CLIENT_API_PERMISSION_ADD_FILES ] ) )
permissions_to_set_up.append( ( 'add_tags', [ ClientAPI.CLIENT_API_PERMISSION_ADD_TAGS ] ) )
permissions_to_set_up.append( ( 'add_urls', [ ClientAPI.CLIENT_API_PERMISSION_ADD_URLS ] ) )
permissions_to_set_up.append( ( 'search_all_files', [ ClientAPI.CLIENT_API_PERMISSION_SEARCH_FILES ] ) )
permissions_to_set_up.append( ( 'search_green_files', [ ClientAPI.CLIENT_API_PERMISSION_SEARCH_FILES ] ) )
set_up_permissions = {}
for ( name, basic_permissions ) in permissions_to_set_up:
ClientAPI.api_request_dialog_open = True
connection.request( 'GET', format_request_new_permissions_query( name, basic_permissions ) )
response = connection.getresponse()
data = response.read()
ClientAPI.api_request_dialog_open = False
self.assertEqual( response.status, 200 )
response_text = str( data, 'utf-8' )
response_json = json.loads( response_text )
access_key_hex = response_json[ 'access_key' ]
self.assertEqual( len( access_key_hex ), 64 )
access_key_hex = HydrusText.HexFilter( access_key_hex )
self.assertEqual( len( access_key_hex ), 64 )
api_permissions = ClientAPI.last_api_permissions_request
if 'green' in name:
search_tag_filter = ClientTags.TagFilter()
search_tag_filter.SetRule( '', CC.FILTER_BLACKLIST )
search_tag_filter.SetRule( ':', CC.FILTER_BLACKLIST )
search_tag_filter.SetRule( 'green', CC.FILTER_WHITELIST )
api_permissions.SetSearchTagFilter( search_tag_filter )
self.assertEqual( bytes.fromhex( access_key_hex ), api_permissions.GetAccessKey() )
set_up_permissions[ name ] = api_permissions
HG.test_controller.client_api_manager.AddAccess( api_permissions )
# /verify_access_key
# missing
connection.request( 'GET', '/verify_access_key' )
response = connection.getresponse()
data = response.read()
self.assertEqual( response.status, 401 )
# fail
incorrect_headers = { 'Hydrus-Client-API-Access-Key' : 'abcd' }
connection.request( 'GET', '/verify_access_key', headers = incorrect_headers )
response = connection.getresponse()
data = response.read()
self.assertEqual( response.status, 403 )
# success
for ( name, api_permissions ) in set_up_permissions.items():
access_key_hex = api_permissions.GetAccessKey().hex()
headers = { 'Hydrus-Client-API-Access-Key' : access_key_hex }
connection.request( 'GET', '/verify_access_key', headers = headers )
response = connection.getresponse()
data = response.read()
text = str( data, 'utf-8' )
body_dict = json.loads( text )
self.assertEqual( response.status, 200 )
self.assertEqual( set( body_dict[ 'basic_permissions' ] ), set( api_permissions.GetBasicPermissions() ) )
self.assertEqual( body_dict[ 'human_description' ], api_permissions.ToHumanString() )
return set_up_permissions
def _test_add_files( self, connection, set_up_permissions ):
api_permissions = set_up_permissions[ 'add_files' ]
access_key_hex = api_permissions.GetAccessKey().hex()
# fail
HG.test_controller.SetRead( 'hash_status', ( CC.STATUS_UNKNOWN, None, '' ) )
headers = { 'Hydrus-Client-API-Access-Key' : access_key_hex, 'Content-Type' : HC.mime_string_lookup[ HC.APPLICATION_OCTET_STREAM ] }
path = '/add_files/add_file'
body = b'blarg'
connection.request( 'POST', path, body = body, headers = headers )
response = connection.getresponse()
data = response.read()
text = str( data, 'utf-8' )
self.assertEqual( response.status, 200 )
response_json = json.loads( text )
self.assertEqual( response_json[ 'status' ], CC.STATUS_ERROR )
self.assertEqual( response_json[ 'hash' ], 'a593942cb7ea9ffcd8ccf2f0fa23c338e23bfecd9a3e508dfc0bcf07501ead08' )
self.assertIn( 'Traceback', response_json[ 'note' ] )
# success as body
hydrus_png_path = os.path.join( HC.STATIC_DIR, 'hydrus.png' )
with open( hydrus_png_path, 'rb' ) as f:
HYDRUS_PNG_BYTES = f.read()
headers = { 'Hydrus-Client-API-Access-Key' : access_key_hex, 'Content-Type' : HC.mime_string_lookup[ HC.APPLICATION_OCTET_STREAM ] }
path = '/add_files/add_file'
body = HYDRUS_PNG_BYTES
connection.request( 'POST', path, body = body, headers = headers )
response = connection.getresponse()
data = response.read()
text = str( data, 'utf-8' )
self.assertEqual( response.status, 200 )
response_json = json.loads( text )
expected_result = { 'status' : CC.STATUS_SUCCESSFUL_AND_NEW, 'hash' : 'ad6d3599a6c489a575eb19c026face97a9cd6579e74728b0ce94a601d232f3c3' , 'note' : 'test note' }
self.assertEqual( response_json, expected_result )
# do hydrus png as path
headers = { 'Hydrus-Client-API-Access-Key' : access_key_hex, 'Content-Type' : HC.mime_string_lookup[ HC.APPLICATION_JSON ] }
path = '/add_files/add_file'
body_dict = { 'path' : hydrus_png_path }
body = json.dumps( body_dict )
connection.request( 'POST', path, body = body, headers = headers )
response = connection.getresponse()
data = response.read()
text = str( data, 'utf-8' )
self.assertEqual( response.status, 200 )
response_json = json.loads( text )
expected_result = { 'status' : CC.STATUS_SUCCESSFUL_AND_NEW, 'hash' : 'ad6d3599a6c489a575eb19c026face97a9cd6579e74728b0ce94a601d232f3c3' , 'note' : 'test note' }
self.assertEqual( response_json, expected_result )
def _test_add_tags( self, connection, set_up_permissions ):
# get services
api_permissions = set_up_permissions[ 'everything' ]
access_key_hex = api_permissions.GetAccessKey().hex()
headers = { 'Hydrus-Client-API-Access-Key' : access_key_hex }
# none
path = '/add_tags/get_tag_services'
connection.request( 'GET', path, headers = headers )
response = connection.getresponse()
data = response.read()
text = str( data, 'utf-8' )
self.assertEqual( response.status, 200 )
d = json.loads( text )
expected_answer = {}
expected_answer[ 'local_tags' ] = [ "local tags" ]
expected_answer[ 'tag_repositories' ] = [ "example tag repo" ]
self.assertEqual( d, expected_answer )
def _test_add_urls( self, connection, set_up_permissions ):
# get url files
api_permissions = set_up_permissions[ 'everything' ]
access_key_hex = api_permissions.GetAccessKey().hex()
headers = { 'Hydrus-Client-API-Access-Key' : access_key_hex }
# none
url = 'https://muhsite.wew/help_compute'
HG.test_controller.SetRead( 'url_statuses', [] )
path = '/add_urls/get_url_files?url={}'.format( urllib.parse.quote( url, safe = '' ) )
connection.request( 'GET', path, headers = headers )
response = connection.getresponse()
data = response.read()
text = str( data, 'utf-8' )
self.assertEqual( response.status, 200 )
d = json.loads( text )
expected_answer = {}
expected_answer[ 'normalised_url' ] = url
expected_answer[ 'url_file_statuses' ] = []
self.assertEqual( d, expected_answer )
# some
url = 'http://safebooru.org/index.php?page=post&s=view&id=2753608'
normalised_url = 'https://safebooru.org/index.php?id=2753608&page=post&s=view'
hash = os.urandom( 32 )
url_file_statuses = [ ( CC.STATUS_SUCCESSFUL_BUT_REDUNDANT, hash, 'muh import phrase' ) ]
json_url_file_statuses = [ { 'status' : CC.STATUS_SUCCESSFUL_BUT_REDUNDANT, 'hash' : hash.hex(), 'note' : 'muh import phrase' } ]
HG.test_controller.SetRead( 'url_statuses', url_file_statuses )
path = '/add_urls/get_url_files?url={}'.format( urllib.parse.quote( url, safe = '' ) )
connection.request( 'GET', path, headers = headers )
response = connection.getresponse()
data = response.read()
text = str( data, 'utf-8' )
self.assertEqual( response.status, 200 )
d = json.loads( text )
expected_answer = {}
expected_answer[ 'normalised_url' ] = normalised_url
expected_answer[ 'url_file_statuses' ] = json_url_file_statuses
self.assertEqual( d, expected_answer )
# get url info
api_permissions = set_up_permissions[ 'everything' ]
access_key_hex = api_permissions.GetAccessKey().hex()
headers = { 'Hydrus-Client-API-Access-Key' : access_key_hex }
# unknown
url = 'https://muhsite.wew/help_compute'
path = '/add_urls/get_url_info?url={}'.format( urllib.parse.quote( url, safe = '' ) )
connection.request( 'GET', path, headers = headers )
response = connection.getresponse()
data = response.read()
text = str( data, 'utf-8' )
self.assertEqual( response.status, 200 )
d = json.loads( text )
expected_answer = {}
expected_answer[ 'normalised_url' ] = url
expected_answer[ 'url_type' ] = HC.URL_TYPE_UNKNOWN
expected_answer[ 'url_type_string' ] = 'unknown url'
expected_answer[ 'match_name' ] = 'unknown url'
expected_answer[ 'can_parse' ] = False
self.assertEqual( d, expected_answer )
# known
url = 'http://8ch.net/tv/res/1846574.html'
normalised_url = 'https://8ch.net/tv/res/1846574.html'
# http so we can test normalised is https
path = '/add_urls/get_url_info?url={}'.format( urllib.parse.quote( url, safe = '' ) )
connection.request( 'GET', path, headers = headers )
response = connection.getresponse()
data = response.read()
text = str( data, 'utf-8' )
self.assertEqual( response.status, 200 )
d = json.loads( text )
expected_answer = {}
expected_answer = { 'url_type' : HC.URL_TYPE_WATCHABLE, 'url_type_string' : 'watchable url', 'match_name' : '8chan thread', 'can_parse' : True }
expected_answer[ 'normalised_url' ] = normalised_url
expected_answer[ 'url_type' ] = HC.URL_TYPE_WATCHABLE
expected_answer[ 'url_type_string' ] = 'watchable url'
expected_answer[ 'match_name' ] = '8chan thread'
expected_answer[ 'can_parse' ] = True
self.assertEqual( d, expected_answer )
# known post url
url = 'http://safebooru.org/index.php?page=post&s=view&id=2753608'
normalised_url = 'https://safebooru.org/index.php?id=2753608&page=post&s=view'
hash = os.urandom( 32 )
path = '/add_urls/get_url_info?url={}'.format( urllib.parse.quote( url, safe = '' ) )
connection.request( 'GET', path, headers = headers )
response = connection.getresponse()
data = response.read()
text = str( data, 'utf-8' )
self.assertEqual( response.status, 200 )
d = json.loads( text )
expected_answer = {}
expected_answer[ 'normalised_url' ] = normalised_url
expected_answer[ 'url_type' ] = HC.URL_TYPE_POST
expected_answer[ 'url_type_string' ] = 'post url'
expected_answer[ 'match_name' ] = 'safebooru file page'
expected_answer[ 'can_parse' ] = True
self.assertEqual( d, expected_answer )
# add url
headers = { 'Hydrus-Client-API-Access-Key' : access_key_hex, 'Content-Type' : HC.mime_string_lookup[ HC.APPLICATION_JSON ] }
request_dict = { 'url' : 'http://8ch.net/tv/res/1846574.html' }
request_body = json.dumps( request_dict )
connection.request( 'POST', '/add_urls/add_url', body = request_body, headers = headers )
response = connection.getresponse()
self.assertEqual( response.status, 200 )
data = response.read()
text = str( data, 'utf-8' )
response_json = json.loads( text )
self.assertEqual( response_json[ 'human_result_text' ], '"https://8ch.net/tv/res/1846574.html" URL added successfully.' )
self.assertEqual( response_json[ 'normalised_url' ], 'https://8ch.net/tv/res/1846574.html' )
def _test_search_files( self, connection, set_up_permissions ):
pass
# search files
def _test_permission_failures( self, connection, set_up_permissions ):
pass
# failed permission tests
def test_client_api( self ):
host = '127.0.0.1'
port = 45869
connection = http.client.HTTPConnection( host, port, timeout = 10 )
self._test_basics( connection )
set_up_permissions = self._test_client_api_basics( connection )
self._test_add_files( connection, set_up_permissions )
self._test_add_tags( connection, set_up_permissions )
self._test_add_urls( connection, set_up_permissions )
self._test_search_files( connection, set_up_permissions )
self._test_permission_failures( connection, set_up_permissions )