diff --git a/pytest.ini b/pytest.ini index e8cef8405..5dd87179e 100644 --- a/pytest.ini +++ b/pytest.ini @@ -1,5 +1,3 @@ [pytest] norecursedirs = docs node_modules .tox DJANGO_SETTINGS_MODULE = swh.web.settings.tests - - diff --git a/swh/web/browse/utils.py b/swh/web/browse/utils.py index 97a61146d..d7b9e761a 100644 --- a/swh/web/browse/utils.py +++ b/swh/web/browse/utils.py @@ -1,1160 +1,1160 @@ # Copyright (C) 2017-2018 The Software Heritage developers # See the AUTHORS file at the top-level directory of this distribution # License: GNU Affero General Public License version 3, or any later version # See top-level LICENSE file for more information import base64 from collections import defaultdict import magic import math import pypandoc import stat from django.core.cache import cache from django.utils.safestring import mark_safe from importlib import reload from swh.model.identifiers import persistent_identifier from swh.web.common import highlightjs, service from swh.web.common.exc import NotFoundExc, http_status_code_message from swh.web.common.utils import ( reverse, format_utc_iso_date, parse_timestamp, get_origin_visits, get_swh_persistent_id ) from swh.web.config import get_config def get_directory_entries(sha1_git): """Function that retrieves the content of a SWH directory from the SWH archive. The directories entries are first sorted in lexicographical order. Sub-directories and regular files are then extracted. Args: sha1_git: sha1_git identifier of the directory Returns: A tuple whose first member corresponds to the sub-directories list and second member the regular files list Raises: NotFoundExc if the directory is not found """ cache_entry_id = 'directory_entries_%s' % sha1_git cache_entry = cache.get(cache_entry_id) if cache_entry: return cache_entry entries = list(service.lookup_directory(sha1_git)) for e in entries: e['perms'] = stat.filemode(e['perms']) if e['type'] == 'rev': # modify dir entry name to explicitely show it points # to a revision e['name'] = '%s @ %s' % (e['name'], e['target'][:7]) dirs = [e for e in entries if e['type'] in ('dir', 'rev')] files = [e for e in entries if e['type'] == 'file'] dirs = sorted(dirs, key=lambda d: d['name']) files = sorted(files, key=lambda f: f['name']) cache.set(cache_entry_id, (dirs, files)) return dirs, files def get_mimetype_and_encoding_for_content(content): """Function that returns the mime type and the encoding associated to a content buffer using the magic module under the hood. Args: content (bytes): a content buffer Returns: A tuple (mimetype, encoding), for instance ('text/plain', 'us-ascii'), associated to the provided content. """ while True: try: magic_result = magic.detect_from_content(content) mime_type = magic_result.mime_type encoding = magic_result.encoding break - except Exception as exc: + except Exception: # workaround an issue with the magic module who can fail # if detect_from_content is called multiple times in # a short amount of time reload(magic) return mime_type, encoding # maximum authorized content size in bytes for HTML display # with code highlighting content_display_max_size = get_config()['content_display_max_size'] snapshot_content_max_size = get_config()['snapshot_content_max_size'] def request_content(query_string, max_size=content_display_max_size, raise_if_unavailable=True, reencode=True): """Function that retrieves a SWH content from the SWH archive. Raw bytes content is first retrieved, then the content mime type. If the mime type is not stored in the archive, it will be computed using Python magic module. Args: query_string: a string of the form "[ALGO_HASH:]HASH" where optional ALGO_HASH can be either *sha1*, *sha1_git*, *sha256*, or *blake2s256* (default to *sha1*) and HASH the hexadecimal representation of the hash value max_size: the maximum size for a content to retrieve (default to 1MB, no size limit if None) Returns: A tuple whose first member corresponds to the content raw bytes and second member the content mime type Raises: NotFoundExc if the content is not found """ content_data = service.lookup_content(query_string) filetype = None language = None license = None # requests to the indexer db may fail so properly handle # those cases in order to avoid content display errors try: filetype = service.lookup_content_filetype(query_string) language = service.lookup_content_language(query_string) license = service.lookup_content_license(query_string) - except Exception as e: + except Exception: pass mimetype = 'unknown' encoding = 'unknown' if filetype: mimetype = filetype['mimetype'] encoding = filetype['encoding'] content_data['error_code'] = 200 content_data['error_message'] = '' content_data['error_description'] = '' if not max_size or content_data['length'] < max_size: try: content_raw = service.lookup_content_raw(query_string) except Exception as e: if raise_if_unavailable: raise e else: content_data['raw_data'] = None content_data['error_code'] = 404 content_data['error_description'] = \ 'The bytes of the content are currently not available in the archive.' # noqa content_data['error_message'] = \ http_status_code_message[content_data['error_code']] else: content_data['raw_data'] = content_raw['data'] if not filetype: mimetype, encoding = \ get_mimetype_and_encoding_for_content(content_data['raw_data']) # noqa # encode textual content to utf-8 if needed if reencode and mimetype.startswith('text/'): # probably a malformed UTF-8 content, re-encode it # by replacing invalid chars with a substitution one if encoding == 'unknown-8bit': content_data['raw_data'] = \ content_data['raw_data'].decode('utf-8', 'replace')\ .encode('utf-8') elif 'ascii' not in encoding and encoding not in ['utf-8', 'binary']: # noqa content_data['raw_data'] = \ content_data['raw_data'].decode(encoding, 'replace')\ .encode('utf-8') elif reencode and mimetype.startswith('application/octet-stream'): # file may detect a text content as binary # so try to decode it for display encodings = ['us-ascii'] encodings += ['iso-8859-%s' % i for i in range(1, 17)] for encoding in encodings: try: content_data['raw_data'] = \ content_data['raw_data'].decode(encoding)\ .encode('utf-8') - except Exception as e: + except Exception: pass else: # ensure display in content view mimetype = 'text/plain' break else: content_data['raw_data'] = None content_data['mimetype'] = mimetype content_data['encoding'] = encoding if language: content_data['language'] = language['lang'] else: content_data['language'] = 'not detected' if license: content_data['licenses'] = ', '.join(license['facts'][0]['licenses']) else: content_data['licenses'] = 'not detected' return content_data _browsers_supported_image_mimes = set(['image/gif', 'image/png', 'image/jpeg', 'image/bmp', 'image/webp', 'image/svg', 'image/svg+xml']) def prepare_content_for_display(content_data, mime_type, path): """Function that prepares a content for HTML display. The function tries to associate a programming language to a content in order to perform syntax highlighting client-side using highlightjs. The language is determined using either the content filename or its mime type. If the mime type corresponds to an image format supported by web browsers, the content will be encoded in base64 for displaying the image. Args: content_data (bytes): raw bytes of the content mime_type (string): mime type of the content path (string): path of the content including filename Returns: A dict containing the content bytes (possibly different from the one provided as parameter if it is an image) under the key 'content_data and the corresponding highlightjs language class under the key 'language'. """ language = highlightjs.get_hljs_language_from_filename(path) if not language: language = highlightjs.get_hljs_language_from_mime_type(mime_type) if not language: language = 'nohighlight' elif mime_type.startswith('application/'): mime_type = mime_type.replace('application/', 'text/') if mime_type.startswith('image/'): if mime_type in _browsers_supported_image_mimes: content_data = base64.b64encode(content_data) else: content_data = None if mime_type.startswith('image/svg'): mime_type = 'image/svg+xml' return {'content_data': content_data, 'language': language, 'mimetype': mime_type} def get_origin_visit(origin_info, visit_ts=None, visit_id=None, snapshot_id=None): """Function that returns information about a SWH visit for a given origin. The visit is retrieved from a provided timestamp. The closest visit from that timestamp is selected. Args: origin_info (dict): a dict filled with origin information (id, url, type) visit_ts (int or str): an ISO date string or Unix timestamp to parse Returns: A dict containing the visit info as described below:: {'origin': 2, 'date': '2017-10-08T11:54:25.582463+00:00', 'metadata': {}, 'visit': 25, 'status': 'full'} """ visits = get_origin_visits(origin_info) if not visits: raise NotFoundExc('No SWH visit associated to origin with' ' type %s and url %s!' % (origin_info['type'], origin_info['url'])) if snapshot_id: visit = [v for v in visits if v['snapshot'] == snapshot_id] if len(visit) == 0: raise NotFoundExc( 'Visit for snapshot with id %s for origin with type %s' ' and url %s not found!' % (snapshot_id, origin_info['type'], origin_info['url'])) return visit[0] if visit_id: visit = [v for v in visits if v['visit'] == int(visit_id)] if len(visit) == 0: raise NotFoundExc( 'Visit with id %s for origin with type %s' ' and url %s not found!' % (visit_id, origin_info['type'], origin_info['url'])) return visit[0] if not visit_ts: # returns the latest full visit when no timestamp is provided for v in reversed(visits): if v['status'] == 'full': return v return visits[-1] parsed_visit_ts = math.floor(parse_timestamp(visit_ts).timestamp()) visit_idx = None for i, visit in enumerate(visits): ts = math.floor(parse_timestamp(visit['date']).timestamp()) if i == 0 and parsed_visit_ts <= ts: return visit elif i == len(visits) - 1: if parsed_visit_ts >= ts: return visit else: next_ts = math.floor( parse_timestamp(visits[i+1]['date']).timestamp()) if parsed_visit_ts >= ts and parsed_visit_ts < next_ts: if (parsed_visit_ts - ts) < (next_ts - parsed_visit_ts): visit_idx = i break else: visit_idx = i+1 break if visit_idx is not None: visit = visits[visit_idx] while visit_idx < len(visits) - 1 and \ visit['date'] == visits[visit_idx+1]['date']: visit_idx = visit_idx + 1 visit = visits[visit_idx] return visit else: raise NotFoundExc( 'Visit with timestamp %s for origin with type %s and url %s not found!' % # noqa (visit_ts, origin_info['type'], origin_info['url'])) def process_snapshot_branches(snapshot_branches): """ Process a dictionary describing snapshot branches: extract those targeting revisions and releases, put them in two different lists, then sort those lists in lexicographical order of the branches' names. Args: snapshot_branches (dict): A dict describing the branches of a snapshot as returned for instance by :func:`swh.web.common.service.lookup_snapshot` Returns: tuple: A tuple whose first member is the sorted list of branches targeting revisions and second member the sorted list of branches targeting releases """ # noqa branches = {} releases = {} revision_to_branch = defaultdict(set) revision_to_release = defaultdict(set) release_to_branch = defaultdict(set) for branch_name, target in snapshot_branches.items(): if not target: # FIXME: display branches with an unknown target anyway continue target_id = target['target'] target_type = target['target_type'] if target_type == 'revision': branches[branch_name] = { 'name': branch_name, 'revision': target_id, } revision_to_branch[target_id].add(branch_name) elif target_type == 'release': release_to_branch[target_id].add(branch_name) # FIXME: handle pointers to other object types # FIXME: handle branch aliases releases_info = service.lookup_release_multiple( release_to_branch.keys() ) for release in releases_info: branches_to_update = release_to_branch[release['id']] for branch in branches_to_update: releases[branch] = { 'name': release['name'], 'branch_name': branch, 'date': format_utc_iso_date(release['date']), 'id': release['id'], 'message': release['message'], 'target_type': release['target_type'], 'target': release['target'], } if release['target_type'] == 'revision': revision_to_release[release['target']].update( branches_to_update ) revisions = service.lookup_revision_multiple( set(revision_to_branch.keys()) | set(revision_to_release.keys()) ) for revision in revisions: revision_data = { 'directory': revision['directory'], 'date': format_utc_iso_date(revision['date']), 'message': revision['message'], } for branch in revision_to_branch[revision['id']]: branches[branch].update(revision_data) for release in revision_to_release[revision['id']]: releases[release]['directory'] = revision['directory'] ret_branches = list(sorted(branches.values(), key=lambda b: b['name'])) ret_releases = list(sorted(releases.values(), key=lambda b: b['name'])) return ret_branches, ret_releases def get_snapshot_content(snapshot_id): """Returns the lists of branches and releases associated to a swh snapshot. That list is put in cache in order to speedup the navigation in the swh-web/browse ui. .. warning:: At most 1000 branches contained in the snapshot will be returned for performance reasons. Args: snapshot_id (str): hexadecimal representation of the snapshot identifier Returns: A tuple with two members. The first one is a list of dict describing the snapshot branches. The second one is a list of dict describing the snapshot releases. Raises: NotFoundExc if the snapshot does not exist """ cache_entry_id = 'swh_snapshot_%s' % snapshot_id cache_entry = cache.get(cache_entry_id) if cache_entry: return cache_entry['branches'], cache_entry['releases'] branches = [] releases = [] if snapshot_id: snapshot = service.lookup_snapshot( snapshot_id, branches_count=snapshot_content_max_size) branches, releases = process_snapshot_branches(snapshot['branches']) cache.set(cache_entry_id, { 'branches': branches, 'releases': releases, }) return branches, releases def get_origin_visit_snapshot(origin_info, visit_ts=None, visit_id=None, snapshot_id=None): """Returns the lists of branches and releases associated to a swh origin for a given visit. The visit is expressed by a timestamp. In the latter case, the closest visit from the provided timestamp will be used. If no visit parameter is provided, it returns the list of branches found for the latest visit. That list is put in cache in order to speedup the navigation in the swh-web/browse ui. .. warning:: At most 1000 branches contained in the snapshot will be returned for performance reasons. Args: origin_info (dict): a dict filled with origin information (id, url, type) visit_ts (int or str): an ISO date string or Unix timestamp to parse visit_id (int): optional visit id for desambiguation in case several visits have the same timestamp Returns: A tuple with two members. The first one is a list of dict describing the origin branches for the given visit. The second one is a list of dict describing the origin releases for the given visit. Raises: NotFoundExc if the origin or its visit are not found """ visit_info = get_origin_visit(origin_info, visit_ts, visit_id, snapshot_id) return get_snapshot_content(visit_info['snapshot']) def gen_link(url, link_text=None, link_attrs={}): """ Utility function for generating an HTML link to insert in Django templates. Args: url (str): an url link_text (str): optional text for the produced link, if not provided the url will be used link_attrs (dict): optional attributes (e.g. class) to add to the link Returns: An HTML link in the form 'link_text' """ attrs = ' ' for k, v in link_attrs.items(): attrs += '%s="%s" ' % (k, v) if not link_text: link_text = url link = '%s' % (attrs, url, link_text) return mark_safe(link) def gen_person_link(person_id, person_name, snapshot_context=None, link_attrs={}): """ Utility function for generating a link to a SWH person HTML view to insert in Django templates. Args: person_id (int): a SWH person id person_name (str): the associated person name link_attrs (dict): optional attributes (e.g. class) to add to the link Returns: An HTML link in the form 'person_name' """ query_params = None if snapshot_context and snapshot_context['origin_info']: origin_info = snapshot_context['origin_info'] query_params = {'origin_type': origin_info['type'], 'origin': origin_info['url']} if 'timestamp' in snapshot_context['url_args']: query_params['timestamp'] = \ snapshot_context['url_args']['timestamp'] if 'visit_id' in snapshot_context['query_params']: query_params['visit_id'] = \ snapshot_context['query_params']['visit_id'] elif snapshot_context: query_params = {'snapshot_id': snapshot_context['snapshot_id']} person_url = reverse('browse-person', kwargs={'person_id': person_id}, query_params=query_params) return gen_link(person_url, person_name or 'None', link_attrs) def gen_revision_link(revision_id, shorten_id=False, snapshot_context=None, link_text=None, link_attrs={}): """ Utility function for generating a link to a SWH revision HTML view to insert in Django templates. Args: revision_id (str): a SWH revision id shorten_id (boolean): whether to shorten the revision id to 7 characters for the link text snapshot_context (dict): if provided, generate snapshot-dependent browsing link link_attrs (dict): optional attributes (e.g. class) to add to the link Returns: An HTML link in the form 'revision_id' """ query_params = None if snapshot_context and snapshot_context['origin_info']: origin_info = snapshot_context['origin_info'] origin_type = snapshot_context['origin_type'] query_params = {'origin_type': origin_type, 'origin': origin_info['url']} if 'timestamp' in snapshot_context['url_args']: query_params['timestamp'] = \ snapshot_context['url_args']['timestamp'] if 'visit_id' in snapshot_context['query_params']: query_params['visit_id'] = \ snapshot_context['query_params']['visit_id'] elif snapshot_context: query_params = {'snapshot_id': snapshot_context['snapshot_id']} revision_url = reverse('browse-revision', kwargs={'sha1_git': revision_id}, query_params=query_params) if shorten_id: return gen_link(revision_url, revision_id[:7], link_attrs) else: if not link_text: link_text = revision_id return gen_link(revision_url, link_text, link_attrs) def gen_origin_link(origin_info, link_attrs={}): """ Utility function for generating a link to a SWH origin HTML view to insert in Django templates. Args: origin_info (dict): a dicted filled with origin information (id, type, url) link_attrs (dict): optional attributes (e.g. class) to add to the link Returns: An HTML link in the form 'Origin: origin_url' """ # noqa origin_browse_url = reverse('browse-origin', kwargs={'origin_type': origin_info['type'], 'origin_url': origin_info['url']}) return gen_link(origin_browse_url, 'Origin: ' + origin_info['url'], link_attrs) def gen_directory_link(sha1_git, link_text=None, link_attrs={}): """ Utility function for generating a link to a SWH directory HTML view to insert in Django templates. Args: sha1_git (str): directory identifier link_text (str): optional text for the generated link (the generated url will be used by default) link_attrs (dict): optional attributes (e.g. class) to add to the link Returns: An HTML link in the form 'link_text' """ directory_url = reverse('browse-directory', kwargs={'sha1_git': sha1_git}) if not link_text: link_text = directory_url return gen_link(directory_url, link_text, link_attrs) def gen_snapshot_link(snapshot_id, link_text=None, link_attrs={}): """ Utility function for generating a link to a SWH snapshot HTML view to insert in Django templates. Args: snapshot_id (str): snapshot identifier link_text (str): optional text for the generated link (the generated url will be used by default) link_attrs (dict): optional attributes (e.g. class) to add to the link Returns: An HTML link in the form 'link_text' """ snapshot_url = reverse('browse-snapshot', kwargs={'snapshot_id': snapshot_id}) if not link_text: link_text = snapshot_url return gen_link(snapshot_url, link_text, link_attrs) def gen_snapshot_directory_link(snapshot_context, revision_id=None, link_text=None, link_attrs={}): """ Utility function for generating a link to a SWH directory HTML view in the context of a snapshot to insert in Django templates. Args: snapshot_context (dict): the snapshot information revision_id (str): optional revision identifier in order to use the associated directory link_text (str): optional text to use for the generated link link_attrs (dict): optional attributes (e.g. class) to add to the link Returns: An HTML link in the form 'origin_directory_view_url' """ query_params = {'revision': revision_id} if snapshot_context['origin_info']: origin_info = snapshot_context['origin_info'] url_args = {'origin_type': origin_info['type'], 'origin_url': origin_info['url']} if 'timestamp' in snapshot_context['url_args']: url_args['timestamp'] = \ snapshot_context['url_args']['timestamp'] if 'visit_id' in snapshot_context['query_params']: query_params['visit_id'] = \ snapshot_context['query_params']['visit_id'] directory_url = reverse('browse-origin-directory', kwargs=url_args, query_params=query_params) else: url_args = {'snapshot_id': snapshot_context['snapshot_id']} directory_url = reverse('browse-snapshot-directory', kwargs=url_args, query_params=query_params) if not link_text: link_text = directory_url return gen_link(directory_url, link_text, link_attrs) def gen_content_link(sha1_git, link_text=None, link_attrs={}): """ Utility function for generating a link to a SWH content HTML view to insert in Django templates. Args: sha1_git (str): content identifier link_text (str): optional text for the generated link (the generated url will be used by default) link_attrs (dict): optional attributes (e.g. class) to add to the link Returns: An HTML link in the form 'link_text' """ content_url = reverse('browse-content', kwargs={'query_string': 'sha1_git:' + sha1_git}) if not link_text: link_text = content_url return gen_link(content_url, link_text, link_attrs) def get_revision_log_url(revision_id, snapshot_context=None): """ Utility function for getting the URL for a SWH revision log HTML view (possibly in the context of an origin). Args: revision_id (str): revision identifier the history heads to snapshot_context (dict): if provided, generate snapshot-dependent browsing link Returns: The SWH revision log view URL """ query_params = {'revision': revision_id} if snapshot_context and snapshot_context['origin_info']: origin_info = snapshot_context['origin_info'] url_args = {'origin_type': origin_info['type'], 'origin_url': origin_info['url']} if 'timestamp' in snapshot_context['url_args']: url_args['timestamp'] = \ snapshot_context['url_args']['timestamp'] if 'visit_id' in snapshot_context['query_params']: query_params['visit_id'] = \ snapshot_context['query_params']['visit_id'] revision_log_url = reverse('browse-origin-log', kwargs=url_args, query_params=query_params) elif snapshot_context: url_args = {'snapshot_id': snapshot_context['snapshot_id']} revision_log_url = reverse('browse-snapshot-log', kwargs=url_args, query_params=query_params) else: revision_log_url = reverse('browse-revision-log', kwargs={'sha1_git': revision_id}) return revision_log_url def gen_revision_log_link(revision_id, snapshot_context=None, link_text=None, link_attrs={}): """ Utility function for generating a link to a SWH revision log HTML view (possibly in the context of an origin) to insert in Django templates. Args: revision_id (str): revision identifier the history heads to snapshot_context (dict): if provided, generate snapshot-dependent browsing link link_text (str): optional text to use for the generated link link_attrs (dict): optional attributes (e.g. class) to add to the link Returns: An HTML link in the form 'link_text' """ revision_log_url = get_revision_log_url(revision_id, snapshot_context) if not link_text: link_text = revision_log_url return gen_link(revision_log_url, link_text, link_attrs) def _format_log_entries(revision_log, per_page, snapshot_context=None): revision_log_data = [] for i, log in enumerate(revision_log): if i == per_page: break author_name = 'None' author_link = 'None' if log['author']: author_name = log['author']['name'] or log['author']['fullname'] author_link = gen_person_link(log['author']['id'], author_name, snapshot_context) revision_log_data.append( {'author': author_link, 'revision': gen_revision_link(log['id'], True, snapshot_context), 'message': log['message'], 'date': format_utc_iso_date(log['date']), 'directory': log['directory']}) return revision_log_data def prepare_revision_log_for_display(revision_log, per_page, revs_breadcrumb, snapshot_context=None): """ Utility functions that process raw revision log data for HTML display. Its purpose is to: * add links to relevant SWH browse views * format date in human readable format * truncate the message log It also computes the data needed to generate the links for navigating back and forth in the history log. Args: revision_log (list): raw revision log as returned by the SWH web api per_page (int): number of log entries per page revs_breadcrumb (str): breadcrumbs of revisions navigated so far, in the form 'rev1[/rev2/../revN]'. Each revision corresponds to the first one displayed in the HTML view for history log. snapshot_context (dict): if provided, generate snapshot-dependent browsing link """ current_rev = revision_log[0]['id'] next_rev = None prev_rev = None next_revs_breadcrumb = None prev_revs_breadcrumb = None if len(revision_log) == per_page + 1: prev_rev = revision_log[-1]['id'] prev_rev_bc = current_rev if snapshot_context: prev_rev_bc = prev_rev if revs_breadcrumb: revs = revs_breadcrumb.split('/') next_rev = revs[-1] if len(revs) > 1: next_revs_breadcrumb = '/'.join(revs[:-1]) if len(revision_log) == per_page + 1: prev_revs_breadcrumb = revs_breadcrumb + '/' + prev_rev_bc else: prev_revs_breadcrumb = prev_rev_bc return {'revision_log_data': _format_log_entries(revision_log, per_page, snapshot_context), 'prev_rev': prev_rev, 'prev_revs_breadcrumb': prev_revs_breadcrumb, 'next_rev': next_rev, 'next_revs_breadcrumb': next_revs_breadcrumb} # list of origin types that can be found in the swh archive # TODO: retrieve it dynamically in an efficient way instead # of hardcoding it _swh_origin_types = ['git', 'svn', 'deb', 'hg', 'ftp', 'deposit', 'pypi'] def get_origin_info(origin_url, origin_type=None): """ Get info about a SWH origin. Its main purpose is to automatically find an origin type when it is not provided as parameter. Args: origin_url (str): complete url of a SWH origin origin_type (str): optional origin type Returns: A dict with the following entries: * type: the origin type * url: the origin url * id: the SWH internal id of the origin """ if origin_type: return service.lookup_origin({'type': origin_type, 'url': origin_url}) else: for origin_type in _swh_origin_types: try: origin_info = service.lookup_origin({'type': origin_type, 'url': origin_url}) return origin_info except Exception: pass raise NotFoundExc('Origin with url %s not found!' % origin_url) def get_snapshot_context(snapshot_id=None, origin_type=None, origin_url=None, timestamp=None, visit_id=None): """ Utility function to compute relevant information when navigating the SWH archive in a snapshot context. The snapshot is either referenced by its id or it will be retrieved from an origin visit. Args: snapshot_id (str): hexadecimal representation of a snapshot identifier, all other parameters will be ignored if it is provided origin_type (str): the origin type (git, svn, deposit, ...) origin_url (str): the origin_url (e.g. https://github.com/(user)/(repo)/) timestamp (str): a datetime string for retrieving the closest SWH visit of the origin visit_id (int): optional visit id for disambiguation in case of several visits with the same timestamp Returns: A dict with the following entries: * origin_info: dict containing origin information * visit_info: dict containing SWH visit information * branches: the list of branches for the origin found during the visit * releases: the list of releases for the origin found during the visit * origin_browse_url: the url to browse the origin * origin_branches_url: the url to browse the origin branches * origin_releases_url': the url to browse the origin releases * origin_visit_url: the url to browse the snapshot of the origin found during the visit * url_args: dict containing url arguments to use when browsing in the context of the origin and its visit """ # noqa origin_info = None visit_info = None url_args = None query_params = {} branches = [] releases = [] browse_url = None visit_url = None branches_url = None releases_url = None swh_type = 'snapshot' if origin_url: swh_type = 'origin' origin_info = get_origin_info(origin_url, origin_type) visit_info = get_origin_visit(origin_info, timestamp, visit_id, snapshot_id) visit_info['fmt_date'] = format_utc_iso_date(visit_info['date']) snapshot_id = visit_info['snapshot'] # provided timestamp is not necessarily equals to the one # of the retrieved visit, so get the exact one in order # use it in the urls generated below if timestamp: timestamp = visit_info['date'] branches, releases = \ get_origin_visit_snapshot(origin_info, timestamp, visit_id, snapshot_id) url_args = {'origin_type': origin_type, 'origin_url': origin_info['url']} query_params = {'visit_id': visit_id} browse_url = reverse('browse-origin-visits', kwargs=url_args) if timestamp: url_args['timestamp'] = format_utc_iso_date(timestamp, '%Y-%m-%dT%H:%M:%S') visit_url = reverse('browse-origin-directory', kwargs=url_args, query_params=query_params) visit_info['url'] = visit_url branches_url = reverse('browse-origin-branches', kwargs=url_args, query_params=query_params) releases_url = reverse('browse-origin-releases', kwargs=url_args, query_params=query_params) elif snapshot_id: branches, releases = get_snapshot_content(snapshot_id) url_args = {'snapshot_id': snapshot_id} browse_url = reverse('browse-snapshot', kwargs=url_args) branches_url = reverse('browse-snapshot-branches', kwargs=url_args) releases_url = reverse('browse-snapshot-releases', kwargs=url_args) releases = list(reversed(releases)) snapshot_size = service.lookup_snapshot_size(snapshot_id) swh_snp_id = persistent_identifier('snapshot', snapshot_id) return { 'swh_type': swh_type, 'swh_object_id': swh_snp_id, 'snapshot_id': snapshot_id, 'snapshot_size': snapshot_size, 'origin_info': origin_info, # keep track if the origin type was provided as url argument 'origin_type': origin_type, 'visit_info': visit_info, 'branches': branches, 'releases': releases, 'branch': None, 'release': None, 'browse_url': browse_url, 'branches_url': branches_url, 'releases_url': releases_url, 'url_args': url_args, 'query_params': query_params } # list of common readme names ordered by preference # (lower indices have higher priority) _common_readme_names = [ "readme.markdown", "readme.md", "readme.rst", "readme.txt", "readme" ] def get_readme_to_display(readmes): """ Process a list of readme files found in a directory in order to find the adequate one to display. Args: readmes: a list of dict where keys are readme file names and values are readme sha1s Returns: A tuple (readme_name, readme_sha1) """ readme_name = None readme_url = None readme_sha1 = None readme_html = None lc_readmes = {k.lower(): {'orig_name': k, 'sha1': v} for k, v in readmes.items()} # look for readme names according to the preference order # defined by the _common_readme_names list for common_readme_name in _common_readme_names: if common_readme_name in lc_readmes: readme_name = lc_readmes[common_readme_name]['orig_name'] readme_sha1 = lc_readmes[common_readme_name]['sha1'] readme_url = reverse('browse-content-raw', kwargs={'query_string': readme_sha1}) break # otherwise pick the first readme like file if any if not readme_name and len(readmes.items()) > 0: readme_name = next(iter(readmes)) readme_sha1 = readmes[readme_name] readme_url = reverse('browse-content-raw', kwargs={'query_string': readme_sha1}) # convert rst README to html server side as there is # no viable solution to perform that task client side if readme_name and readme_name.endswith('.rst'): cache_entry_id = 'readme_%s' % readme_sha1 cache_entry = cache.get(cache_entry_id) if cache_entry: readme_html = cache_entry else: try: rst_doc = request_content(readme_sha1) readme_html = pypandoc.convert_text(rst_doc['raw_data'], 'html', format='rst') cache.set(cache_entry_id, readme_html) except Exception: readme_html = 'Readme bytes are not available' return readme_name, readme_url, readme_html def get_swh_persistent_ids(swh_objects, snapshot_context=None): """ Returns a list of dict containing info related to persistent identifiers of swh objects. Args: swh_objects (list): a list of dict with the following keys: * type: swh object type (content/directory/release/revision/snapshot) * id: swh object id snapshot_context (dict): optional parameter describing the snapshot in which the object has been found Returns: list: a list of dict with the following keys: * object_type: the swh object type (content/directory/release/revision/snapshot) * object_icon: the swh object icon to use in HTML views * swh_id: the computed swh object persistent identifier * swh_id_url: the url resolving the persistent identifier * show_options: boolean indicating if the persistent id options must be displayed in persistent ids HTML view """ # noqa swh_ids = [] for swh_object in swh_objects: swh_id = get_swh_persistent_id(swh_object['type'], swh_object['id']) show_options = swh_object['type'] == 'content' or \ (snapshot_context and snapshot_context['origin_info'] is not None) object_icon = mark_safe('') if swh_object['type'] == 'directory': object_icon = mark_safe('') elif swh_object['type'] == 'release': object_icon = mark_safe('') elif swh_object['type'] == 'revision': object_icon = mark_safe('') # noqa elif swh_object['type'] == 'snapshot': object_icon = mark_safe('') swh_ids.append({ 'object_type': swh_object['type'], 'object_icon': object_icon, 'swh_id': swh_id, 'swh_id_url': reverse('browse-swh-id', kwargs={'swh_id': swh_id}), 'show_options': show_options }) return swh_ids diff --git a/swh/web/common/utils.py b/swh/web/common/utils.py index aef03f063..0cd127d4b 100644 --- a/swh/web/common/utils.py +++ b/swh/web/common/utils.py @@ -1,392 +1,392 @@ # Copyright (C) 2017-2018 The Software Heritage developers # See the AUTHORS file at the top-level directory of this distribution # License: GNU Affero General Public License version 3, or any later version # See top-level LICENSE file for more information import docutils.parsers.rst import docutils.utils import re import requests from datetime import datetime, timezone from dateutil import parser as date_parser from dateutil import tz from django.core.cache import cache -from django.core import urlresolvers +from django.urls import reverse as django_reverse from django.http import QueryDict from swh.model.exceptions import ValidationError from swh.model.identifiers import ( persistent_identifier, parse_persistent_identifier, CONTENT, DIRECTORY, RELEASE, REVISION, SNAPSHOT ) from swh.web.common import service from swh.web.common.exc import BadInputExc from swh.web.config import get_config def reverse(viewname, args=None, kwargs=None, query_params=None, current_app=None, urlconf=None): """An override of django reverse function supporting query parameters. Args: viewname: the name of the django view from which to compute a url args: list of url arguments ordered according to their position it kwargs: dictionary of url arguments indexed by their names query_params: dictionary of query parameters to append to the reversed url current_app: the name of the django app tighted to the view urlconf: url configuration module Returns: str: the url of the requested view with processed arguments and query parameters """ if kwargs: kwargs = {k: v for k, v in kwargs.items() if v is not None} - url = urlresolvers.reverse( + url = django_reverse( viewname, urlconf=urlconf, args=args, kwargs=kwargs, current_app=current_app) if query_params: query_params = {k: v for k, v in query_params.items() if v} if query_params and len(query_params) > 0: query_dict = QueryDict('', mutable=True) for k in sorted(query_params.keys()): query_dict[k] = query_params[k] url += ('?' + query_dict.urlencode(safe='/;:')) return url def datetime_to_utc(date): """Returns datetime in UTC without timezone info Args: date (datetime.datetime): input datetime with timezone info Returns: datetime.datetime: datetime in UTC without timezone info """ if date.tzinfo: return date.astimezone(tz.gettz('UTC')).replace(tzinfo=timezone.utc) else: return date def parse_timestamp(timestamp): """Given a time or timestamp (as string), parse the result as UTC datetime. Returns: datetime.datetime: a timezone-aware datetime representing the parsed value or None if the parsing fails. Samples: - 2016-01-12 - 2016-01-12T09:19:12+0100 - Today is January 1, 2047 at 8:21:00AM - 1452591542 """ if not timestamp: return None try: date = date_parser.parse(timestamp, ignoretz=False, fuzzy=True) return datetime_to_utc(date) except Exception: try: return datetime.utcfromtimestamp(float(timestamp)).replace( tzinfo=timezone.utc) except (ValueError, OverflowError) as e: raise BadInputExc(e) def shorten_path(path): """Shorten the given path: for each hash present, only return the first 8 characters followed by an ellipsis""" sha256_re = r'([0-9a-f]{8})[0-9a-z]{56}' sha1_re = r'([0-9a-f]{8})[0-9a-f]{32}' ret = re.sub(sha256_re, r'\1...', path) return re.sub(sha1_re, r'\1...', ret) def format_utc_iso_date(iso_date, fmt='%d %B %Y, %H:%M UTC'): """Turns a string reprensation of an ISO 8601 date string to UTC and format it into a more human readable one. For instance, from the following input string: '2017-05-04T13:27:13+02:00' the following one is returned: '04 May 2017, 11:27 UTC'. Custom format string may also be provided as parameter Args: iso_date (str): a string representation of an ISO 8601 date fmt (str): optional date formatting string Returns: str: a formatted string representation of the input iso date """ if not iso_date: return iso_date date = parse_timestamp(iso_date) return date.strftime(fmt) def gen_path_info(path): """Function to generate path data navigation for use with a breadcrumb in the swh web ui. For instance, from a path /folder1/folder2/folder3, it returns the following list:: [{'name': 'folder1', 'path': 'folder1'}, {'name': 'folder2', 'path': 'folder1/folder2'}, {'name': 'folder3', 'path': 'folder1/folder2/folder3'}] Args: path: a filesystem path Returns: list: a list of path data for navigation as illustrated above. """ path_info = [] if path: sub_paths = path.strip('/').split('/') path_from_root = '' for p in sub_paths: path_from_root += '/' + p path_info.append({'name': p, 'path': path_from_root.strip('/')}) return path_info def get_origin_visits(origin_info): """Function that returns the list of visits for a swh origin. That list is put in cache in order to speedup the navigation in the swh web browse ui. Args: origin_id (int): the id of the swh origin to fetch visits from Returns: list: A list of dict describing the origin visits with the following keys: * **date**: UTC visit date in ISO format, * **origin**: the origin id * **status**: the visit status, either *full* or *partial* * **visit**: the visit id Raises: NotFoundExc: if the origin is not found """ cache_entry_id = 'origin_%s_visits' % origin_info['id'] cache_entry = cache.get(cache_entry_id) last_snapshot = service.lookup_latest_origin_snapshot(origin_info['id']) if cache_entry and \ (not last_snapshot or last_snapshot['id'] == cache_entry[-1]['snapshot']): return cache_entry origin_visits = [] per_page = service.MAX_LIMIT last_visit = None while 1: visits = list(service.lookup_origin_visits(origin_info['id'], last_visit=last_visit, per_page=per_page)) origin_visits += visits if len(visits) < per_page: break else: if not last_visit: last_visit = per_page else: last_visit += per_page def _visit_sort_key(visit): ts = parse_timestamp(visit['date']).timestamp() return ts + (float(visit['visit']) / 10e3) for v in origin_visits: if 'metadata' in v: del v['metadata'] origin_visits = [dict(t) for t in set([tuple(d.items()) for d in origin_visits])] origin_visits = sorted(origin_visits, key=lambda v: _visit_sort_key(v)) cache.set(cache_entry_id, origin_visits) return origin_visits def get_swh_persistent_id(object_type, object_id, scheme_version=1): """ Returns the persistent identifier for a swh object based on: * the object type * the object id * the swh identifiers scheme version Args: object_type (str): the swh object type (content/directory/release/revision/snapshot) object_id (str): the swh object id (hexadecimal representation of its hash value) scheme_version (int): the scheme version of the swh persistent identifiers Returns: str: the swh object persistent identifier Raises: BadInputExc: if the provided parameters do not enable to generate a valid identifier """ try: swh_id = persistent_identifier(object_type, object_id, scheme_version) except ValidationError as e: raise BadInputExc('Invalid object (%s) for swh persistent id. %s' % (object_id, e)) else: return swh_id def resolve_swh_persistent_id(swh_id, query_params=None): """ Try to resolve a SWH persistent id into an url for browsing the pointed object. Args: swh_id (str): a SWH persistent identifier query_params (django.http.QueryDict): optional dict filled with query parameters to append to the browse url Returns: dict: a dict with the following keys: * **swh_id_parsed (swh.model.identifiers.PersistentId)**: the parsed identifier * **browse_url (str)**: the url for browsing the pointed object Raises: BadInputExc: if the provided identifier can not be parsed """ # noqa try: swh_id_parsed = parse_persistent_identifier(swh_id) object_type = swh_id_parsed.object_type object_id = swh_id_parsed.object_id browse_url = None query_dict = QueryDict('', mutable=True) if query_params and len(query_params) > 0: for k in sorted(query_params.keys()): query_dict[k] = query_params[k] if 'origin' in swh_id_parsed.metadata: query_dict['origin'] = swh_id_parsed.metadata['origin'] if object_type == CONTENT: query_string = 'sha1_git:' + object_id fragment = '' if 'lines' in swh_id_parsed.metadata: lines = swh_id_parsed.metadata['lines'].split('-') fragment += '#L' + lines[0] if len(lines) > 1: fragment += '-L' + lines[1] browse_url = reverse('browse-content', kwargs={'query_string': query_string}, query_params=query_dict) + fragment elif object_type == DIRECTORY: browse_url = reverse('browse-directory', kwargs={'sha1_git': object_id}, query_params=query_dict) elif object_type == RELEASE: browse_url = reverse('browse-release', kwargs={'sha1_git': object_id}, query_params=query_dict) elif object_type == REVISION: browse_url = reverse('browse-revision', kwargs={'sha1_git': object_id}, query_params=query_dict) elif object_type == SNAPSHOT: browse_url = reverse('browse-snapshot', kwargs={'snapshot_id': object_id}, query_params=query_dict) except ValidationError as ve: raise BadInputExc('Error when parsing identifier. %s' % ' '.join(ve.messages)) else: return {'swh_id_parsed': swh_id_parsed, 'browse_url': browse_url} def parse_rst(text, report_level=2): """ Parse a reStructuredText string with docutils. Args: text (str): string with reStructuredText markups in it report_level (int): level of docutils report messages to print (1 info 2 warning 3 error 4 severe 5 none) Returns: docutils.nodes.document: a parsed docutils document """ parser = docutils.parsers.rst.Parser() components = (docutils.parsers.rst.Parser,) settings = docutils.frontend.OptionParser( components=components).get_default_values() settings.report_level = report_level document = docutils.utils.new_document('rst-doc', settings=settings) parser.parse(text, document) return document def get_client_ip(request): """ Return the client IP address from an incoming HTTP request. Args: request (django.http.HttpRequest): the incoming HTTP request Returns: str: The client IP address """ x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR') if x_forwarded_for: ip = x_forwarded_for.split(',')[0] else: ip = request.META.get('REMOTE_ADDR') return ip def is_recaptcha_valid(request, recaptcha_response): """ Verify if the response for Google reCAPTCHA is valid. Args: request (django.http.HttpRequest): the incoming HTTP request recaptcha_response (str): the reCAPTCHA response Returns: bool: Wether the reCAPTCHA response is valid or not """ config = get_config() return requests.post( config['grecaptcha']['validation_url'], data={ 'secret': config['grecaptcha']['private_key'], 'response': recaptcha_response, 'remoteip': get_client_ip(request) }, verify=True ).json().get("success", False) diff --git a/swh/web/tests/admin/test_origin_save.py b/swh/web/tests/admin/test_origin_save.py index cffec5fad..d05ef8363 100644 --- a/swh/web/tests/admin/test_origin_save.py +++ b/swh/web/tests/admin/test_origin_save.py @@ -1,196 +1,196 @@ # Copyright (C) 2015-2018 The Software Heritage developers # See the AUTHORS file at the top-level directory of this distribution # License: GNU Affero General Public License version 3, or any later version # See top-level LICENSE file for more information from urllib.parse import unquote from django.contrib.auth import get_user_model from unittest.mock import patch from swh.web.common.models import ( SaveAuthorizedOrigin, SaveUnauthorizedOrigin ) from swh.web.common.origin_save import can_save_origin from swh.web.common.models import ( SAVE_REQUEST_PENDING, SAVE_REQUEST_ACCEPTED, SAVE_REQUEST_REJECTED, SAVE_TASK_NOT_YET_SCHEDULED ) from swh.web.common.utils import reverse from swh.web.tests.testcase import SWHWebTestCase _user_name = 'swh-web-admin' _user_mail = 'admin@swh-web.org' _user_password = '..34~pounds~BEAUTY~march~63..' _authorized_origin_url = 'https://scm.ourproject.org/anonscm/' _unauthorized_origin_url = 'https://www.softwareheritage.org/' class OriginSaveAdminTestCase(SWHWebTestCase): @classmethod def setUpTestData(cls): # noqa: N802 User = get_user_model() # noqa: N806 user = User.objects.create_user(_user_name, _user_mail, _user_password) user.is_staff = True user.save() SaveAuthorizedOrigin.objects.create(url=_authorized_origin_url) SaveUnauthorizedOrigin.objects.create(url=_unauthorized_origin_url) def check_not_login(self, url): login_url = reverse('login', query_params={'next': url}) response = self.client.post(url) - self.assertEquals(response.status_code, 302) - self.assertEquals(unquote(response.url), login_url) + self.assertEqual(response.status_code, 302) + self.assertEqual(unquote(response.url), login_url) def test_add_authorized_origin_url(self): authorized_url = 'https://scm.adullact.net/anonscm/' - self.assertEquals(can_save_origin(authorized_url), - SAVE_REQUEST_PENDING) + self.assertEqual(can_save_origin(authorized_url), + SAVE_REQUEST_PENDING) url = reverse('admin-origin-save-add-authorized-url', kwargs={'origin_url': authorized_url}) self.check_not_login(url) - self.assertEquals(can_save_origin(authorized_url), - SAVE_REQUEST_PENDING) + self.assertEqual(can_save_origin(authorized_url), + SAVE_REQUEST_PENDING) self.client.login(username=_user_name, password=_user_password) response = self.client.post(url) - self.assertEquals(response.status_code, 200) - self.assertEquals(can_save_origin(authorized_url), - SAVE_REQUEST_ACCEPTED) + self.assertEqual(response.status_code, 200) + self.assertEqual(can_save_origin(authorized_url), + SAVE_REQUEST_ACCEPTED) def test_remove_authorized_origin_url(self): - self.assertEquals(can_save_origin(_authorized_origin_url), - SAVE_REQUEST_ACCEPTED) + self.assertEqual(can_save_origin(_authorized_origin_url), + SAVE_REQUEST_ACCEPTED) url = reverse('admin-origin-save-remove-authorized-url', kwargs={'origin_url': _authorized_origin_url}) self.check_not_login(url) - self.assertEquals(can_save_origin(_authorized_origin_url), - SAVE_REQUEST_ACCEPTED) + self.assertEqual(can_save_origin(_authorized_origin_url), + SAVE_REQUEST_ACCEPTED) self.client.login(username=_user_name, password=_user_password) response = self.client.post(url) - self.assertEquals(response.status_code, 200) - self.assertEquals(can_save_origin(_authorized_origin_url), - SAVE_REQUEST_PENDING) + self.assertEqual(response.status_code, 200) + self.assertEqual(can_save_origin(_authorized_origin_url), + SAVE_REQUEST_PENDING) def test_add_unauthorized_origin_url(self): unauthorized_url = 'https://www.yahoo./' - self.assertEquals(can_save_origin(unauthorized_url), - SAVE_REQUEST_PENDING) + self.assertEqual(can_save_origin(unauthorized_url), + SAVE_REQUEST_PENDING) url = reverse('admin-origin-save-add-unauthorized-url', kwargs={'origin_url': unauthorized_url}) self.check_not_login(url) - self.assertEquals(can_save_origin(unauthorized_url), - SAVE_REQUEST_PENDING) + self.assertEqual(can_save_origin(unauthorized_url), + SAVE_REQUEST_PENDING) self.client.login(username=_user_name, password=_user_password) response = self.client.post(url) - self.assertEquals(response.status_code, 200) - self.assertEquals(can_save_origin(unauthorized_url), - SAVE_REQUEST_REJECTED) + self.assertEqual(response.status_code, 200) + self.assertEqual(can_save_origin(unauthorized_url), + SAVE_REQUEST_REJECTED) def test_remove_unauthorized_origin_url(self): - self.assertEquals(can_save_origin(_unauthorized_origin_url), - SAVE_REQUEST_REJECTED) + self.assertEqual(can_save_origin(_unauthorized_origin_url), + SAVE_REQUEST_REJECTED) url = reverse('admin-origin-save-remove-unauthorized-url', kwargs={'origin_url': _unauthorized_origin_url}) self.check_not_login(url) - self.assertEquals(can_save_origin(_unauthorized_origin_url), - SAVE_REQUEST_REJECTED) + self.assertEqual(can_save_origin(_unauthorized_origin_url), + SAVE_REQUEST_REJECTED) self.client.login(username=_user_name, password=_user_password) response = self.client.post(url) - self.assertEquals(response.status_code, 200) - self.assertEquals(can_save_origin(_unauthorized_origin_url), - SAVE_REQUEST_PENDING) + self.assertEqual(response.status_code, 200) + self.assertEqual(can_save_origin(_unauthorized_origin_url), + SAVE_REQUEST_PENDING) @patch('swh.web.common.origin_save.scheduler') def test_accept_pending_save_request(self, mock_scheduler): origin_type = 'git' origin_url = 'https://v2.pikacode.com/bthate/botlib.git' save_request_url = reverse('api-save-origin', kwargs={'origin_type': origin_type, 'origin_url': origin_url}) response = self.client.post(save_request_url, data={}, content_type='application/x-www-form-urlencoded') # noqa - self.assertEquals(response.status_code, 200) - self.assertEquals(response.data['save_request_status'], - SAVE_REQUEST_PENDING) + self.assertEqual(response.status_code, 200) + self.assertEqual(response.data['save_request_status'], + SAVE_REQUEST_PENDING) accept_request_url = reverse('admin-origin-save-request-accept', kwargs={'origin_type': origin_type, 'origin_url': origin_url}) self.check_not_login(accept_request_url) tasks_data = [ { 'priority': 'high', 'policy': 'oneshot', 'type': 'origin-update-git', 'arguments': { 'kwargs': { 'repo_url': origin_url }, 'args': [] }, 'status': 'next_run_not_scheduled', 'id': 1, } ] mock_scheduler.create_tasks.return_value = tasks_data mock_scheduler.get_tasks.return_value = tasks_data self.client.login(username=_user_name, password=_user_password) response = self.client.post(accept_request_url) - self.assertEquals(response.status_code, 200) + self.assertEqual(response.status_code, 200) response = self.client.get(save_request_url) - self.assertEquals(response.status_code, 200) - self.assertEquals(response.data[0]['save_request_status'], - SAVE_REQUEST_ACCEPTED) - self.assertEquals(response.data[0]['save_task_status'], - SAVE_TASK_NOT_YET_SCHEDULED) + self.assertEqual(response.status_code, 200) + self.assertEqual(response.data[0]['save_request_status'], + SAVE_REQUEST_ACCEPTED) + self.assertEqual(response.data[0]['save_task_status'], + SAVE_TASK_NOT_YET_SCHEDULED) def test_reject_pending_save_request(self): origin_type = 'git' origin_url = 'https://wikipedia.com' save_request_url = reverse('api-save-origin', kwargs={'origin_type': origin_type, 'origin_url': origin_url}) response = self.client.post(save_request_url, data={}, content_type='application/x-www-form-urlencoded') # noqa - self.assertEquals(response.status_code, 200) - self.assertEquals(response.data['save_request_status'], - SAVE_REQUEST_PENDING) + self.assertEqual(response.status_code, 200) + self.assertEqual(response.data['save_request_status'], + SAVE_REQUEST_PENDING) reject_request_url = reverse('admin-origin-save-request-reject', kwargs={'origin_type': origin_type, 'origin_url': origin_url}) self.check_not_login(reject_request_url) self.client.login(username=_user_name, password=_user_password) response = self.client.post(reject_request_url) - self.assertEquals(response.status_code, 200) + self.assertEqual(response.status_code, 200) response = self.client.get(save_request_url) - self.assertEquals(response.status_code, 200) - self.assertEquals(response.data[0]['save_request_status'], - SAVE_REQUEST_REJECTED) + self.assertEqual(response.status_code, 200) + self.assertEqual(response.data[0]['save_request_status'], + SAVE_REQUEST_REJECTED) diff --git a/swh/web/tests/api/test_apiresponse.py b/swh/web/tests/api/test_apiresponse.py index bb803fcb3..d73f2d34e 100644 --- a/swh/web/tests/api/test_apiresponse.py +++ b/swh/web/tests/api/test_apiresponse.py @@ -1,169 +1,169 @@ # Copyright (C) 2015-2018 The Software Heritage developers # See the AUTHORS file at the top-level directory of this distribution # License: GNU Affero General Public License version 3, or any later version # See top-level LICENSE file for more information import json from rest_framework.test import APIRequestFactory from unittest.mock import patch from swh.web.api.apiresponse import ( compute_link_header, transform, make_api_response, filter_by_fields ) from swh.web.tests.testcase import SWHWebTestCase api_request_factory = APIRequestFactory() class SWHComputeLinkHeaderTest(SWHWebTestCase): def test_compute_link_header(self): rv = { 'headers': {'link-next': 'foo', 'link-prev': 'bar'}, 'results': [1, 2, 3] } options = {} # when headers = compute_link_header( rv, options) - self.assertEquals(headers, { + self.assertEqual(headers, { 'Link': '; rel="next",; rel="previous"', }) def test_compute_link_header_nothing_changed(self): rv = {} options = {} # when headers = compute_link_header( rv, options) - self.assertEquals(headers, {}) + self.assertEqual(headers, {}) def test_compute_link_header_nothing_changed_2(self): rv = {'headers': {}} options = {} # when headers = compute_link_header( rv, options) - self.assertEquals(headers, {}) + self.assertEqual(headers, {}) class SWHTransformProcessorTest(SWHWebTestCase): def test_transform_only_return_results_1(self): rv = {'results': {'some-key': 'some-value'}} - self.assertEquals(transform(rv), {'some-key': 'some-value'}) + self.assertEqual(transform(rv), {'some-key': 'some-value'}) def test_transform_only_return_results_2(self): rv = {'headers': {'something': 'do changes'}, 'results': {'some-key': 'some-value'}} - self.assertEquals(transform(rv), {'some-key': 'some-value'}) + self.assertEqual(transform(rv), {'some-key': 'some-value'}) def test_transform_do_remove_headers(self): rv = {'headers': {'something': 'do changes'}, 'some-key': 'some-value'} - self.assertEquals(transform(rv), {'some-key': 'some-value'}) + self.assertEqual(transform(rv), {'some-key': 'some-value'}) def test_transform_do_nothing(self): rv = {'some-key': 'some-value'} - self.assertEquals(transform(rv), {'some-key': 'some-value'}) + self.assertEqual(transform(rv), {'some-key': 'some-value'}) class RendererTestCase(SWHWebTestCase): @patch('swh.web.api.apiresponse.json') @patch('swh.web.api.apiresponse.filter_by_fields') @patch('swh.web.api.apiresponse.shorten_path') def test_swh_multi_response_mimetype(self, mock_shorten_path, mock_filter, mock_json): # given data = { 'data': [12, 34], 'id': 'adc83b19e793491b1c6ea0fd8b46cd9f32e592fc' } mock_filter.return_value = data mock_shorten_path.return_value = 'my_short_path' accepted_response_formats = {'html': 'text/html', 'yaml': 'application/yaml', 'json': 'application/json'} for format in accepted_response_formats: request = api_request_factory.get('/api/test/path/') mime_type = accepted_response_formats[format] setattr(request, 'accepted_media_type', mime_type) if mime_type == 'text/html': expected_data = { 'response_data': json.dumps(data), 'request': { 'path': request.path, 'method': request.method, 'absolute_uri': request.build_absolute_uri() }, 'headers_data': {}, 'heading': 'my_short_path', 'status_code': 200 } mock_json.dumps.return_value = json.dumps(data) else: expected_data = data # when rv = make_api_response(request, data) # then mock_filter.assert_called_with(request, data) self.assertEqual(rv.data, expected_data) self.assertEqual(rv.status_code, 200) if mime_type == 'text/html': self.assertEqual(rv.template_name, 'api/apidoc.html') def test_swh_filter_renderer_do_nothing(self): # given input_data = {'a': 'some-data'} request = api_request_factory.get('/api/test/path/', data={}) setattr(request, 'query_params', request.GET) # when actual_data = filter_by_fields(request, input_data) # then - self.assertEquals(actual_data, input_data) + self.assertEqual(actual_data, input_data) @patch('swh.web.api.apiresponse.utils.filter_field_keys') def test_swh_filter_renderer_do_filter(self, mock_ffk): # given mock_ffk.return_value = {'a': 'some-data'} request = api_request_factory.get('/api/test/path/', data={'fields': 'a,c'}) setattr(request, 'query_params', request.GET) input_data = {'a': 'some-data', 'b': 'some-other-data'} # when actual_data = filter_by_fields(request, input_data) # then - self.assertEquals(actual_data, {'a': 'some-data'}) + self.assertEqual(actual_data, {'a': 'some-data'}) mock_ffk.assert_called_once_with(input_data, {'a', 'c'}) diff --git a/swh/web/tests/api/views/test_content.py b/swh/web/tests/api/views/test_content.py index d6fc8a204..fa738f0eb 100644 --- a/swh/web/tests/api/views/test_content.py +++ b/swh/web/tests/api/views/test_content.py @@ -1,705 +1,705 @@ # Copyright (C) 2015-2018 The Software Heritage developers # See the AUTHORS file at the top-level directory of this distribution # License: GNU Affero General Public License version 3, or any later version # See top-level LICENSE file for more information from rest_framework.test import APITestCase from unittest.mock import patch, MagicMock from swh.web.tests.testcase import SWHWebTestCase class ContentApiTestCase(SWHWebTestCase, APITestCase): @patch('swh.web.api.views.content.service') def test_api_content_filetype(self, mock_service): stub_filetype = { 'accepted_media_type': 'application/xml', 'encoding': 'ascii', 'id': '34571b8614fcd89ccd17ca2b1d9e66c5b00a6d03', } mock_service.lookup_content_filetype.return_value = stub_filetype # when rv = self.client.get( '/api/1/content/' 'sha1_git:b04caf10e9535160d90e874b45aa426de762f19f/filetype/') # then - self.assertEquals(rv.status_code, 200) - self.assertEquals(rv['Content-Type'], 'application/json') - self.assertEquals(rv.data, { + self.assertEqual(rv.status_code, 200) + self.assertEqual(rv['Content-Type'], 'application/json') + self.assertEqual(rv.data, { 'accepted_media_type': 'application/xml', 'encoding': 'ascii', 'id': '34571b8614fcd89ccd17ca2b1d9e66c5b00a6d03', 'content_url': '/api/1/content/' 'sha1:34571b8614fcd89ccd17ca2b1d9e66c5b00a6d03/', }) mock_service.lookup_content_filetype.assert_called_once_with( 'sha1_git:b04caf10e9535160d90e874b45aa426de762f19f') @patch('swh.web.api.views.content.service') def test_api_content_filetype_sha_not_found(self, mock_service): # given mock_service.lookup_content_filetype.return_value = None # when rv = self.client.get( '/api/1/content/sha1:40e71b8614fcd89ccd17ca2b1d9e66c5b00a6d03/' 'filetype/') # then - self.assertEquals(rv.status_code, 404) - self.assertEquals(rv['Content-Type'], 'application/json') - self.assertEquals(rv.data, { + self.assertEqual(rv.status_code, 404) + self.assertEqual(rv['Content-Type'], 'application/json') + self.assertEqual(rv.data, { 'exception': 'NotFoundExc', 'reason': 'No filetype information found for content ' 'sha1:40e71b8614fcd89ccd17ca2b1d9e66c5b00a6d03.' }) mock_service.lookup_content_filetype.assert_called_once_with( 'sha1:40e71b8614fcd89ccd17ca2b1d9e66c5b00a6d03') @patch('swh.web.api.views.content.service') def test_api_content_language(self, mock_service): stub_language = { 'lang': 'lisp', 'id': '34571b8614fcd89ccd17ca2b1d9e66c5b00a6d03', } mock_service.lookup_content_language.return_value = stub_language # when rv = self.client.get( '/api/1/content/' 'sha1_git:b04caf10e9535160d90e874b45aa426de762f19f/language/') # then - self.assertEquals(rv.status_code, 200) - self.assertEquals(rv['Content-Type'], 'application/json') - self.assertEquals(rv.data, { + self.assertEqual(rv.status_code, 200) + self.assertEqual(rv['Content-Type'], 'application/json') + self.assertEqual(rv.data, { 'lang': 'lisp', 'id': '34571b8614fcd89ccd17ca2b1d9e66c5b00a6d03', 'content_url': '/api/1/content/' 'sha1:34571b8614fcd89ccd17ca2b1d9e66c5b00a6d03/', }) mock_service.lookup_content_language.assert_called_once_with( 'sha1_git:b04caf10e9535160d90e874b45aa426de762f19f') @patch('swh.web.api.views.content.service') def test_api_content_language_sha_not_found(self, mock_service): # given mock_service.lookup_content_language.return_value = None # when rv = self.client.get( '/api/1/content/sha1:40e71b8614fcd89ccd17ca2b1d9e66c5b00a6d03' '/language/') # then - self.assertEquals(rv.status_code, 404) - self.assertEquals(rv['Content-Type'], 'application/json') - self.assertEquals(rv.data, { + self.assertEqual(rv.status_code, 404) + self.assertEqual(rv['Content-Type'], 'application/json') + self.assertEqual(rv.data, { 'exception': 'NotFoundExc', 'reason': 'No language information found for content ' 'sha1:40e71b8614fcd89ccd17ca2b1d9e66c5b00a6d03.' }) mock_service.lookup_content_language.assert_called_once_with( 'sha1:40e71b8614fcd89ccd17ca2b1d9e66c5b00a6d03') @patch('swh.web.api.views.content.service') def test_api_content_symbol(self, mock_service): stub_ctag = [{ 'sha1': '34571b8614fcd89ccd17ca2b1d9e66c5b00a6d03', 'name': 'foobar', 'kind': 'Haskell', 'line': 10, }] mock_service.lookup_expression.return_value = stub_ctag # when rv = self.client.get('/api/1/content/symbol/foo/?last_sha1=sha1') # then - self.assertEquals(rv.status_code, 200) - self.assertEquals(rv['Content-Type'], 'application/json') - self.assertEquals(rv.data, [{ + self.assertEqual(rv.status_code, 200) + self.assertEqual(rv['Content-Type'], 'application/json') + self.assertEqual(rv.data, [{ 'sha1': '34571b8614fcd89ccd17ca2b1d9e66c5b00a6d03', 'name': 'foobar', 'kind': 'Haskell', 'line': 10, 'content_url': '/api/1/content/' 'sha1:34571b8614fcd89ccd17ca2b1d9e66c5b00a6d03/', 'data_url': '/api/1/content/' 'sha1:34571b8614fcd89ccd17ca2b1d9e66c5b00a6d03/raw/', 'license_url': '/api/1/content/' 'sha1:34571b8614fcd89ccd17ca2b1d9e66c5b00a6d03/license/', 'language_url': '/api/1/content/' 'sha1:34571b8614fcd89ccd17ca2b1d9e66c5b00a6d03/language/', 'filetype_url': '/api/1/content/' 'sha1:34571b8614fcd89ccd17ca2b1d9e66c5b00a6d03/filetype/', }]) self.assertFalse('Link' in rv) mock_service.lookup_expression.assert_called_once_with( 'foo', 'sha1', 10) @patch('swh.web.api.views.content.service') def test_api_content_symbol_2(self, mock_service): stub_ctag = [{ 'sha1': '12371b8614fcd89ccd17ca2b1d9e66c5b00a6456', 'name': 'foobar', 'kind': 'Haskell', 'line': 10, }, { 'sha1': '34571b8614fcd89ccd17ca2b1d9e66c5b00a6678', 'name': 'foo', 'kind': 'Lisp', 'line': 10, }] mock_service.lookup_expression.return_value = stub_ctag # when rv = self.client.get( '/api/1/content/symbol/foo/?last_sha1=prev-sha1&per_page=2') # then - self.assertEquals(rv.status_code, 200) - self.assertEquals(rv['Content-Type'], 'application/json') - self.assertEquals(rv.data, stub_ctag) + self.assertEqual(rv.status_code, 200) + self.assertEqual(rv['Content-Type'], 'application/json') + self.assertEqual(rv.data, stub_ctag) self.assertTrue( rv['Link'] == '; rel="next"' or # noqa rv['Link'] == '; rel="next"' # noqa ) mock_service.lookup_expression.assert_called_once_with( 'foo', 'prev-sha1', 2) @patch('swh.web.api.views.content.service') def test_api_content_symbol_3(self, mock_service): stub_ctag = [{ 'sha1': '67891b8614fcd89ccd17ca2b1d9e66c5b00a6d03', 'name': 'foo', 'kind': 'variable', 'line': 100, }] mock_service.lookup_expression.return_value = stub_ctag # when rv = self.client.get('/api/1/content/symbol/foo/') # then - self.assertEquals(rv.status_code, 200) - self.assertEquals(rv['Content-Type'], 'application/json') - self.assertEquals(rv.data, [{ + self.assertEqual(rv.status_code, 200) + self.assertEqual(rv['Content-Type'], 'application/json') + self.assertEqual(rv.data, [{ 'sha1': '67891b8614fcd89ccd17ca2b1d9e66c5b00a6d03', 'name': 'foo', 'kind': 'variable', 'line': 100, 'content_url': '/api/1/content/' 'sha1:67891b8614fcd89ccd17ca2b1d9e66c5b00a6d03/', 'data_url': '/api/1/content/' 'sha1:67891b8614fcd89ccd17ca2b1d9e66c5b00a6d03/raw/', 'license_url': '/api/1/content/' 'sha1:67891b8614fcd89ccd17ca2b1d9e66c5b00a6d03/license/', 'language_url': '/api/1/content/' 'sha1:67891b8614fcd89ccd17ca2b1d9e66c5b00a6d03/language/', 'filetype_url': '/api/1/content/' 'sha1:67891b8614fcd89ccd17ca2b1d9e66c5b00a6d03/filetype/', }]) self.assertFalse(rv.has_header('Link')) mock_service.lookup_expression.assert_called_once_with('foo', None, 10) @patch('swh.web.api.views.content.service') def test_api_content_symbol_not_found(self, mock_service): # given mock_service.lookup_expression.return_value = [] # when rv = self.client.get('/api/1/content/symbol/bar/?last_sha1=hash') # then - self.assertEquals(rv.status_code, 404) - self.assertEquals(rv['Content-Type'], 'application/json') - self.assertEquals(rv.data, { + self.assertEqual(rv.status_code, 404) + self.assertEqual(rv['Content-Type'], 'application/json') + self.assertEqual(rv.data, { 'exception': 'NotFoundExc', 'reason': 'No indexed raw content match expression \'bar\'.' }) self.assertFalse('Link' in rv) mock_service.lookup_expression.assert_called_once_with( 'bar', 'hash', 10) @patch('swh.web.api.views.content.service') def test_api_content_ctags(self, mock_service): stub_ctags = { 'id': '34571b8614fcd89ccd17ca2b1d9e66c5b00a6d03', 'ctags': [] } mock_service.lookup_content_ctags.return_value = stub_ctags # when rv = self.client.get( '/api/1/content/' 'sha1_git:b04caf10e9535160d90e874b45aa426de762f19f/ctags/') # then - self.assertEquals(rv.status_code, 200) - self.assertEquals(rv['Content-Type'], 'application/json') - self.assertEquals(rv.data, { + self.assertEqual(rv.status_code, 200) + self.assertEqual(rv['Content-Type'], 'application/json') + self.assertEqual(rv.data, { 'id': '34571b8614fcd89ccd17ca2b1d9e66c5b00a6d03', 'ctags': [], 'content_url': '/api/1/content/' 'sha1:34571b8614fcd89ccd17ca2b1d9e66c5b00a6d03/', }) mock_service.lookup_content_ctags.assert_called_once_with( 'sha1_git:b04caf10e9535160d90e874b45aa426de762f19f') @patch('swh.web.api.views.content.service') def test_api_content_license(self, mock_service): stub_license = { 'licenses': ['No_license_found', 'Apache-2.0'], 'id': '34571b8614fcd89ccd17ca2b1d9e66c5b00a6d03', 'tool_name': 'nomos', } mock_service.lookup_content_license.return_value = stub_license # when rv = self.client.get( '/api/1/content/' 'sha1_git:b04caf10e9535160d90e874b45aa426de762f19f/license/') # then - self.assertEquals(rv.status_code, 200) - self.assertEquals(rv['Content-Type'], 'application/json') - self.assertEquals(rv.data, { + self.assertEqual(rv.status_code, 200) + self.assertEqual(rv['Content-Type'], 'application/json') + self.assertEqual(rv.data, { 'licenses': ['No_license_found', 'Apache-2.0'], 'id': '34571b8614fcd89ccd17ca2b1d9e66c5b00a6d03', 'tool_name': 'nomos', 'content_url': '/api/1/content/' 'sha1:34571b8614fcd89ccd17ca2b1d9e66c5b00a6d03/', }) mock_service.lookup_content_license.assert_called_once_with( 'sha1_git:b04caf10e9535160d90e874b45aa426de762f19f') @patch('swh.web.api.views.content.service') def test_api_content_license_sha_not_found(self, mock_service): # given mock_service.lookup_content_license.return_value = None # when rv = self.client.get( '/api/1/content/sha1:40e71b8614fcd89ccd17ca2b1d9e66c5b00a6d03/' 'license/') # then - self.assertEquals(rv.status_code, 404) - self.assertEquals(rv['Content-Type'], 'application/json') - self.assertEquals(rv.data, { + self.assertEqual(rv.status_code, 404) + self.assertEqual(rv['Content-Type'], 'application/json') + self.assertEqual(rv.data, { 'exception': 'NotFoundExc', 'reason': 'No license information found for content ' 'sha1:40e71b8614fcd89ccd17ca2b1d9e66c5b00a6d03.' }) mock_service.lookup_content_license.assert_called_once_with( 'sha1:40e71b8614fcd89ccd17ca2b1d9e66c5b00a6d03') @patch('swh.web.api.views.content.service') def test_api_content_provenance(self, mock_service): stub_provenances = [{ 'origin': 1, 'visit': 2, 'revision': 'b04caf10e9535160d90e874b45aa426de762f19f', 'content': '34571b8614fcd89ccd17ca2b1d9e66c5b00a6d03', 'path': 'octavio-3.4.0/octave.html/doc_002dS_005fISREG.html' }] mock_service.lookup_content_provenance.return_value = stub_provenances # when rv = self.client.get( '/api/1/content/' 'sha1_git:34571b8614fcd89ccd17ca2b1d9e66c5b00a6d03/provenance/') # then - self.assertEquals(rv.status_code, 200) - self.assertEquals(rv['Content-Type'], 'application/json') - self.assertEquals(rv.data, [{ + self.assertEqual(rv.status_code, 200) + self.assertEqual(rv['Content-Type'], 'application/json') + self.assertEqual(rv.data, [{ 'origin': 1, 'visit': 2, 'origin_url': '/api/1/origin/1/', 'origin_visits_url': '/api/1/origin/1/visits/', 'origin_visit_url': '/api/1/origin/1/visit/2/', 'revision': 'b04caf10e9535160d90e874b45aa426de762f19f', 'revision_url': '/api/1/revision/' 'b04caf10e9535160d90e874b45aa426de762f19f/', 'content': '34571b8614fcd89ccd17ca2b1d9e66c5b00a6d03', 'content_url': '/api/1/content/' 'sha1_git:34571b8614fcd89ccd17ca2b1d9e66c5b00a6d03/', 'path': 'octavio-3.4.0/octave.html/doc_002dS_005fISREG.html' }]) mock_service.lookup_content_provenance.assert_called_once_with( 'sha1_git:34571b8614fcd89ccd17ca2b1d9e66c5b00a6d03') @patch('swh.web.api.views.content.service') def test_api_content_provenance_sha_not_found(self, mock_service): # given mock_service.lookup_content_provenance.return_value = None # when rv = self.client.get( '/api/1/content/sha1:40e71b8614fcd89ccd17ca2b1d9e66c5b00a6d03/' 'provenance/') # then - self.assertEquals(rv.status_code, 404) - self.assertEquals(rv['Content-Type'], 'application/json') - self.assertEquals(rv.data, { + self.assertEqual(rv.status_code, 404) + self.assertEqual(rv['Content-Type'], 'application/json') + self.assertEqual(rv.data, { 'exception': 'NotFoundExc', 'reason': 'Content with sha1:40e71b8614fcd89ccd17ca2b1d9e6' '6c5b00a6d03 not found.' }) mock_service.lookup_content_provenance.assert_called_once_with( 'sha1:40e71b8614fcd89ccd17ca2b1d9e66c5b00a6d03') @patch('swh.web.api.views.content.service') def test_api_content_metadata(self, mock_service): # given mock_service.lookup_content.return_value = { 'checksums': { 'blake2s256': '685395c5dc57cada459364f0946d3dd45bad5f' 'cbabc1048edb44380f1d31d0aa', 'sha1': '40e71b8614fcd89ccd17ca2b1d9e66c5b00a6d03', 'sha1_git': 'b4e8f472ffcb01a03875b26e462eb568739f6882', 'sha256': '83c0e67cc80f60caf1fcbec2d84b0ccd7968b3be47' '35637006560cde9b067a4f', }, 'length': 17, 'status': 'visible' } # when rv = self.client.get( '/api/1/content/sha1:40e71b8614fcd89ccd17ca2b1d9e66c5b00a6d03/') - self.assertEquals(rv.status_code, 200) - self.assertEquals(rv['Content-Type'], 'application/json') - self.assertEquals(rv.data, { + self.assertEqual(rv.status_code, 200) + self.assertEqual(rv['Content-Type'], 'application/json') + self.assertEqual(rv.data, { 'checksums': { 'blake2s256': '685395c5dc57cada459364f0946d3dd45bad5f' 'cbabc1048edb44380f1d31d0aa', 'sha1': '40e71b8614fcd89ccd17ca2b1d9e66c5b00a6d03', 'sha1_git': 'b4e8f472ffcb01a03875b26e462eb568739f6882', 'sha256': '83c0e67cc80f60caf1fcbec2d84b0ccd7968b3be47' '35637006560cde9b067a4f', }, 'data_url': '/api/1/content/' 'sha1:40e71b8614fcd89ccd17ca2b1d9e66c5b00a6d03/raw/', 'filetype_url': '/api/1/content/' 'sha1:40e71b8614fcd89ccd17ca2b1d9e66c5b00a6d03/filetype/', 'language_url': '/api/1/content/' 'sha1:40e71b8614fcd89ccd17ca2b1d9e66c5b00a6d03/language/', 'license_url': '/api/1/content/' 'sha1:40e71b8614fcd89ccd17ca2b1d9e66c5b00a6d03/license/', 'length': 17, 'status': 'visible' }) mock_service.lookup_content.assert_called_once_with( 'sha1:40e71b8614fcd89ccd17ca2b1d9e66c5b00a6d03') @patch('swh.web.api.views.content.service') def test_api_content_not_found_as_json(self, mock_service): # given mock_service.lookup_content.return_value = None mock_service.lookup_content_provenance = MagicMock() # when rv = self.client.get( '/api/1/content/sha256:83c0e67cc80f60caf1fcbec2d84b0ccd7968b3' 'be4735637006560c/') - self.assertEquals(rv.status_code, 404) - self.assertEquals(rv['Content-Type'], 'application/json') - self.assertEquals(rv.data, { + self.assertEqual(rv.status_code, 404) + self.assertEqual(rv['Content-Type'], 'application/json') + self.assertEqual(rv.data, { 'exception': 'NotFoundExc', 'reason': 'Content with sha256:83c0e67cc80f60caf1fcbec2d84b0ccd79' '68b3be4735637006560c not found.' }) mock_service.lookup_content.assert_called_once_with( 'sha256:83c0e67cc80f60caf1fcbec2d84b0ccd7968b3' 'be4735637006560c') mock_service.lookup_content_provenance.called = False @patch('swh.web.api.views.content.service') def test_api_content_not_found_as_yaml(self, mock_service): # given mock_service.lookup_content.return_value = None mock_service.lookup_content_provenance = MagicMock() # when rv = self.client.get( '/api/1/content/sha256:83c0e67cc80f60caf1fcbec2d84b0ccd7968b3' 'be4735637006560c/', HTTP_ACCEPT='application/yaml') - self.assertEquals(rv.status_code, 404) + self.assertEqual(rv.status_code, 404) self.assertTrue('application/yaml' in rv['Content-Type']) - self.assertEquals(rv.data, { + self.assertEqual(rv.data, { 'exception': 'NotFoundExc', 'reason': 'Content with sha256:83c0e67cc80f60caf1fcbec2d84b0ccd79' '68b3be4735637006560c not found.' }) mock_service.lookup_content.assert_called_once_with( 'sha256:83c0e67cc80f60caf1fcbec2d84b0ccd7968b3' 'be4735637006560c') mock_service.lookup_content_provenance.called = False @patch('swh.web.api.views.content.service') def test_api_content_raw_ko_not_found(self, mock_service): # given mock_service.lookup_content_raw.return_value = None # when rv = self.client.get( '/api/1/content/sha1:40e71b8614fcd89ccd17ca2b1d9e66c5b00a6d03' '/raw/') - self.assertEquals(rv.status_code, 404) - self.assertEquals(rv['Content-Type'], 'application/json') - self.assertEquals(rv.data, { + self.assertEqual(rv.status_code, 404) + self.assertEqual(rv['Content-Type'], 'application/json') + self.assertEqual(rv.data, { 'exception': 'NotFoundExc', 'reason': 'Content sha1:40e71b8614fcd89ccd17ca2b1d9e6' '6c5b00a6d03 is not found.' }) mock_service.lookup_content_raw.assert_called_once_with( 'sha1:40e71b8614fcd89ccd17ca2b1d9e66c5b00a6d03') @patch('swh.web.api.views.content.service') def test_api_content_raw_text(self, mock_service): # given stub_content = {'data': b'some content data'} mock_service.lookup_content_raw.return_value = stub_content mock_service.lookup_content_filetype.return_value = { 'mimetype': 'text/html' } # when rv = self.client.get( '/api/1/content/sha1:40e71b8614fcd89ccd17ca2b1d9e66c5b00a6d03' '/raw/') - self.assertEquals(rv.status_code, 200) - self.assertEquals(rv['Content-Type'], 'application/octet-stream') - self.assertEquals( + self.assertEqual(rv.status_code, 200) + self.assertEqual(rv['Content-Type'], 'application/octet-stream') + self.assertEqual( rv['Content-disposition'], 'attachment; filename=content_sha1_' '40e71b8614fcd89ccd17ca2b1d9e66c5b00a6d03_raw') - self.assertEquals( + self.assertEqual( rv['Content-Type'], 'application/octet-stream') - self.assertEquals(rv.content, stub_content['data']) + self.assertEqual(rv.content, stub_content['data']) mock_service.lookup_content_raw.assert_called_once_with( 'sha1:40e71b8614fcd89ccd17ca2b1d9e66c5b00a6d03') mock_service.lookup_content_filetype.assert_called_once_with( 'sha1:40e71b8614fcd89ccd17ca2b1d9e66c5b00a6d03') @patch('swh.web.api.views.content.service') def test_api_content_raw_text_with_filename(self, mock_service): # given stub_content = {'data': b'some content data'} mock_service.lookup_content_raw.return_value = stub_content mock_service.lookup_content_filetype.return_value = { 'mimetype': 'text/html' } # when rv = self.client.get( '/api/1/content/sha1:40e71b8614fcd89ccd17ca2b1d9e66c5b00a6d03' '/raw/?filename=filename.txt') - self.assertEquals(rv.status_code, 200) - self.assertEquals(rv['Content-Type'], 'application/octet-stream') - self.assertEquals( + self.assertEqual(rv.status_code, 200) + self.assertEqual(rv['Content-Type'], 'application/octet-stream') + self.assertEqual( rv['Content-disposition'], 'attachment; filename=filename.txt') - self.assertEquals( + self.assertEqual( rv['Content-Type'], 'application/octet-stream') - self.assertEquals(rv.content, stub_content['data']) + self.assertEqual(rv.content, stub_content['data']) mock_service.lookup_content_raw.assert_called_once_with( 'sha1:40e71b8614fcd89ccd17ca2b1d9e66c5b00a6d03') mock_service.lookup_content_filetype.assert_called_once_with( 'sha1:40e71b8614fcd89ccd17ca2b1d9e66c5b00a6d03') @patch('swh.web.api.views.content.service') def test_api_content_raw_no_accepted_media_type_text_is_not_available_for_download( # noqa self, mock_service): # given stub_content = {'data': b'some content data'} mock_service.lookup_content_raw.return_value = stub_content mock_service.lookup_content_filetype.return_value = { 'mimetype': 'application/octet-stream' } # when rv = self.client.get( '/api/1/content/sha1:40e71b8614fcd89ccd17ca2b1d9e66c5b00a6d03' '/raw/') - self.assertEquals(rv.status_code, 403) - self.assertEquals(rv['Content-Type'], 'application/json') - self.assertEquals(rv.data, { + self.assertEqual(rv.status_code, 403) + self.assertEqual(rv['Content-Type'], 'application/json') + self.assertEqual(rv.data, { 'exception': 'ForbiddenExc', 'reason': 'Only textual content is available for download. ' 'Actual content mimetype is application/octet-stream.' }) mock_service.lookup_content_raw.assert_called_once_with( 'sha1:40e71b8614fcd89ccd17ca2b1d9e66c5b00a6d03') mock_service.lookup_content_filetype.assert_called_once_with( 'sha1:40e71b8614fcd89ccd17ca2b1d9e66c5b00a6d03') @patch('swh.web.api.views.content.service') def test_api_content_raw_no_accepted_media_type_found_so_not_available_for_download( # noqa self, mock_service): # given stub_content = {'data': b'some content data'} mock_service.lookup_content_raw.return_value = stub_content mock_service.lookup_content_filetype.return_value = None # when rv = self.client.get( '/api/1/content/sha1:40e71b8614fcd89ccd17ca2b1d9e66c5b00a6d03' '/raw/') - self.assertEquals(rv.status_code, 404) - self.assertEquals(rv['Content-Type'], 'application/json') - self.assertEquals(rv.data, { + self.assertEqual(rv.status_code, 404) + self.assertEqual(rv['Content-Type'], 'application/json') + self.assertEqual(rv.data, { 'exception': 'NotFoundExc', 'reason': 'Content sha1:40e71b8614fcd89ccd17ca2b1d9e66c5b00a6d03 ' 'is not available for download.' }) mock_service.lookup_content_raw.assert_called_once_with( 'sha1:40e71b8614fcd89ccd17ca2b1d9e66c5b00a6d03') mock_service.lookup_content_filetype.assert_called_once_with( 'sha1:40e71b8614fcd89ccd17ca2b1d9e66c5b00a6d03') @patch('swh.web.api.views.content.service') def test_api_check_content_known(self, mock_service): # given mock_service.lookup_multiple_hashes.return_value = [ {'found': True, 'filename': None, 'sha1': 'sha1:blah'} ] expected_result = { 'search_stats': {'nbfiles': 1, 'pct': 100}, 'search_res': [{'sha1': 'sha1:blah', 'found': True}] } # when rv = self.client.get('/api/1/content/known/sha1:blah/') - self.assertEquals(rv.status_code, 200) - self.assertEquals(rv['Content-Type'], 'application/json') - self.assertEquals(rv.data, expected_result) + self.assertEqual(rv.status_code, 200) + self.assertEqual(rv['Content-Type'], 'application/json') + self.assertEqual(rv.data, expected_result) mock_service.lookup_multiple_hashes.assert_called_once_with( [{'filename': None, 'sha1': 'sha1:blah'}]) @patch('swh.web.api.views.content.service') def test_api_check_content_known_as_yaml(self, mock_service): # given mock_service.lookup_multiple_hashes.return_value = [ {'found': True, 'filename': None, 'sha1': 'sha1:halb'}, {'found': False, 'filename': None, 'sha1': 'sha1_git:hello'} ] expected_result = { 'search_stats': {'nbfiles': 2, 'pct': 50}, 'search_res': [{'sha1': 'sha1:halb', 'found': True}, {'sha1': 'sha1_git:hello', 'found': False}] } # when rv = self.client.get('/api/1/content/known/sha1:halb,sha1_git:hello/', HTTP_ACCEPT='application/yaml') - self.assertEquals(rv.status_code, 200) + self.assertEqual(rv.status_code, 200) self.assertTrue('application/yaml' in rv['Content-Type']) - self.assertEquals(rv.data, expected_result) + self.assertEqual(rv.data, expected_result) mock_service.lookup_multiple_hashes.assert_called_once_with( [{'filename': None, 'sha1': 'sha1:halb'}, {'filename': None, 'sha1': 'sha1_git:hello'}]) @patch('swh.web.api.views.content.service') def test_api_check_content_known_post_as_yaml(self, mock_service): # given stub_result = [{'sha1': '7e62b1fe10c88a3eddbba930b156bee2956b2435', 'found': True}, {'filename': 'filepath', 'sha1': '8e62b1fe10c88a3eddbba930b156bee2956b2435', 'found': True}, {'filename': 'filename', 'sha1': '64025b5d1520c615061842a6ce6a456cad962a3f', 'found': False}] mock_service.lookup_multiple_hashes.return_value = stub_result expected_result = { 'search_stats': {'nbfiles': 3, 'pct': 2/3 * 100}, 'search_res': stub_result } # when rv = self.client.post( '/api/1/content/known/search/', data=dict( q='7e62b1fe10c88a3eddbba930b156bee2956b2435', filepath='8e62b1fe10c88a3eddbba930b156bee2956b2435', filename='64025b5d1520c615061842a6ce6a456cad962a3f'), HTTP_ACCEPT='application/yaml' ) - self.assertEquals(rv.status_code, 200) + self.assertEqual(rv.status_code, 200) self.assertTrue('application/yaml' in rv['Content-Type']) - self.assertEquals(rv.data, expected_result) + self.assertEqual(rv.data, expected_result) @patch('swh.web.api.views.content.service') def test_api_check_content_known_not_found(self, mock_service): # given stub_result = [{'sha1': 'sha1:halb', 'found': False}] mock_service.lookup_multiple_hashes.return_value = stub_result expected_result = { 'search_stats': {'nbfiles': 1, 'pct': 0.0}, 'search_res': stub_result } # when rv = self.client.get('/api/1/content/known/sha1:halb/') - self.assertEquals(rv.status_code, 200) - self.assertEquals(rv['Content-Type'], 'application/json') - self.assertEquals(rv.data, expected_result) + self.assertEqual(rv.status_code, 200) + self.assertEqual(rv['Content-Type'], 'application/json') + self.assertEqual(rv.data, expected_result) mock_service.lookup_multiple_hashes.assert_called_once_with( [{'filename': None, 'sha1': 'sha1:halb'}]) diff --git a/swh/web/tests/api/views/test_directory.py b/swh/web/tests/api/views/test_directory.py index c1966f4d7..8847f6619 100644 --- a/swh/web/tests/api/views/test_directory.py +++ b/swh/web/tests/api/views/test_directory.py @@ -1,122 +1,122 @@ # Copyright (C) 2015-2018 The Software Heritage developers # See the AUTHORS file at the top-level directory of this distribution # License: GNU Affero General Public License version 3, or any later version # See top-level LICENSE file for more information from rest_framework.test import APITestCase from unittest.mock import patch from swh.web.tests.testcase import SWHWebTestCase class DirectoryApiTestCase(SWHWebTestCase, APITestCase): @patch('swh.web.api.views.directory.service') def test_api_directory(self, mock_service): # given stub_directories = [ { 'sha1_git': '18d8be353ed3480476f032475e7c233eff7371d5', 'type': 'file', 'target': '4568be353ed3480476f032475e7c233eff737123', }, { 'sha1_git': '1d518d8be353ed3480476f032475e7c233eff737', 'type': 'dir', 'target': '8be353ed3480476f032475e7c233eff737123456', }] expected_directories = [ { 'sha1_git': '18d8be353ed3480476f032475e7c233eff7371d5', 'type': 'file', 'target': '4568be353ed3480476f032475e7c233eff737123', 'target_url': '/api/1/content/' 'sha1_git:4568be353ed3480476f032475e7c233eff737123/', }, { 'sha1_git': '1d518d8be353ed3480476f032475e7c233eff737', 'type': 'dir', 'target': '8be353ed3480476f032475e7c233eff737123456', 'target_url': '/api/1/directory/8be353ed3480476f032475e7c233eff737123456/', }] mock_service.lookup_directory.return_value = stub_directories # when rv = self.client.get('/api/1/directory/' '18d8be353ed3480476f032475e7c233eff7371d5/') # then - self.assertEquals(rv.status_code, 200) - self.assertEquals(rv['Content-Type'], 'application/json') - self.assertEquals(rv.data, expected_directories) + self.assertEqual(rv.status_code, 200) + self.assertEqual(rv['Content-Type'], 'application/json') + self.assertEqual(rv.data, expected_directories) mock_service.lookup_directory.assert_called_once_with( '18d8be353ed3480476f032475e7c233eff7371d5') @patch('swh.web.api.views.directory.service') def test_api_directory_not_found(self, mock_service): # given mock_service.lookup_directory.return_value = [] # when rv = self.client.get('/api/1/directory/' '66618d8be353ed3480476f032475e7c233eff737/') # then - self.assertEquals(rv.status_code, 404) - self.assertEquals(rv['Content-Type'], 'application/json') - self.assertEquals(rv.data, { + self.assertEqual(rv.status_code, 404) + self.assertEqual(rv['Content-Type'], 'application/json') + self.assertEqual(rv.data, { 'exception': 'NotFoundExc', 'reason': 'Directory with sha1_git ' '66618d8be353ed3480476f032475e7c233eff737 not found.'}) @patch('swh.web.api.views.directory.service') def test_api_directory_with_path_found(self, mock_service): # given expected_dir = { 'sha1_git': '18d8be353ed3480476f032475e7c233eff7371d5', 'type': 'file', 'name': 'bla', 'target': '4568be353ed3480476f032475e7c233eff737123', 'target_url': '/api/1/content/' 'sha1_git:4568be353ed3480476f032475e7c233eff737123/', } mock_service.lookup_directory_with_path.return_value = expected_dir # when rv = self.client.get('/api/1/directory/' '18d8be353ed3480476f032475e7c233eff7371d5/bla/') # then - self.assertEquals(rv.status_code, 200) - self.assertEquals(rv['Content-Type'], 'application/json') - self.assertEquals(rv.data, expected_dir) + self.assertEqual(rv.status_code, 200) + self.assertEqual(rv['Content-Type'], 'application/json') + self.assertEqual(rv.data, expected_dir) mock_service.lookup_directory_with_path.assert_called_once_with( '18d8be353ed3480476f032475e7c233eff7371d5', 'bla') @patch('swh.web.api.views.directory.service') def test_api_directory_with_path_not_found(self, mock_service): # given mock_service.lookup_directory_with_path.return_value = None path = 'some/path/to/dir/' # when rv = self.client.get(('/api/1/directory/' '66618d8be353ed3480476f032475e7c233eff737/%s') % path) path = path.strip('/') # Path stripped of lead/trail separators # then - self.assertEquals(rv.status_code, 404) - self.assertEquals(rv['Content-Type'], 'application/json') - self.assertEquals(rv.data, { + self.assertEqual(rv.status_code, 404) + self.assertEqual(rv['Content-Type'], 'application/json') + self.assertEqual(rv.data, { 'exception': 'NotFoundExc', 'reason': (('Entry with path %s relative to ' 'directory with sha1_git ' '66618d8be353ed3480476f032475e7c233eff737 not found.') % path)}) diff --git a/swh/web/tests/api/views/test_entity.py b/swh/web/tests/api/views/test_entity.py index 4d909efc0..1a6d35c21 100644 --- a/swh/web/tests/api/views/test_entity.py +++ b/swh/web/tests/api/views/test_entity.py @@ -1,91 +1,91 @@ # Copyright (C) 2015-2018 The Software Heritage developers # See the AUTHORS file at the top-level directory of this distribution # License: GNU Affero General Public License version 3, or any later version # See top-level LICENSE file for more information from rest_framework.test import APITestCase from unittest.mock import patch from swh.web.common.exc import BadInputExc from swh.web.tests.testcase import SWHWebTestCase class EntityApiTestCase(SWHWebTestCase, APITestCase): @patch('swh.web.api.views.entity.service') def test_api_lookup_entity_by_uuid_not_found(self, mock_service): # when mock_service.lookup_entity_by_uuid.return_value = [] # when rv = self.client.get('/api/1/entity/' '5f4d4c51-498a-4e28-88b3-b3e4e8396cba/') - self.assertEquals(rv.status_code, 404) - self.assertEquals(rv['Content-Type'], 'application/json') - self.assertEquals(rv.data, { + self.assertEqual(rv.status_code, 404) + self.assertEqual(rv['Content-Type'], 'application/json') + self.assertEqual(rv.data, { 'exception': 'NotFoundExc', 'reason': "Entity with uuid '5f4d4c51-498a-4e28-88b3-b3e4e8396cba' not " + "found."}) mock_service.lookup_entity_by_uuid.assert_called_once_with( '5f4d4c51-498a-4e28-88b3-b3e4e8396cba') @patch('swh.web.api.views.entity.service') def test_api_lookup_entity_by_uuid_bad_request(self, mock_service): # when mock_service.lookup_entity_by_uuid.side_effect = BadInputExc( 'bad input: uuid malformed!') # when rv = self.client.get('/api/1/entity/uuid malformed/') - self.assertEquals(rv.status_code, 400) - self.assertEquals(rv['Content-Type'], 'application/json') - self.assertEquals(rv.data, { + self.assertEqual(rv.status_code, 400) + self.assertEqual(rv['Content-Type'], 'application/json') + self.assertEqual(rv.data, { 'exception': 'BadInputExc', 'reason': 'bad input: uuid malformed!'}) mock_service.lookup_entity_by_uuid.assert_called_once_with( 'uuid malformed') @patch('swh.web.api.views.entity.service') def test_api_lookup_entity_by_uuid(self, mock_service): # when stub_entities = [ { 'uuid': '34bd6b1b-463f-43e5-a697-785107f598e4', 'parent': 'aee991a0-f8d7-4295-a201-d1ce2efc9fb2' }, { 'uuid': 'aee991a0-f8d7-4295-a201-d1ce2efc9fb2' } ] mock_service.lookup_entity_by_uuid.return_value = stub_entities expected_entities = [ { 'uuid': '34bd6b1b-463f-43e5-a697-785107f598e4', 'uuid_url': '/api/1/entity/34bd6b1b-463f-43e5-a697-' '785107f598e4/', 'parent': 'aee991a0-f8d7-4295-a201-d1ce2efc9fb2', 'parent_url': '/api/1/entity/aee991a0-f8d7-4295-a201-' 'd1ce2efc9fb2/' }, { 'uuid': 'aee991a0-f8d7-4295-a201-d1ce2efc9fb2', 'uuid_url': '/api/1/entity/aee991a0-f8d7-4295-a201-' 'd1ce2efc9fb2/' } ] # when rv = self.client.get('/api/1/entity' '/34bd6b1b-463f-43e5-a697-785107f598e4/') - self.assertEquals(rv.status_code, 200) - self.assertEquals(rv['Content-Type'], 'application/json') - self.assertEquals(rv.data, expected_entities) + self.assertEqual(rv.status_code, 200) + self.assertEqual(rv['Content-Type'], 'application/json') + self.assertEqual(rv.data, expected_entities) mock_service.lookup_entity_by_uuid.assert_called_once_with( '34bd6b1b-463f-43e5-a697-785107f598e4') diff --git a/swh/web/tests/api/views/test_identifiers.py b/swh/web/tests/api/views/test_identifiers.py index aa63cf853..e075c71c4 100644 --- a/swh/web/tests/api/views/test_identifiers.py +++ b/swh/web/tests/api/views/test_identifiers.py @@ -1,65 +1,65 @@ # Copyright (C) 2018 The Software Heritage developers # See the AUTHORS file at the top-level directory of this distribution # License: GNU Affero General Public License version 3, or any later version # See top-level LICENSE file for more information from rest_framework.test import APITestCase from unittest.mock import patch from swh.model.identifiers import REVISION from swh.web.common.utils import reverse from swh.web.common.exc import NotFoundExc from swh.web.tests.testcase import SWHWebTestCase class SwhIdsApiTestCase(SWHWebTestCase, APITestCase): @patch('swh.web.api.views.identifiers.service') def test_swh_id_resolve_success(self, mock_service): rev_id = '96db9023b881d7cd9f379b0c154650d6c108e9a3' origin = 'https://github.com/openssl/openssl' swh_id = 'swh:1:rev:%s;origin=%s' % (rev_id, origin) url = reverse('api-resolve-swh-pid', kwargs={'swh_id': swh_id}) mock_service.lookup_revision.return_value = {} resp = self.client.get(url) browse_rev_url = reverse('browse-revision', kwargs={'sha1_git': rev_id}, query_params={'origin': origin}) expected_result = { 'browse_url': browse_rev_url, 'metadata': {'origin': origin}, 'namespace': 'swh', 'object_id': rev_id, 'object_type': REVISION, 'scheme_version': 1 } - self.assertEquals(resp.status_code, 200) - self.assertEquals(resp.data, expected_result) + self.assertEqual(resp.status_code, 200) + self.assertEqual(resp.data, expected_result) def test_swh_id_resolve_invalid(self): rev_id_invalid = '96db9023b8_foo_50d6c108e9a3' swh_id = 'swh:1:rev:%s' % rev_id_invalid url = reverse('api-resolve-swh-pid', kwargs={'swh_id': swh_id}) resp = self.client.get(url) - self.assertEquals(resp.status_code, 400) + self.assertEqual(resp.status_code, 400) @patch('swh.web.api.views.identifiers.service') def test_swh_id_resolve_not_found(self, mock_service): rev_id_not_found = '56db90232881d7cd9e379b0c154650d6c108e9a1' swh_id = 'swh:1:rev:%s' % rev_id_not_found url = reverse('api-resolve-swh-pid', kwargs={'swh_id': swh_id}) mock_service.lookup_revision.side_effect = NotFoundExc('Revision not found !') # noqa resp = self.client.get(url) - self.assertEquals(resp.status_code, 404) + self.assertEqual(resp.status_code, 404) diff --git a/swh/web/tests/api/views/test_origin.py b/swh/web/tests/api/views/test_origin.py index fc87a2d82..697c799a0 100644 --- a/swh/web/tests/api/views/test_origin.py +++ b/swh/web/tests/api/views/test_origin.py @@ -1,246 +1,246 @@ # Copyright (C) 2015-2018 The Software Heritage developers # See the AUTHORS file at the top-level directory of this distribution # License: GNU Affero General Public License version 3, or any later version # See top-level LICENSE file for more information from rest_framework.test import APITestCase from unittest.mock import patch from swh.storage.exc import StorageDBError, StorageAPIError from swh.web.tests.testcase import SWHWebTestCase class OriginApiTestCase(SWHWebTestCase, APITestCase): def setUp(self): self.origin_visit1 = { 'date': 1104616800.0, 'origin': 10, 'visit': 100, 'metadata': None, 'status': 'full', } self.origin1 = { 'id': 1234, 'url': 'ftp://some/url/to/origin/0', 'type': 'ftp' } @patch('swh.web.api.views.origin.get_origin_visits') def test_api_1_lookup_origin_visits_raise_error( self, mock_get_origin_visits, ): # given mock_get_origin_visits.side_effect = ValueError( 'voluntary error to check the bad request middleware.') # when rv = self.client.get('/api/1/origin/2/visits/') # then - self.assertEquals(rv.status_code, 400) - self.assertEquals(rv['Content-Type'], 'application/json') - self.assertEquals(rv.data, { + self.assertEqual(rv.status_code, 400) + self.assertEqual(rv['Content-Type'], 'application/json') + self.assertEqual(rv.data, { 'exception': 'ValueError', 'reason': 'voluntary error to check the bad request middleware.'}) @patch('swh.web.common.utils.service') def test_api_1_lookup_origin_visits_raise_swh_storage_error_db( self, mock_service): # given mock_service.lookup_origin_visits.side_effect = StorageDBError( 'SWH Storage exploded! Will be back online shortly!') # when rv = self.client.get('/api/1/origin/2/visits/') # then - self.assertEquals(rv.status_code, 503) - self.assertEquals(rv['Content-Type'], 'application/json') - self.assertEquals(rv.data, { + self.assertEqual(rv.status_code, 503) + self.assertEqual(rv['Content-Type'], 'application/json') + self.assertEqual(rv.data, { 'exception': 'StorageDBError', 'reason': 'An unexpected error occurred in the backend: ' 'SWH Storage exploded! Will be back online shortly!'}) @patch('swh.web.common.utils.service') def test_api_1_lookup_origin_visits_raise_swh_storage_error_api( self, mock_service): # given mock_service.lookup_origin_visits.side_effect = StorageAPIError( 'SWH Storage API dropped dead! Will resurrect from its ashes asap!' ) # when rv = self.client.get('/api/1/origin/2/visits/') # then - self.assertEquals(rv.status_code, 503) - self.assertEquals(rv['Content-Type'], 'application/json') - self.assertEquals(rv.data, { + self.assertEqual(rv.status_code, 503) + self.assertEqual(rv['Content-Type'], 'application/json') + self.assertEqual(rv.data, { 'exception': 'StorageAPIError', 'reason': 'An unexpected error occurred in the api backend: ' 'SWH Storage API dropped dead! Will resurrect from its ashes asap!' }) @patch('swh.web.api.views.origin.get_origin_visits') def test_api_1_lookup_origin_visits(self, mock_get_origin_visits): # given stub_visits = [ { 'date': 1293919200.0, 'origin': 2, 'snapshot': '1234', 'visit': 1 }, { 'date': 1293919200.0, 'origin': 2, 'snapshot': '1234', 'visit': 2 }, { 'date': 1420149600.0, 'origin': 2, 'snapshot': '5678', 'visit': 3 }, { 'date': 1420149600.0, 'origin': 2, 'snapshot': '5678', 'visit': 4 } ] mock_get_origin_visits.return_value = stub_visits # when rv = self.client.get('/api/1/origin/2/visits/?per_page=2&last_visit=3') - self.assertEquals(rv.status_code, 200) - self.assertEquals(rv['Content-Type'], 'application/json') - self.assertEquals(rv.data, [ + self.assertEqual(rv.status_code, 200) + self.assertEqual(rv['Content-Type'], 'application/json') + self.assertEqual(rv.data, [ { 'date': 1293919200.0, 'origin': 2, 'snapshot': '1234', 'visit': 2, 'origin_visit_url': '/api/1/origin/2/visit/2/', 'snapshot_url': '/api/1/snapshot/1234/' }, { 'date': 1293919200.0, 'origin': 2, 'snapshot': '1234', 'visit': 1, 'origin_visit_url': '/api/1/origin/2/visit/1/', 'snapshot_url': '/api/1/snapshot/1234/' }, ]) @patch('swh.web.api.views.origin.service') def test_api_1_lookup_origin_visit(self, mock_service): # given origin_visit = self.origin_visit1.copy() origin_visit.update({ 'snapshot': '57478754' }) mock_service.lookup_origin_visit.return_value = origin_visit expected_origin_visit = self.origin_visit1.copy() expected_origin_visit.update({ 'origin_url': '/api/1/origin/10/', 'snapshot': '57478754', 'snapshot_url': '/api/1/snapshot/57478754/' }) # when rv = self.client.get('/api/1/origin/10/visit/100/') - self.assertEquals(rv.status_code, 200) - self.assertEquals(rv['Content-Type'], 'application/json') - self.assertEquals(rv.data, expected_origin_visit) + self.assertEqual(rv.status_code, 200) + self.assertEqual(rv['Content-Type'], 'application/json') + self.assertEqual(rv.data, expected_origin_visit) mock_service.lookup_origin_visit.assert_called_once_with('10', '100') @patch('swh.web.api.views.origin.service') def test_api_1_lookup_origin_visit_not_found(self, mock_service): # given mock_service.lookup_origin_visit.return_value = None # when rv = self.client.get('/api/1/origin/1/visit/1000/') - self.assertEquals(rv.status_code, 404) - self.assertEquals(rv['Content-Type'], 'application/json') - self.assertEquals(rv.data, { + self.assertEqual(rv.status_code, 404) + self.assertEqual(rv['Content-Type'], 'application/json') + self.assertEqual(rv.data, { 'exception': 'NotFoundExc', 'reason': 'No visit 1000 for origin 1 found' }) mock_service.lookup_origin_visit.assert_called_once_with('1', '1000') @patch('swh.web.api.views.origin.service') def test_api_origin_by_id(self, mock_service): # given mock_service.lookup_origin.return_value = self.origin1 expected_origin = self.origin1.copy() expected_origin.update({ 'origin_visits_url': '/api/1/origin/1234/visits/' }) # when rv = self.client.get('/api/1/origin/1234/') # then - self.assertEquals(rv.status_code, 200) - self.assertEquals(rv['Content-Type'], 'application/json') - self.assertEquals(rv.data, expected_origin) + self.assertEqual(rv.status_code, 200) + self.assertEqual(rv['Content-Type'], 'application/json') + self.assertEqual(rv.data, expected_origin) mock_service.lookup_origin.assert_called_with({'id': '1234'}) @patch('swh.web.api.views.origin.service') def test_api_origin_by_type_url(self, mock_service): # given stub_origin = self.origin1.copy() stub_origin.update({ 'id': 987 }) mock_service.lookup_origin.return_value = stub_origin expected_origin = stub_origin.copy() expected_origin.update({ 'origin_visits_url': '/api/1/origin/987/visits/' }) # when rv = self.client.get('/api/1/origin/ftp/url' '/ftp://some/url/to/origin/0/') # then - self.assertEquals(rv.status_code, 200) - self.assertEquals(rv['Content-Type'], 'application/json') - self.assertEquals(rv.data, expected_origin) + self.assertEqual(rv.status_code, 200) + self.assertEqual(rv['Content-Type'], 'application/json') + self.assertEqual(rv.data, expected_origin) mock_service.lookup_origin.assert_called_with( {'url': 'ftp://some/url/to/origin/0/', 'type': 'ftp'}) @patch('swh.web.api.views.origin.service') def test_api_origin_not_found(self, mock_service): # given mock_service.lookup_origin.return_value = None # when rv = self.client.get('/api/1/origin/4321/') # then - self.assertEquals(rv.status_code, 404) - self.assertEquals(rv['Content-Type'], 'application/json') - self.assertEquals(rv.data, { + self.assertEqual(rv.status_code, 404) + self.assertEqual(rv['Content-Type'], 'application/json') + self.assertEqual(rv.data, { 'exception': 'NotFoundExc', 'reason': 'Origin with id 4321 not found.' }) mock_service.lookup_origin.assert_called_with({'id': '4321'}) diff --git a/swh/web/tests/api/views/test_origin_save.py b/swh/web/tests/api/views/test_origin_save.py index fb09f9106..0dee908d9 100644 --- a/swh/web/tests/api/views/test_origin_save.py +++ b/swh/web/tests/api/views/test_origin_save.py @@ -1,247 +1,247 @@ # Copyright (C) 2018 The Software Heritage developers # See the AUTHORS file at the top-level directory of this distribution # License: GNU Affero General Public License version 3, or any later version # See top-level LICENSE file for more information from datetime import datetime, timedelta from rest_framework.test import APITestCase from unittest.mock import patch from swh.web.common.utils import reverse from swh.web.common.models import ( SaveUnauthorizedOrigin, SaveOriginRequest, SAVE_REQUEST_ACCEPTED, SAVE_REQUEST_REJECTED, SAVE_REQUEST_PENDING ) from swh.web.common.models import ( SAVE_TASK_NOT_CREATED, SAVE_TASK_NOT_YET_SCHEDULED, SAVE_TASK_SCHEDULED, SAVE_TASK_FAILED, SAVE_TASK_SUCCEED ) from swh.web.tests.testcase import SWHWebTestCase class SaveApiTestCase(SWHWebTestCase, APITestCase): @classmethod def setUpTestData(cls): # noqa: N802 SaveUnauthorizedOrigin.objects.create( url='https://github.com/user/illegal_repo') SaveUnauthorizedOrigin.objects.create( url='https://gitlab.com/user_to_exclude') def test_invalid_origin_type(self): url = reverse('api-save-origin', kwargs={'origin_type': 'foo', 'origin_url': 'https://github.com/torvalds/linux'}) # noqa response = self.client.post(url) - self.assertEquals(response.status_code, 400) + self.assertEqual(response.status_code, 400) def test_invalid_origin_url(self): url = reverse('api-save-origin', kwargs={'origin_type': 'git', 'origin_url': 'bar'}) response = self.client.post(url) - self.assertEquals(response.status_code, 400) + self.assertEqual(response.status_code, 400) def check_created_save_request_status(self, mock_scheduler, origin_url, scheduler_task_status, expected_request_status, expected_task_status=None, visit_date=None): if not scheduler_task_status: mock_scheduler.get_tasks.return_value = [] else: mock_scheduler.get_tasks.return_value = \ [{ 'priority': 'high', 'policy': 'oneshot', 'type': 'origin-update-git', 'arguments': { 'kwargs': { 'repo_url': origin_url }, 'args': [] }, 'status': scheduler_task_status, 'id': 1, }] mock_scheduler.create_tasks.return_value = \ [{ 'priority': 'high', 'policy': 'oneshot', 'type': 'origin-update-git', 'arguments': { 'kwargs': { 'repo_url': origin_url }, 'args': [] }, 'status': 'next_run_not_scheduled', 'id': 1, }] url = reverse('api-save-origin', kwargs={'origin_type': 'git', 'origin_url': origin_url}) with patch('swh.web.common.origin_save._get_visit_date_for_save_request') as mock_visit_date: # noqa mock_visit_date.return_value = visit_date response = self.client.post(url) if expected_request_status != SAVE_REQUEST_REJECTED: self.assertEqual(response.status_code, 200) self.assertEqual(response.data['save_request_status'], expected_request_status) self.assertEqual(response.data['save_task_status'], expected_task_status) else: self.assertEqual(response.status_code, 403) def check_save_request_status(self, mock_scheduler, origin_url, expected_request_status, expected_task_status, scheduler_task_status='next_run_not_scheduled', # noqa visit_date=None): mock_scheduler.get_tasks.return_value = \ [{ 'priority': 'high', 'policy': 'oneshot', 'type': 'origin-update-git', 'arguments': { 'kwargs': { 'repo_url': origin_url }, 'args': [] }, 'status': scheduler_task_status, 'id': 1, }] url = reverse('api-save-origin', kwargs={'origin_type': 'git', 'origin_url': origin_url}) with patch('swh.web.common.origin_save._get_visit_date_for_save_request') as mock_visit_date: # noqa mock_visit_date.return_value = visit_date response = self.client.get(url) self.assertEqual(response.status_code, 200) save_request_data = response.data[0] self.assertEqual(save_request_data['save_request_status'], expected_request_status) self.assertEqual(save_request_data['save_task_status'], expected_task_status) # Check that save task status is still available when # the scheduler task has been archived mock_scheduler.get_tasks.return_value = [] response = self.client.get(url) self.assertEqual(response.status_code, 200) save_request_data = response.data[0] self.assertEqual(save_request_data['save_task_status'], expected_task_status) @patch('swh.web.common.origin_save.scheduler') def test_save_request_rejected(self, mock_scheduler): origin_url = 'https://github.com/user/illegal_repo' self.check_created_save_request_status(mock_scheduler, origin_url, None, SAVE_REQUEST_REJECTED) self.check_save_request_status(mock_scheduler, origin_url, SAVE_REQUEST_REJECTED, SAVE_TASK_NOT_CREATED) @patch('swh.web.common.origin_save.scheduler') def test_save_request_pending(self, mock_scheduler): origin_url = 'https://unkwownforge.com/user/repo' self.check_created_save_request_status(mock_scheduler, origin_url, None, SAVE_REQUEST_PENDING, SAVE_TASK_NOT_CREATED) self.check_save_request_status(mock_scheduler, origin_url, SAVE_REQUEST_PENDING, SAVE_TASK_NOT_CREATED) @patch('swh.web.common.origin_save.scheduler') def test_save_request_succeed(self, mock_scheduler): origin_url = 'https://github.com/Kitware/CMake' self.check_created_save_request_status(mock_scheduler, origin_url, None, SAVE_REQUEST_ACCEPTED, SAVE_TASK_NOT_YET_SCHEDULED) self.check_save_request_status(mock_scheduler, origin_url, SAVE_REQUEST_ACCEPTED, SAVE_TASK_SCHEDULED, scheduler_task_status='next_run_scheduled') # noqa self.check_save_request_status(mock_scheduler, origin_url, SAVE_REQUEST_ACCEPTED, SAVE_TASK_SCHEDULED, scheduler_task_status='completed', visit_date=None) # noqa visit_date = datetime.now() + timedelta(hours=1) self.check_save_request_status(mock_scheduler, origin_url, SAVE_REQUEST_ACCEPTED, SAVE_TASK_SUCCEED, scheduler_task_status='completed', visit_date=visit_date) # noqa @patch('swh.web.common.origin_save.scheduler') def test_save_request_failed(self, mock_scheduler): origin_url = 'https://gitlab.com/inkscape/inkscape' self.check_created_save_request_status(mock_scheduler, origin_url, None, SAVE_REQUEST_ACCEPTED, SAVE_TASK_NOT_YET_SCHEDULED) self.check_save_request_status(mock_scheduler, origin_url, SAVE_REQUEST_ACCEPTED, SAVE_TASK_SCHEDULED, scheduler_task_status='next_run_scheduled') # noqa self.check_save_request_status(mock_scheduler, origin_url, SAVE_REQUEST_ACCEPTED, SAVE_TASK_FAILED, scheduler_task_status='disabled') # noqa @patch('swh.web.common.origin_save.scheduler') def test_create_save_request_only_when_needed(self, mock_scheduler): origin_url = 'https://gitlab.com/webpack/webpack' SaveOriginRequest.objects.create(origin_type='git', origin_url=origin_url, status=SAVE_REQUEST_ACCEPTED, # noqa loading_task_id=56) self.check_created_save_request_status(mock_scheduler, origin_url, 'next_run_not_scheduled', SAVE_REQUEST_ACCEPTED, SAVE_TASK_NOT_YET_SCHEDULED) sors = list(SaveOriginRequest.objects.filter(origin_type='git', origin_url=origin_url)) - self.assertEquals(len(sors), 1) + self.assertEqual(len(sors), 1) self.check_created_save_request_status(mock_scheduler, origin_url, 'next_run_scheduled', SAVE_REQUEST_ACCEPTED, SAVE_TASK_SCHEDULED) sors = list(SaveOriginRequest.objects.filter(origin_type='git', origin_url=origin_url)) - self.assertEquals(len(sors), 1) + self.assertEqual(len(sors), 1) visit_date = datetime.now() + timedelta(hours=1) self.check_created_save_request_status(mock_scheduler, origin_url, 'completed', SAVE_REQUEST_ACCEPTED, SAVE_TASK_NOT_YET_SCHEDULED, visit_date=visit_date) sors = list(SaveOriginRequest.objects.filter(origin_type='git', origin_url=origin_url)) - self.assertEquals(len(sors), 2) + self.assertEqual(len(sors), 2) self.check_created_save_request_status(mock_scheduler, origin_url, 'disabled', SAVE_REQUEST_ACCEPTED, SAVE_TASK_NOT_YET_SCHEDULED) sors = list(SaveOriginRequest.objects.filter(origin_type='git', origin_url=origin_url)) - self.assertEquals(len(sors), 3) + self.assertEqual(len(sors), 3) diff --git a/swh/web/tests/api/views/test_person.py b/swh/web/tests/api/views/test_person.py index d0e95a647..b4c0c22dd 100644 --- a/swh/web/tests/api/views/test_person.py +++ b/swh/web/tests/api/views/test_person.py @@ -1,45 +1,45 @@ # Copyright (C) 2015-2018 The Software Heritage developers # See the AUTHORS file at the top-level directory of this distribution # License: GNU Affero General Public License version 3, or any later version # See top-level LICENSE file for more information from rest_framework.test import APITestCase from unittest.mock import patch from swh.web.tests.testcase import SWHWebTestCase class PersonApiTestCase(SWHWebTestCase, APITestCase): @patch('swh.web.api.views.person.service') def test_api_person(self, mock_service): # given stub_person = { 'id': '198003', 'name': 'Software Heritage', 'email': 'robot@softwareheritage.org', } mock_service.lookup_person.return_value = stub_person # when rv = self.client.get('/api/1/person/198003/') # then - self.assertEquals(rv.status_code, 200) - self.assertEquals(rv['Content-Type'], 'application/json') - self.assertEquals(rv.data, stub_person) + self.assertEqual(rv.status_code, 200) + self.assertEqual(rv['Content-Type'], 'application/json') + self.assertEqual(rv.data, stub_person) @patch('swh.web.api.views.person.service') def test_api_person_not_found(self, mock_service): # given mock_service.lookup_person.return_value = None # when rv = self.client.get('/api/1/person/666/') # then - self.assertEquals(rv.status_code, 404) - self.assertEquals(rv['Content-Type'], 'application/json') - self.assertEquals(rv.data, { + self.assertEqual(rv.status_code, 404) + self.assertEqual(rv['Content-Type'], 'application/json') + self.assertEqual(rv.data, { 'exception': 'NotFoundExc', 'reason': 'Person with id 666 not found.'}) diff --git a/swh/web/tests/api/views/test_release.py b/swh/web/tests/api/views/test_release.py index ff0be83bc..6f0731aaa 100644 --- a/swh/web/tests/api/views/test_release.py +++ b/swh/web/tests/api/views/test_release.py @@ -1,117 +1,117 @@ # Copyright (C) 2015-2018 The Software Heritage developers # See the AUTHORS file at the top-level directory of this distribution # License: GNU Affero General Public License version 3, or any later version # See top-level LICENSE file for more information from rest_framework.test import APITestCase from unittest.mock import patch from swh.web.tests.testcase import SWHWebTestCase class ReleaseApiTestCase(SWHWebTestCase, APITestCase): @patch('swh.web.api.views.release.service') def test_api_release(self, mock_service): release_id = '7045404f3d1c54e6473' target_id = '6072557b6c10cd9a211' # given stub_release = { 'id': release_id, 'target_type': 'revision', 'target': target_id, "date": "Mon, 10 Mar 1997 08:00:00 GMT", "synthetic": True, 'author': { 'id': 10, 'name': 'author release name', 'email': 'author@email', }, } expected_release = { 'id': release_id, 'target_type': 'revision', 'target': target_id, 'target_url': '/api/1/revision/%s/' % target_id, "date": "Mon, 10 Mar 1997 08:00:00 GMT", "synthetic": True, 'author_url': '/api/1/person/10/', 'author': { 'id': 10, 'name': 'author release name', 'email': 'author@email', }, } mock_service.lookup_release.return_value = stub_release # when rv = self.client.get('/api/1/release/%s/' % release_id) # then - self.assertEquals(rv.status_code, 200) - self.assertEquals(rv['Content-Type'], 'application/json') - self.assertEquals(rv.data, expected_release) + self.assertEqual(rv.status_code, 200) + self.assertEqual(rv['Content-Type'], 'application/json') + self.assertEqual(rv.data, expected_release) mock_service.lookup_release.assert_called_once_with(release_id) @patch('swh.web.api.views.release.service') def test_api_release_target_type_not_a_revision(self, mock_service): release = '8d56a78' target = '9a5c3f' # given stub_release = { 'id': release, 'target_type': 'other-stuff', 'target': target, "date": "Mon, 10 Mar 1997 08:00:00 GMT", "synthetic": True, 'author': { 'id': 9, 'name': 'author release name', 'email': 'author@email', }, } expected_release = { 'id': release, 'target_type': 'other-stuff', 'target': target, "date": "Mon, 10 Mar 1997 08:00:00 GMT", "synthetic": True, 'author_url': '/api/1/person/9/', 'author': { 'id': 9, 'name': 'author release name', 'email': 'author@email', }, } mock_service.lookup_release.return_value = stub_release # when rv = self.client.get('/api/1/release/%s/' % release) # then - self.assertEquals(rv.status_code, 200) - self.assertEquals(rv['Content-Type'], 'application/json') - self.assertEquals(rv.data, expected_release) + self.assertEqual(rv.status_code, 200) + self.assertEqual(rv['Content-Type'], 'application/json') + self.assertEqual(rv.data, expected_release) mock_service.lookup_release.assert_called_once_with(release) @patch('swh.web.api.views.release.service') def test_api_release_not_found(self, mock_service): # given mock_service.lookup_release.return_value = None # when rv = self.client.get('/api/1/release/c54e6473c71bbb716529/') # then - self.assertEquals(rv.status_code, 404) - self.assertEquals(rv['Content-Type'], 'application/json') - self.assertEquals(rv.data, { + self.assertEqual(rv.status_code, 404) + self.assertEqual(rv['Content-Type'], 'application/json') + self.assertEqual(rv.data, { 'exception': 'NotFoundExc', 'reason': 'Release with sha1_git c54e6473c71bbb716529 not found.' }) diff --git a/swh/web/tests/api/views/test_revision.py b/swh/web/tests/api/views/test_revision.py index d3f756b11..ffb1566d9 100644 --- a/swh/web/tests/api/views/test_revision.py +++ b/swh/web/tests/api/views/test_revision.py @@ -1,892 +1,892 @@ # Copyright (C) 2015-2018 The Software Heritage developers # See the AUTHORS file at the top-level directory of this distribution # License: GNU Affero General Public License version 3, or any later version # See top-level LICENSE file for more information from rest_framework.test import APITestCase from unittest.mock import patch from swh.web.common.exc import NotFoundExc from swh.web.api.views.revision import ( _revision_directory_by ) from swh.web.tests.testcase import SWHWebTestCase class ReleaseApiTestCase(SWHWebTestCase, APITestCase): @patch('swh.web.api.views.revision.service') def test_api_revision(self, mock_service): # given stub_revision = { 'id': '18d8be353ed3480476f032475e7c233eff7371d5', 'directory': '7834ef7e7c357ce2af928115c6c6a42b7e2a44e6', 'author_name': 'Software Heritage', 'author_email': 'robot@softwareheritage.org', 'committer_name': 'Software Heritage', 'committer_email': 'robot@softwareheritage.org', 'message': 'synthetic revision message', 'date_offset': 0, 'committer_date_offset': 0, 'parents': ['8734ef7e7c357ce2af928115c6c6a42b7e2a44e7'], 'type': 'tar', 'synthetic': True, 'metadata': { 'original_artifact': [{ 'archive_type': 'tar', 'name': 'webbase-5.7.0.tar.gz', 'sha1': '147f73f369733d088b7a6fa9c4e0273dcd3c7ccd', 'sha1_git': '6a15ea8b881069adedf11feceec35588f2cfe8f1', 'sha256': '401d0df797110bea805d358b85bcc1ced29549d3d73f' '309d36484e7edf7bb912' }] }, } mock_service.lookup_revision.return_value = stub_revision expected_revision = { 'id': '18d8be353ed3480476f032475e7c233eff7371d5', 'url': '/api/1/revision/18d8be353ed3480476f032475e7c233eff7371d5/', 'history_url': '/api/1/revision/18d8be353ed3480476f032475e7c233e' 'ff7371d5/log/', 'directory': '7834ef7e7c357ce2af928115c6c6a42b7e2a44e6', 'directory_url': '/api/1/directory/7834ef7e7c357ce2af928115c6c6' 'a42b7e2a44e6/', 'author_name': 'Software Heritage', 'author_email': 'robot@softwareheritage.org', 'committer_name': 'Software Heritage', 'committer_email': 'robot@softwareheritage.org', 'message': 'synthetic revision message', 'date_offset': 0, 'committer_date_offset': 0, 'parents': [{ 'id': '8734ef7e7c357ce2af928115c6c6a42b7e2a44e7', 'url': '/api/1/revision/8734ef7e7c357ce2af928115c6c6a42b7e2a44e7/' # noqa }], 'type': 'tar', 'synthetic': True, 'metadata': { 'original_artifact': [{ 'archive_type': 'tar', 'name': 'webbase-5.7.0.tar.gz', 'sha1': '147f73f369733d088b7a6fa9c4e0273dcd3c7ccd', 'sha1_git': '6a15ea8b881069adedf11feceec35588f2cfe8f1', 'sha256': '401d0df797110bea805d358b85bcc1ced29549d3d73f' '309d36484e7edf7bb912' }] }, } # when rv = self.client.get('/api/1/revision/' '18d8be353ed3480476f032475e7c233eff7371d5/') # then - self.assertEquals(rv.status_code, 200) - self.assertEquals(rv['Content-Type'], 'application/json') - self.assertEquals(expected_revision, rv.data) + self.assertEqual(rv.status_code, 200) + self.assertEqual(rv['Content-Type'], 'application/json') + self.assertEqual(expected_revision, rv.data) mock_service.lookup_revision.assert_called_once_with( '18d8be353ed3480476f032475e7c233eff7371d5') @patch('swh.web.api.views.revision.service') def test_api_revision_not_found(self, mock_service): # given mock_service.lookup_revision.return_value = None # when rv = self.client.get('/api/1/revision/12345/') # then - self.assertEquals(rv.status_code, 404) - self.assertEquals(rv['Content-Type'], 'application/json') - self.assertEquals(rv.data, { + self.assertEqual(rv.status_code, 404) + self.assertEqual(rv['Content-Type'], 'application/json') + self.assertEqual(rv.data, { 'exception': 'NotFoundExc', 'reason': 'Revision with sha1_git 12345 not found.'}) @patch('swh.web.api.views.revision.service') def test_api_revision_raw_ok(self, mock_service): # given stub_revision = {'message': 'synthetic revision message'} mock_service.lookup_revision_message.return_value = stub_revision # when rv = self.client.get('/api/1/revision/18d8be353ed3480476f032475e7c2' '33eff7371d5/raw/') # then - self.assertEquals(rv.status_code, 200) - self.assertEquals(rv['Content-Type'], 'application/octet-stream') - self.assertEquals(rv.content, b'synthetic revision message') + self.assertEqual(rv.status_code, 200) + self.assertEqual(rv['Content-Type'], 'application/octet-stream') + self.assertEqual(rv.content, b'synthetic revision message') mock_service.lookup_revision_message.assert_called_once_with( '18d8be353ed3480476f032475e7c233eff7371d5') @patch('swh.web.api.views.revision.service') def test_api_revision_raw_ok_no_msg(self, mock_service): # given mock_service.lookup_revision_message.side_effect = NotFoundExc( 'No message for revision') # when rv = self.client.get('/api/1/revision/' '18d8be353ed3480476f032475e7c233eff7371d5/raw/') # then - self.assertEquals(rv.status_code, 404) - self.assertEquals(rv['Content-Type'], 'application/json') - self.assertEquals(rv.data, { + self.assertEqual(rv.status_code, 404) + self.assertEqual(rv['Content-Type'], 'application/json') + self.assertEqual(rv.data, { 'exception': 'NotFoundExc', 'reason': 'No message for revision'}) - self.assertEquals + self.assertEqual mock_service.lookup_revision_message.assert_called_once_with( '18d8be353ed3480476f032475e7c233eff7371d5') @patch('swh.web.api.views.revision.service') def test_api_revision_raw_ko_no_rev(self, mock_service): # given mock_service.lookup_revision_message.side_effect = NotFoundExc( 'No revision found') # when rv = self.client.get('/api/1/revision/' '18d8be353ed3480476f032475e7c233eff7371d5/raw/') # then - self.assertEquals(rv.status_code, 404) - self.assertEquals(rv['Content-Type'], 'application/json') - self.assertEquals(rv.data, { + self.assertEqual(rv.status_code, 404) + self.assertEqual(rv['Content-Type'], 'application/json') + self.assertEqual(rv.data, { 'exception': 'NotFoundExc', 'reason': 'No revision found'}) mock_service.lookup_revision_message.assert_called_once_with( '18d8be353ed3480476f032475e7c233eff7371d5') @patch('swh.web.api.views.revision.service') def test_api_revision_with_origin_not_found(self, mock_service): mock_service.lookup_revision_by.return_value = None rv = self.client.get('/api/1/revision/origin/123/') # then - self.assertEquals(rv.status_code, 404) - self.assertEquals(rv['Content-Type'], 'application/json') + self.assertEqual(rv.status_code, 404) + self.assertEqual(rv['Content-Type'], 'application/json') self.assertIn('Revision with (origin_id: 123', rv.data['reason']) self.assertIn('not found', rv.data['reason']) self.assertEqual('NotFoundExc', rv.data['exception']) mock_service.lookup_revision_by.assert_called_once_with( '123', 'refs/heads/master', None) @patch('swh.web.api.views.revision.service') def test_api_revision_with_origin(self, mock_service): mock_revision = { 'id': '32', 'directory': '21', 'message': 'message 1', 'type': 'deb', } expected_revision = { 'id': '32', 'url': '/api/1/revision/32/', 'history_url': '/api/1/revision/32/log/', 'directory': '21', 'directory_url': '/api/1/directory/21/', 'message': 'message 1', 'type': 'deb', } mock_service.lookup_revision_by.return_value = mock_revision rv = self.client.get('/api/1/revision/origin/1/') # then - self.assertEquals(rv.status_code, 200) - self.assertEquals(rv['Content-Type'], 'application/json') + self.assertEqual(rv.status_code, 200) + self.assertEqual(rv['Content-Type'], 'application/json') self.assertEqual(rv.data, expected_revision) mock_service.lookup_revision_by.assert_called_once_with( '1', 'refs/heads/master', None) @patch('swh.web.api.views.revision.service') def test_api_revision_with_origin_and_branch_name(self, mock_service): mock_revision = { 'id': '12', 'directory': '23', 'message': 'message 2', 'type': 'tar', } mock_service.lookup_revision_by.return_value = mock_revision expected_revision = { 'id': '12', 'url': '/api/1/revision/12/', 'history_url': '/api/1/revision/12/log/', 'directory': '23', 'directory_url': '/api/1/directory/23/', 'message': 'message 2', 'type': 'tar', } rv = self.client.get('/api/1/revision/origin/1' '/branch/refs/origin/dev/') # then - self.assertEquals(rv.status_code, 200) - self.assertEquals(rv['Content-Type'], 'application/json') + self.assertEqual(rv.status_code, 200) + self.assertEqual(rv['Content-Type'], 'application/json') self.assertEqual(rv.data, expected_revision) mock_service.lookup_revision_by.assert_called_once_with( '1', 'refs/origin/dev', None) @patch('swh.web.api.views.revision.parse_timestamp') @patch('swh.web.api.views.revision.service') @patch('swh.web.api.views.revision.utils') def test_api_revision_with_origin_and_branch_name_and_timestamp(self, mock_utils, mock_service, mock_parse_timestamp): # noqa mock_revision = { 'id': '123', 'directory': '456', 'message': 'message 3', 'type': 'tar', } mock_service.lookup_revision_by.return_value = mock_revision expected_revision = { 'id': '123', 'url': '/api/1/revision/123/', 'history_url': '/api/1/revision/123/log/', 'directory': '456', 'directory_url': '/api/1/directory/456/', 'message': 'message 3', 'type': 'tar', } mock_parse_timestamp.return_value = 'parsed-date' mock_utils.enrich_revision.return_value = expected_revision rv = self.client.get('/api/1/revision' '/origin/1' '/branch/refs/origin/dev' '/ts/1452591542/') # then - self.assertEquals(rv.status_code, 200) - self.assertEquals(rv['Content-Type'], 'application/json') + self.assertEqual(rv.status_code, 200) + self.assertEqual(rv['Content-Type'], 'application/json') self.assertEqual(rv.data, expected_revision) mock_service.lookup_revision_by.assert_called_once_with( '1', 'refs/origin/dev', 'parsed-date') mock_parse_timestamp.assert_called_once_with('1452591542') mock_utils.enrich_revision.assert_called_once_with( mock_revision) @patch('swh.web.api.views.revision.parse_timestamp') @patch('swh.web.api.views.revision.service') @patch('swh.web.api.views.revision.utils') def test_api_revision_with_origin_and_branch_name_and_timestamp_escapes( self, mock_utils, mock_service, mock_parse_timestamp): mock_revision = { 'id': '999', } mock_service.lookup_revision_by.return_value = mock_revision expected_revision = { 'id': '999', 'url': '/api/1/revision/999/', 'history_url': '/api/1/revision/999/log/', } mock_parse_timestamp.return_value = 'parsed-date' mock_utils.enrich_revision.return_value = expected_revision rv = self.client.get('/api/1/revision' '/origin/1' '/branch/refs%2Forigin%2Fdev' '/ts/Today%20is%20' 'January%201,%202047%20at%208:21:00AM/') # then - self.assertEquals(rv.status_code, 200) - self.assertEquals(rv['Content-Type'], 'application/json') + self.assertEqual(rv.status_code, 200) + self.assertEqual(rv['Content-Type'], 'application/json') self.assertEqual(rv.data, expected_revision) mock_service.lookup_revision_by.assert_called_once_with( '1', 'refs/origin/dev', 'parsed-date') mock_parse_timestamp.assert_called_once_with( 'Today is January 1, 2047 at 8:21:00AM') mock_utils.enrich_revision.assert_called_once_with( mock_revision) @patch('swh.web.api.views.revision.service') def test_revision_directory_by_ko_raise(self, mock_service): # given mock_service.lookup_directory_through_revision.side_effect = NotFoundExc('not') # noqa # when with self.assertRaises(NotFoundExc): _revision_directory_by( {'sha1_git': 'id'}, None, '/api/1/revision/sha1/directory/') # then mock_service.lookup_directory_through_revision.assert_called_once_with( {'sha1_git': 'id'}, None, limit=100, with_data=False) @patch('swh.web.api.views.revision.service') def test_revision_directory_by_type_dir(self, mock_service): # given mock_service.lookup_directory_through_revision.return_value = ( 'rev-id', { 'type': 'dir', 'revision': 'rev-id', 'path': 'some/path', 'content': [] }) # when actual_dir_content = _revision_directory_by( {'sha1_git': 'blah-id'}, 'some/path', '/api/1/revision/sha1/directory/') # then - self.assertEquals(actual_dir_content, { + self.assertEqual(actual_dir_content, { 'type': 'dir', 'revision': 'rev-id', 'path': 'some/path', 'content': [] }) mock_service.lookup_directory_through_revision.assert_called_once_with( {'sha1_git': 'blah-id'}, 'some/path', limit=100, with_data=False) @patch('swh.web.api.views.revision.service') def test_revision_directory_by_type_file(self, mock_service): # given mock_service.lookup_directory_through_revision.return_value = ( 'rev-id', { 'type': 'file', 'revision': 'rev-id', 'path': 'some/path', 'content': {'blah': 'blah'} }) # when actual_dir_content = _revision_directory_by( {'sha1_git': 'sha1'}, 'some/path', '/api/1/revision/origin/2/directory/', limit=1000, with_data=True) # then - self.assertEquals(actual_dir_content, { + self.assertEqual(actual_dir_content, { 'type': 'file', 'revision': 'rev-id', 'path': 'some/path', 'content': {'blah': 'blah'} }) mock_service.lookup_directory_through_revision.assert_called_once_with( {'sha1_git': 'sha1'}, 'some/path', limit=1000, with_data=True) @patch('swh.web.api.views.revision.parse_timestamp') @patch('swh.web.api.views.revision._revision_directory_by') @patch('swh.web.api.views.revision.utils') def test_api_directory_through_revision_origin_ko_not_found(self, mock_utils, mock_rev_dir, mock_parse_timestamp): # noqa mock_rev_dir.side_effect = NotFoundExc('not found') mock_parse_timestamp.return_value = '2012-10-20 00:00:00' rv = self.client.get('/api/1/revision' '/origin/10' '/branch/refs/remote/origin/dev' '/ts/2012-10-20' '/directory/') # then - self.assertEquals(rv.status_code, 404) - self.assertEquals(rv['Content-Type'], 'application/json') + self.assertEqual(rv.status_code, 404) + self.assertEqual(rv['Content-Type'], 'application/json') self.assertEqual(rv.data, { 'exception': 'NotFoundExc', 'reason': 'not found'}) mock_rev_dir.assert_called_once_with( {'origin_id': '10', 'branch_name': 'refs/remote/origin/dev', 'ts': '2012-10-20 00:00:00'}, None, '/api/1/revision' '/origin/10' '/branch/refs/remote/origin/dev' '/ts/2012-10-20' '/directory/', with_data=False) @patch('swh.web.api.views.revision._revision_directory_by') def test_api_directory_through_revision_origin(self, mock_revision_dir): expected_res = [{ 'id': '123' }] mock_revision_dir.return_value = expected_res rv = self.client.get('/api/1/revision/origin/3/directory/') # then - self.assertEquals(rv.status_code, 200) - self.assertEquals(rv['Content-Type'], 'application/json') + self.assertEqual(rv.status_code, 200) + self.assertEqual(rv['Content-Type'], 'application/json') self.assertEqual(rv.data, expected_res) mock_revision_dir.assert_called_once_with({ 'origin_id': '3', 'branch_name': 'refs/heads/master', 'ts': None}, None, '/api/1/revision/origin/3/directory/', with_data=False) @patch('swh.web.api.views.revision.service') def test_api_revision_log(self, mock_service): # given stub_revisions = [{ 'id': '18d8be353ed3480476f032475e7c233eff7371d5', 'directory': '7834ef7e7c357ce2af928115c6c6a42b7e2a44e6', 'author_name': 'Software Heritage', 'author_email': 'robot@softwareheritage.org', 'committer_name': 'Software Heritage', 'committer_email': 'robot@softwareheritage.org', 'message': 'synthetic revision message', 'date_offset': 0, 'committer_date_offset': 0, 'parents': ['7834ef7e7c357ce2af928115c6c6a42b7e2a4345'], 'type': 'tar', 'synthetic': True, }] mock_service.lookup_revision_log.return_value = stub_revisions expected_revisions = [{ 'id': '18d8be353ed3480476f032475e7c233eff7371d5', 'url': '/api/1/revision/18d8be353ed3480476f032475e7c233eff7371d5/', 'history_url': '/api/1/revision/18d8be353ed3480476f032475e7c233ef' 'f7371d5/log/', 'directory': '7834ef7e7c357ce2af928115c6c6a42b7e2a44e6', 'directory_url': '/api/1/directory/7834ef7e7c357ce2af928115c6c6a' '42b7e2a44e6/', 'author_name': 'Software Heritage', 'author_email': 'robot@softwareheritage.org', 'committer_name': 'Software Heritage', 'committer_email': 'robot@softwareheritage.org', 'message': 'synthetic revision message', 'date_offset': 0, 'committer_date_offset': 0, 'parents': [{ 'id': '7834ef7e7c357ce2af928115c6c6a42b7e2a4345', 'url': '/api/1/revision/7834ef7e7c357ce2af928115c6c6a42b7e2a4345/', # noqa }], 'type': 'tar', 'synthetic': True, }] # when rv = self.client.get('/api/1/revision/8834ef7e7c357ce2af928115c6c6a42' 'b7e2a44e6/log/') # then - self.assertEquals(rv.status_code, 200) - self.assertEquals(rv['Content-Type'], 'application/json') + self.assertEqual(rv.status_code, 200) + self.assertEqual(rv['Content-Type'], 'application/json') - self.assertEquals(rv.data, expected_revisions) + self.assertEqual(rv.data, expected_revisions) self.assertFalse(rv.has_header('Link')) mock_service.lookup_revision_log.assert_called_once_with( '8834ef7e7c357ce2af928115c6c6a42b7e2a44e6', 11) @patch('swh.web.api.views.revision.service') def test_api_revision_log_with_next(self, mock_service): # given stub_revisions = [] for i in range(27): stub_revisions.append({'id': str(i)}) mock_service.lookup_revision_log.return_value = stub_revisions[:26] expected_revisions = [x for x in stub_revisions if int(x['id']) < 25] for e in expected_revisions: e['url'] = '/api/1/revision/%s/' % e['id'] e['history_url'] = '/api/1/revision/%s/log/' % e['id'] # when rv = self.client.get('/api/1/revision/8834ef7e7c357ce2af928115c6c6a42' 'b7e2a44e6/log/?per_page=25') # then - self.assertEquals(rv.status_code, 200) - self.assertEquals(rv['Content-Type'], 'application/json') - self.assertEquals(rv.data, expected_revisions) - self.assertEquals(rv['Link'], - '; rel="next"') + self.assertEqual(rv.status_code, 200) + self.assertEqual(rv['Content-Type'], 'application/json') + self.assertEqual(rv.data, expected_revisions) + self.assertEqual(rv['Link'], + '; rel="next"') mock_service.lookup_revision_log.assert_called_once_with( '8834ef7e7c357ce2af928115c6c6a42b7e2a44e6', 26) @patch('swh.web.api.views.revision.service') def test_api_revision_log_not_found(self, mock_service): # given mock_service.lookup_revision_log.return_value = None # when rv = self.client.get('/api/1/revision/8834ef7e7c357ce2af928115c6c6' 'a42b7e2a44e6/log/') # then - self.assertEquals(rv.status_code, 404) - self.assertEquals(rv['Content-Type'], 'application/json') - self.assertEquals(rv.data, { + self.assertEqual(rv.status_code, 404) + self.assertEqual(rv['Content-Type'], 'application/json') + self.assertEqual(rv.data, { 'exception': 'NotFoundExc', 'reason': 'Revision with sha1_git' ' 8834ef7e7c357ce2af928115c6c6a42b7e2a44e6 not found.'}) self.assertFalse(rv.has_header('Link')) mock_service.lookup_revision_log.assert_called_once_with( '8834ef7e7c357ce2af928115c6c6a42b7e2a44e6', 11) @patch('swh.web.api.views.revision.service') def test_api_revision_log_context(self, mock_service): # given stub_revisions = [{ 'id': '18d8be353ed3480476f032475e7c233eff7371d5', 'directory': '7834ef7e7c357ce2af928115c6c6a42b7e2a44e6', 'author_name': 'Software Heritage', 'author_email': 'robot@softwareheritage.org', 'committer_name': 'Software Heritage', 'committer_email': 'robot@softwareheritage.org', 'message': 'synthetic revision message', 'date_offset': 0, 'committer_date_offset': 0, 'parents': ['7834ef7e7c357ce2af928115c6c6a42b7e2a4345'], 'type': 'tar', 'synthetic': True, }] mock_service.lookup_revision_log.return_value = stub_revisions mock_service.lookup_revision_multiple.return_value = [{ 'id': '7834ef7e7c357ce2af928115c6c6a42b7e2a44e6', 'directory': '18d8be353ed3480476f032475e7c233eff7371d5', 'author_name': 'Name Surname', 'author_email': 'name@surname.com', 'committer_name': 'Name Surname', 'committer_email': 'name@surname.com', 'message': 'amazing revision message', 'date_offset': 0, 'committer_date_offset': 0, 'parents': ['adc83b19e793491b1c6ea0fd8b46cd9f32e592fc'], 'type': 'tar', 'synthetic': True, }] expected_revisions = [ { 'url': '/api/1/revision/' '7834ef7e7c357ce2af928115c6c6a42b7e2a44e6/', 'history_url': '/api/1/revision/' '7834ef7e7c357ce2af928115c6c6a42b7e2a44e6/log/', 'id': '7834ef7e7c357ce2af928115c6c6a42b7e2a44e6', 'directory': '18d8be353ed3480476f032475e7c233eff7371d5', 'directory_url': '/api/1/directory/' '18d8be353ed3480476f032475e7c233eff7371d5/', 'author_name': 'Name Surname', 'author_email': 'name@surname.com', 'committer_name': 'Name Surname', 'committer_email': 'name@surname.com', 'message': 'amazing revision message', 'date_offset': 0, 'committer_date_offset': 0, 'parents': [{ 'id': 'adc83b19e793491b1c6ea0fd8b46cd9f32e592fc', 'url': '/api/1/revision/adc83b19e793491b1c6ea0fd8b46cd9f32e592fc/', # noqa }], 'type': 'tar', 'synthetic': True, }, { 'url': '/api/1/revision/' '18d8be353ed3480476f032475e7c233eff7371d5/', 'history_url': '/api/1/revision/' '18d8be353ed3480476f032475e7c233eff7371d5/log/', 'id': '18d8be353ed3480476f032475e7c233eff7371d5', 'directory': '7834ef7e7c357ce2af928115c6c6a42b7e2a44e6', 'directory_url': '/api/1/directory/' '7834ef7e7c357ce2af928115c6c6a42b7e2a44e6/', 'author_name': 'Software Heritage', 'author_email': 'robot@softwareheritage.org', 'committer_name': 'Software Heritage', 'committer_email': 'robot@softwareheritage.org', 'message': 'synthetic revision message', 'date_offset': 0, 'committer_date_offset': 0, 'parents': [{ 'id': '7834ef7e7c357ce2af928115c6c6a42b7e2a4345', 'url': '/api/1/revision/7834ef7e7c357ce2af928115c6c6a42b7e2a4345/', # noqa }], 'type': 'tar', 'synthetic': True, }] # when rv = self.client.get('/api/1/revision/18d8be353ed3480476f0' '32475e7c233eff7371d5/prev/21145781e2' '6ad1f978e/log/') # then - self.assertEquals(rv.status_code, 200) - self.assertEquals(rv['Content-Type'], 'application/json') - self.assertEquals(expected_revisions, rv.data) + self.assertEqual(rv.status_code, 200) + self.assertEqual(rv['Content-Type'], 'application/json') + self.assertEqual(expected_revisions, rv.data) self.assertFalse(rv.has_header('Link')) mock_service.lookup_revision_log.assert_called_once_with( '18d8be353ed3480476f032475e7c233eff7371d5', 11) mock_service.lookup_revision_multiple.assert_called_once_with( ['21145781e26ad1f978e']) @patch('swh.web.api.views.revision.service') def test_api_revision_log_by(self, mock_service): # given stub_revisions = [{ 'id': '18d8be353ed3480476f032475e7c233eff7371d5', 'directory': '7834ef7e7c357ce2af928115c6c6a42b7e2a44e6', 'author_name': 'Software Heritage', 'author_email': 'robot@softwareheritage.org', 'committer_name': 'Software Heritage', 'committer_email': 'robot@softwareheritage.org', 'message': 'synthetic revision message', 'date_offset': 0, 'committer_date_offset': 0, 'parents': ['7834ef7e7c357ce2af928115c6c6a42b7e2a4345'], 'type': 'tar', 'synthetic': True, }] mock_service.lookup_revision_log_by.return_value = stub_revisions expected_revisions = [{ 'id': '18d8be353ed3480476f032475e7c233eff7371d5', 'url': '/api/1/revision/18d8be353ed3480476f032475e7c233eff7371d5/', 'history_url': '/api/1/revision/18d8be353ed3480476f032475e7c233ef' 'f7371d5/log/', 'directory': '7834ef7e7c357ce2af928115c6c6a42b7e2a44e6', 'directory_url': '/api/1/directory/7834ef7e7c357ce2af928115c6c6a' '42b7e2a44e6/', 'author_name': 'Software Heritage', 'author_email': 'robot@softwareheritage.org', 'committer_name': 'Software Heritage', 'committer_email': 'robot@softwareheritage.org', 'message': 'synthetic revision message', 'date_offset': 0, 'committer_date_offset': 0, 'parents': [{ 'id': '7834ef7e7c357ce2af928115c6c6a42b7e2a4345', 'url': '/api/1/revision/7834ef7e7c357ce2af928115c6c6a42b7e2a4345/' # noqa }], 'type': 'tar', 'synthetic': True, }] # when rv = self.client.get('/api/1/revision/origin/1/log/') # then - self.assertEquals(rv.status_code, 200) - self.assertEquals(rv['Content-Type'], 'application/json') - self.assertEquals(rv.data, expected_revisions) + self.assertEqual(rv.status_code, 200) + self.assertEqual(rv['Content-Type'], 'application/json') + self.assertEqual(rv.data, expected_revisions) self.assertFalse(rv.has_header('Link')) mock_service.lookup_revision_log_by.assert_called_once_with( '1', 'refs/heads/master', None, 11) @patch('swh.web.api.views.revision.service') def test_api_revision_log_by_with_next(self, mock_service): # given stub_revisions = [] for i in range(27): stub_revisions.append({'id': str(i)}) mock_service.lookup_revision_log_by.return_value = stub_revisions[:26] expected_revisions = [x for x in stub_revisions if int(x['id']) < 25] for e in expected_revisions: e['url'] = '/api/1/revision/%s/' % e['id'] e['history_url'] = '/api/1/revision/%s/log/' % e['id'] # when rv = self.client.get('/api/1/revision/origin/1/log/?per_page=25') # then - self.assertEquals(rv.status_code, 200) + self.assertEqual(rv.status_code, 200) - self.assertEquals(rv['Content-Type'], 'application/json') + self.assertEqual(rv['Content-Type'], 'application/json') self.assertIsNotNone(rv['Link']) - self.assertEquals(rv.data, expected_revisions) + self.assertEqual(rv.data, expected_revisions) mock_service.lookup_revision_log_by.assert_called_once_with( '1', 'refs/heads/master', None, 26) @patch('swh.web.api.views.revision.service') def test_api_revision_log_by_norev(self, mock_service): # given mock_service.lookup_revision_log_by.side_effect = NotFoundExc( 'No revision') # when rv = self.client.get('/api/1/revision/origin/1/log/') # then - self.assertEquals(rv.status_code, 404) - self.assertEquals(rv['Content-Type'], 'application/json') + self.assertEqual(rv.status_code, 404) + self.assertEqual(rv['Content-Type'], 'application/json') self.assertFalse(rv.has_header('Link')) - self.assertEquals(rv.data, {'exception': 'NotFoundExc', - 'reason': 'No revision'}) + self.assertEqual(rv.data, {'exception': 'NotFoundExc', + 'reason': 'No revision'}) mock_service.lookup_revision_log_by.assert_called_once_with( '1', 'refs/heads/master', None, 11) @patch('swh.web.api.views.revision.service') def test_api_revision_history(self, mock_service): # for readability purposes, we use: # - sha1 as 3 letters (url are way too long otherwise to respect pep8) # - only keys with modification steps (all other keys are kept as is) # given stub_revision = { 'id': '883', 'children': ['777', '999'], 'parents': [], 'directory': '272' } mock_service.lookup_revision.return_value = stub_revision # then rv = self.client.get('/api/1/revision/883/prev/999/') - self.assertEquals(rv.status_code, 200) - self.assertEquals(rv['Content-Type'], 'application/json') - self.assertEquals(rv.data, { + self.assertEqual(rv.status_code, 200) + self.assertEqual(rv['Content-Type'], 'application/json') + self.assertEqual(rv.data, { 'id': '883', 'url': '/api/1/revision/883/', 'history_url': '/api/1/revision/883/log/', 'history_context_url': '/api/1/revision/883/prev/999/log/', 'children': ['777', '999'], 'children_urls': ['/api/1/revision/777/', '/api/1/revision/999/'], 'parents': [], 'directory': '272', 'directory_url': '/api/1/directory/272/' }) mock_service.lookup_revision.assert_called_once_with('883') @patch('swh.web.api.views.revision._revision_directory_by') def test_api_revision_directory_ko_not_found(self, mock_rev_dir): # given mock_rev_dir.side_effect = NotFoundExc('Not found') # then rv = self.client.get('/api/1/revision/999/directory/some/path/to/dir/') - self.assertEquals(rv.status_code, 404) - self.assertEquals(rv['Content-Type'], 'application/json') - self.assertEquals(rv.data, { + self.assertEqual(rv.status_code, 404) + self.assertEqual(rv['Content-Type'], 'application/json') + self.assertEqual(rv.data, { 'exception': 'NotFoundExc', 'reason': 'Not found'}) mock_rev_dir.assert_called_once_with( {'sha1_git': '999'}, 'some/path/to/dir', '/api/1/revision/999/directory/some/path/to/dir/', with_data=False) @patch('swh.web.api.views.revision._revision_directory_by') def test_api_revision_directory_ok_returns_dir_entries(self, mock_rev_dir): stub_dir = { 'type': 'dir', 'revision': '999', 'content': [ { 'sha1_git': '789', 'type': 'file', 'target': '101', 'target_url': '/api/1/content/sha1_git:101/', 'name': 'somefile', 'file_url': '/api/1/revision/999/directory/some/path/' 'somefile/' }, { 'sha1_git': '123', 'type': 'dir', 'target': '456', 'target_url': '/api/1/directory/456/', 'name': 'to-subdir', 'dir_url': '/api/1/revision/999/directory/some/path/' 'to-subdir/', }] } # given mock_rev_dir.return_value = stub_dir # then rv = self.client.get('/api/1/revision/999/directory/some/path/') - self.assertEquals(rv.status_code, 200) - self.assertEquals(rv['Content-Type'], 'application/json') - self.assertEquals(rv.data, stub_dir) + self.assertEqual(rv.status_code, 200) + self.assertEqual(rv['Content-Type'], 'application/json') + self.assertEqual(rv.data, stub_dir) mock_rev_dir.assert_called_once_with( {'sha1_git': '999'}, 'some/path', '/api/1/revision/999/directory/some/path/', with_data=False) @patch('swh.web.api.views.revision._revision_directory_by') def test_api_revision_directory_ok_returns_content(self, mock_rev_dir): stub_content = { 'type': 'file', 'revision': '999', 'content': { 'sha1_git': '789', 'sha1': '101', 'data_url': '/api/1/content/101/raw/', } } # given mock_rev_dir.return_value = stub_content # then url = '/api/1/revision/666/directory/some/other/path/' rv = self.client.get(url) - self.assertEquals(rv.status_code, 200) - self.assertEquals(rv['Content-Type'], 'application/json') - self.assertEquals(rv.data, stub_content) + self.assertEqual(rv.status_code, 200) + self.assertEqual(rv['Content-Type'], 'application/json') + self.assertEqual(rv.data, stub_content) mock_rev_dir.assert_called_once_with( {'sha1_git': '666'}, 'some/other/path', url, with_data=False) diff --git a/swh/web/tests/api/views/test_snapshot.py b/swh/web/tests/api/views/test_snapshot.py index fe0f36c89..2ffaf5ba0 100644 --- a/swh/web/tests/api/views/test_snapshot.py +++ b/swh/web/tests/api/views/test_snapshot.py @@ -1,186 +1,186 @@ # Copyright (C) 2018 The Software Heritage developers # See the AUTHORS file at the top-level directory of this distribution # License: GNU Affero General Public License version 3, or any later version # See top-level LICENSE file for more information from rest_framework.test import APITestCase from unittest.mock import patch from swh.web.common.exc import BadInputExc, NotFoundExc from swh.web.common.utils import reverse from swh.web.tests.testcase import SWHWebTestCase _snapshot_id = '36ce36946fcd0f39bdfc40727af4acfce81f67af' _snapshot_branches = [ { 'name': 'refs/heads/andresgalante-dismissable-badges', 'target': '3af57e6db525015a25b4f3abb29263432e4af7b1', 'target_type': 'revision', }, { 'name': 'refs/heads/boom-toasted', 'target': 'e3f4957facfbdc25fdc4c6d3f7fcf1c488f06cea', 'target_type': 'revision', }, { 'name': 'refs/heads/flex-checks', 'target': '1b08ea1630a987d6f56f0c99e869896485bf230b', 'target_type': 'revision', }, { 'name': 'refs/heads/gh-pages', 'target': 'ea4129886adec992483aa592db717f908b4be355', 'target_type': 'revision', }, { 'name': 'refs/heads/grid-vertical-align-height', 'target': 'ba23eea651f483b88b78bee1084d7d0f61161e8d', 'target_type': 'revision', }, { 'name': 'refs/tags/v1.0.0', 'target': 'd28343dc3ad53a411ae3685e7d6a7866c8c22d6b', 'target_type': 'release', }, { 'name': 'refs/tags/v1.1.0', 'target': '0f11410b77140852f835ad456e5fbcf28760846c', 'target_type': 'release', }, { 'name': 'refs/tags/v1.1.1', 'target': '4ca26e76ee4867bfcd65ecf81039f183fc1d3b4d', 'target_type': 'release', }, { 'name': 'refs/tags/v1.2.0', 'target': 'cabae13db21e0e1db686f5628d1725c6191062ef', 'target_type': 'release', }, { 'name': 'refs/tags/v1.3.0', 'target': '3c3d596d94501509bec1959a4cfb44b20bfa8606', 'target_type': 'release', } ] def _lookup_snapshot(snapshot_id, branches_from='', branches_count=None, target_types=None): ret = {'id': snapshot_id, 'branches': {}} count = 0 for branch in _snapshot_branches: if branches_count and count == branches_count: break if branch['name'] >= branches_from: if not target_types or branch['target_type'] in target_types: # noqa ret['branches'][branch['name']] = { 'target': branch['target'], 'target_type': branch['target_type'] } count += 1 return ret def _enrich_snapshot_data(snapshot_data): for branch in snapshot_data['branches'].keys(): target = snapshot_data['branches'][branch]['target'] if snapshot_data['branches'][branch]['target_type'] == 'revision': # noqa snapshot_data['branches'][branch]['target_url'] = \ reverse('api-revision', kwargs={'sha1_git': target}) if snapshot_data['branches'][branch]['target_type'] == 'release': # noqa snapshot_data['branches'][branch]['target_url'] = \ reverse('api-release', kwargs={'sha1_git': target}) return snapshot_data @patch('swh.web.api.views.snapshot.service') class SnapshotApiTestCase(SWHWebTestCase, APITestCase): def test_api_snapshot(self, mock_service): mock_service.lookup_snapshot.side_effect = _lookup_snapshot url = reverse('api-snapshot', kwargs={'snapshot_id': _snapshot_id}) rv = self.client.get(url) - self.assertEquals(rv.status_code, 200) - self.assertEquals(rv['Content-Type'], 'application/json') + self.assertEqual(rv.status_code, 200) + self.assertEqual(rv['Content-Type'], 'application/json') expected_data = _lookup_snapshot(_snapshot_id) expected_data = _enrich_snapshot_data(expected_data) - self.assertEquals(rv.data, expected_data) + self.assertEqual(rv.data, expected_data) def test_api_snapshot_paginated(self, mock_service): mock_service.lookup_snapshot.side_effect = _lookup_snapshot branches_offset = 0 branches_count = 2 whole_snapshot = {'id': _snapshot_id, 'branches': {}} while branches_offset < len(_snapshot_branches): branches_from = _snapshot_branches[branches_offset]['name'] url = reverse('api-snapshot', kwargs={'snapshot_id': _snapshot_id}, query_params={'branches_from': branches_from, 'branches_count': branches_count}) rv = self.client.get(url) - self.assertEquals(rv.status_code, 200) - self.assertEquals(rv['Content-Type'], 'application/json') + self.assertEqual(rv.status_code, 200) + self.assertEqual(rv['Content-Type'], 'application/json') expected_data = _lookup_snapshot(_snapshot_id, branches_from, branches_count) expected_data = _enrich_snapshot_data(expected_data) - self.assertEquals(rv.data, expected_data) + self.assertEqual(rv.data, expected_data) whole_snapshot['branches'].update(expected_data['branches']) branches_offset += branches_count if branches_offset < len(_snapshot_branches): next_branch = _snapshot_branches[branches_offset]['name'] # noqa next_url = reverse('api-snapshot', kwargs={'snapshot_id': _snapshot_id}, query_params={'branches_from': next_branch, 'branches_count': branches_count}) # noqa - self.assertEquals(rv['Link'], '<%s>; rel="next"' % next_url) + self.assertEqual(rv['Link'], '<%s>; rel="next"' % next_url) else: self.assertFalse(rv.has_header('Link')) url = reverse('api-snapshot', kwargs={'snapshot_id': _snapshot_id}) rv = self.client.get(url) - self.assertEquals(rv.status_code, 200) - self.assertEquals(rv['Content-Type'], 'application/json') - self.assertEquals(rv.data, whole_snapshot) + self.assertEqual(rv.status_code, 200) + self.assertEqual(rv['Content-Type'], 'application/json') + self.assertEqual(rv.data, whole_snapshot) def test_api_snapshot_filtered(self, mock_service): mock_service.lookup_snapshot.side_effect = _lookup_snapshot target_types = 'release' url = reverse('api-snapshot', kwargs={'snapshot_id': _snapshot_id}, query_params={'target_types': target_types}) rv = self.client.get(url) - self.assertEquals(rv.status_code, 200) - self.assertEquals(rv['Content-Type'], 'application/json') + self.assertEqual(rv.status_code, 200) + self.assertEqual(rv['Content-Type'], 'application/json') expected_data = _lookup_snapshot(_snapshot_id, target_types=target_types.split(',')) expected_data = _enrich_snapshot_data(expected_data) - self.assertEquals(rv.data, expected_data) + self.assertEqual(rv.data, expected_data) def test_api_snapshot_errors(self, mock_service): mock_service.lookup_snapshot.side_effect = \ BadInputExc('Invalid snapshot id!') url = reverse('api-snapshot', kwargs={'snapshot_id': '63ce369'}) rv = self.client.get(url) - self.assertEquals(rv.status_code, 400) + self.assertEqual(rv.status_code, 400) mock_service.lookup_snapshot.side_effect = \ NotFoundExc('Snapshot not found!') snapshot_inexistent = '63ce36946fcd0f79bdfc40727af4acfce81f67fa' url = reverse('api-snapshot', kwargs={'snapshot_id': snapshot_inexistent}) rv = self.client.get(url) - self.assertEquals(rv.status_code, 404) + self.assertEqual(rv.status_code, 404) diff --git a/swh/web/tests/api/views/test_stat.py b/swh/web/tests/api/views/test_stat.py index c34c1ba73..5e179c339 100644 --- a/swh/web/tests/api/views/test_stat.py +++ b/swh/web/tests/api/views/test_stat.py @@ -1,90 +1,90 @@ # Copyright (C) 2015-2018 The Software Heritage developers # See the AUTHORS file at the top-level directory of this distribution # License: GNU Affero General Public License version 3, or any later version # See top-level LICENSE file for more information from rest_framework.test import APITestCase from unittest.mock import patch from swh.storage.exc import StorageDBError, StorageAPIError from swh.web.tests.testcase import SWHWebTestCase class StatApiTestCase(SWHWebTestCase, APITestCase): @patch('swh.web.api.views.stat.service') def test_api_1_stat_counters_raise_error(self, mock_service): # given mock_service.stat_counters.side_effect = ValueError( 'voluntary error to check the bad request middleware.') # when rv = self.client.get('/api/1/stat/counters/') # then - self.assertEquals(rv.status_code, 400) - self.assertEquals(rv['Content-Type'], 'application/json') - self.assertEquals(rv.data, { + self.assertEqual(rv.status_code, 400) + self.assertEqual(rv['Content-Type'], 'application/json') + self.assertEqual(rv.data, { 'exception': 'ValueError', 'reason': 'voluntary error to check the bad request middleware.'}) @patch('swh.web.api.views.stat.service') def test_api_1_stat_counters_raise_from_db(self, mock_service): # given mock_service.stat_counters.side_effect = StorageDBError( 'SWH Storage exploded! Will be back online shortly!') # when rv = self.client.get('/api/1/stat/counters/') # then - self.assertEquals(rv.status_code, 503) - self.assertEquals(rv['Content-Type'], 'application/json') - self.assertEquals(rv.data, { + self.assertEqual(rv.status_code, 503) + self.assertEqual(rv['Content-Type'], 'application/json') + self.assertEqual(rv.data, { 'exception': 'StorageDBError', 'reason': 'An unexpected error occurred in the backend: ' 'SWH Storage exploded! Will be back online shortly!'}) @patch('swh.web.api.views.stat.service') def test_api_1_stat_counters_raise_from_api(self, mock_service): # given mock_service.stat_counters.side_effect = StorageAPIError( 'SWH Storage API dropped dead! Will resurrect from its ashes asap!' ) # when rv = self.client.get('/api/1/stat/counters/') # then - self.assertEquals(rv.status_code, 503) - self.assertEquals(rv['Content-Type'], 'application/json') - self.assertEquals(rv.data, { + self.assertEqual(rv.status_code, 503) + self.assertEqual(rv['Content-Type'], 'application/json') + self.assertEqual(rv.data, { 'exception': 'StorageAPIError', 'reason': 'An unexpected error occurred in the api backend: ' 'SWH Storage API dropped dead! Will resurrect from its ashes asap!' }) @patch('swh.web.api.views.stat.service') def test_api_1_stat_counters(self, mock_service): # given stub_stats = { "content": 1770830, "directory": 211683, "directory_entry_dir": 209167, "directory_entry_file": 1807094, "directory_entry_rev": 0, "entity": 0, "entity_history": 0, "origin": 1096, "person": 0, "release": 8584, "revision": 7792, "revision_history": 0, "skipped_content": 0 } mock_service.stat_counters.return_value = stub_stats # when rv = self.client.get('/api/1/stat/counters/') - self.assertEquals(rv.status_code, 200) - self.assertEquals(rv['Content-Type'], 'application/json') - self.assertEquals(rv.data, stub_stats) + self.assertEqual(rv.status_code, 200) + self.assertEqual(rv['Content-Type'], 'application/json') + self.assertEqual(rv.data, stub_stats) mock_service.stat_counters.assert_called_once_with() diff --git a/swh/web/tests/api/views/test_vault.py b/swh/web/tests/api/views/test_vault.py index e9980359c..14b84c3cd 100644 --- a/swh/web/tests/api/views/test_vault.py +++ b/swh/web/tests/api/views/test_vault.py @@ -1,83 +1,83 @@ # Copyright (C) 2017-2018 The Software Heritage developers # See the AUTHORS file at the top-level directory of this distribution # License: GNU Affero General Public License version 3, or any later version # See top-level LICENSE file for more information from rest_framework.test import APITestCase from unittest.mock import patch from swh.model import hashutil from swh.web.tests.testcase import SWHWebTestCase TEST_OBJ_ID = 'd4905454cc154b492bd6afed48694ae3c579345e' OBJECT_TYPES = {'directory': ('directory', None), 'revision_gitfast': ('revision', 'gitfast')} class VaultApiTestCase(SWHWebTestCase, APITestCase): @patch('swh.web.api.views.vault.service') def test_api_vault_cook(self, mock_service): stub_cook = { 'fetch_url': ('http://127.0.0.1:5004/api/1/vault/directory/{}/raw/' .format(TEST_OBJ_ID)), 'obj_id': 'd4905454cc154b492bd6afed48694ae3c579345e', 'obj_type': 'test_type', 'progress_message': None, 'status': 'done', 'task_uuid': 'de75c902-5ee5-4739-996e-448376a93eff', } stub_fetch = b'content' mock_service.vault_cook.return_value = stub_cook mock_service.vault_fetch.return_value = stub_fetch for obj_type, (obj_type_name, obj_type_format) in OBJECT_TYPES.items(): url = '/api/1/vault/{}/{}/'.format(obj_type_name, TEST_OBJ_ID) if obj_type_format: url += '{}/'.format(obj_type_format) rv = self.client.post(url, {'email': 'test@test.mail'}) - self.assertEquals(rv.status_code, 200) - self.assertEquals(rv['Content-Type'], 'application/json') + self.assertEqual(rv.status_code, 200) + self.assertEqual(rv['Content-Type'], 'application/json') - self.assertEquals(rv.data, stub_cook) + self.assertEqual(rv.data, stub_cook) mock_service.vault_cook.assert_called_with( obj_type, hashutil.hash_to_bytes(TEST_OBJ_ID), 'test@test.mail') rv = self.client.get(url + 'raw/') - self.assertEquals(rv.status_code, 200) - self.assertEquals(rv['Content-Type'], 'application/gzip') - self.assertEquals(rv.content, stub_fetch) + self.assertEqual(rv.status_code, 200) + self.assertEqual(rv['Content-Type'], 'application/gzip') + self.assertEqual(rv.content, stub_fetch) mock_service.vault_fetch.assert_called_with( obj_type, hashutil.hash_to_bytes(TEST_OBJ_ID)) @patch('swh.web.api.views.vault.service') def test_api_vault_cook_notfound(self, mock_service): mock_service.vault_cook.return_value = None mock_service.vault_fetch.return_value = None for obj_type, (obj_type_name, obj_type_format) in OBJECT_TYPES.items(): url = '/api/1/vault/{}/{}/'.format(obj_type_name, TEST_OBJ_ID) if obj_type_format: url += '{}/'.format(obj_type_format) rv = self.client.post(url) - self.assertEquals(rv.status_code, 404) - self.assertEquals(rv['Content-Type'], 'application/json') + self.assertEqual(rv.status_code, 404) + self.assertEqual(rv['Content-Type'], 'application/json') - self.assertEquals(rv.data['exception'], 'NotFoundExc') + self.assertEqual(rv.data['exception'], 'NotFoundExc') mock_service.vault_cook.assert_called_with( obj_type, hashutil.hash_to_bytes(TEST_OBJ_ID), None) rv = self.client.get(url + 'raw/') - self.assertEquals(rv.status_code, 404) - self.assertEquals(rv['Content-Type'], 'application/json') - self.assertEquals(rv.data['exception'], 'NotFoundExc') + self.assertEqual(rv.status_code, 404) + self.assertEqual(rv['Content-Type'], 'application/json') + self.assertEqual(rv.data['exception'], 'NotFoundExc') mock_service.vault_fetch.assert_called_with( obj_type, hashutil.hash_to_bytes(TEST_OBJ_ID)) diff --git a/swh/web/tests/browse/views/test_content.py b/swh/web/tests/browse/views/test_content.py index a4d0cbf69..379f1da51 100644 --- a/swh/web/tests/browse/views/test_content.py +++ b/swh/web/tests/browse/views/test_content.py @@ -1,315 +1,315 @@ # Copyright (C) 2017-2018 The Software Heritage developers # See the AUTHORS file at the top-level directory of this distribution # License: GNU Affero General Public License version 3, or any later version # See top-level LICENSE file for more information import base64 from unittest.mock import patch from django.utils.html import escape from django.utils.encoding import DjangoUnicodeDecodeError from swh.web.browse.utils import get_mimetype_and_encoding_for_content from swh.web.common.exc import NotFoundExc from swh.web.common.utils import reverse, get_swh_persistent_id from swh.web.common.utils import gen_path_info from swh.web.tests.testcase import SWHWebTestCase from .data.content_test_data import ( stub_content_text_data, stub_content_text_path_with_root_dir, stub_content_bin_data, stub_content_bin_filename, stub_content_text_no_highlight_data, non_utf8_encoded_content_data, non_utf8_encoded_content, non_utf8_encoding, stub_content_too_large_data ) class SwhBrowseContentTest(SWHWebTestCase): @patch('swh.web.browse.views.content.request_content') def test_content_view_text(self, mock_request_content): mock_request_content.return_value = stub_content_text_data sha1_git = stub_content_text_data['checksums']['sha1_git'] url = reverse('browse-content', kwargs={'query_string': stub_content_text_data['checksums']['sha1']}) # noqa url_raw = reverse('browse-content-raw', kwargs={'query_string': stub_content_text_data['checksums']['sha1']}) # noqa resp = self.client.get(url) - self.assertEquals(resp.status_code, 200) + self.assertEqual(resp.status_code, 200) self.assertTemplateUsed('browse/content.html') self.assertContains(resp, '') self.assertContains(resp, escape(stub_content_text_data['raw_data'])) self.assertContains(resp, url_raw) swh_cnt_id = get_swh_persistent_id('content', sha1_git) swh_cnt_id_url = reverse('browse-swh-id', kwargs={'swh_id': swh_cnt_id}) self.assertContains(resp, swh_cnt_id) self.assertContains(resp, swh_cnt_id_url) @patch('swh.web.browse.views.content.request_content') def test_content_view_text_no_highlight(self, mock_request_content): mock_request_content.return_value = stub_content_text_no_highlight_data sha1_git = stub_content_text_no_highlight_data['checksums']['sha1_git'] url = reverse('browse-content', kwargs={'query_string': stub_content_text_no_highlight_data['checksums']['sha1']}) # noqa url_raw = reverse('browse-content-raw', kwargs={'query_string': stub_content_text_no_highlight_data['checksums']['sha1']}) # noqa resp = self.client.get(url) - self.assertEquals(resp.status_code, 200) + self.assertEqual(resp.status_code, 200) self.assertTemplateUsed('browse/content.html') self.assertContains(resp, '') self.assertContains(resp, escape(stub_content_text_no_highlight_data['raw_data'])) # noqa self.assertContains(resp, url_raw) swh_cnt_id = get_swh_persistent_id('content', sha1_git) swh_cnt_id_url = reverse('browse-swh-id', kwargs={'swh_id': swh_cnt_id}) self.assertContains(resp, swh_cnt_id) self.assertContains(resp, swh_cnt_id_url) @patch('swh.web.browse.utils.service') def test_content_view_no_utf8_text(self, mock_service): mock_service.lookup_content.return_value = \ non_utf8_encoded_content_data mock_service.lookup_content_raw.return_value = \ {'data': non_utf8_encoded_content} mock_service.lookup_content_filetype.return_value = None mock_service.lookup_content_language.return_value = None mock_service.lookup_content_license.return_value = None sha1_git = non_utf8_encoded_content_data['checksums']['sha1_git'] url = reverse('browse-content', kwargs={'query_string': non_utf8_encoded_content_data['checksums']['sha1']}) # noqa try: resp = self.client.get(url) - self.assertEquals(resp.status_code, 200) + self.assertEqual(resp.status_code, 200) self.assertTemplateUsed('browse/content.html') swh_cnt_id = get_swh_persistent_id('content', sha1_git) swh_cnt_id_url = reverse('browse-swh-id', kwargs={'swh_id': swh_cnt_id}) self.assertContains(resp, swh_cnt_id_url) self.assertContains(resp, escape(non_utf8_encoded_content.decode(non_utf8_encoding).encode('utf-8'))) # noqa except DjangoUnicodeDecodeError: self.fail('Textual content is not encoded in utf-8') @patch('swh.web.browse.views.content.request_content') def test_content_view_image(self, mock_request_content): mime_type = 'image/png' mock_request_content.return_value = stub_content_bin_data url = reverse('browse-content', kwargs={'query_string': stub_content_bin_data['checksums']['sha1']}) # noqa url_raw = reverse('browse-content-raw', kwargs={'query_string': stub_content_bin_data['checksums']['sha1']}) # noqa resp = self.client.get(url) - self.assertEquals(resp.status_code, 200) + self.assertEqual(resp.status_code, 200) self.assertTemplateUsed('browse/content.html') png_encoded = base64.b64encode(stub_content_bin_data['raw_data']) \ .decode('utf-8') self.assertContains(resp, '' % (mime_type, png_encoded)) self.assertContains(resp, url_raw) @patch('swh.web.browse.views.content.request_content') def test_content_view_with_path(self, mock_request_content): mock_request_content.return_value = stub_content_text_data url = reverse('browse-content', kwargs={'query_string': stub_content_text_data['checksums']['sha1']}, # noqa query_params={'path': stub_content_text_path_with_root_dir}) # noqa resp = self.client.get(url) - self.assertEquals(resp.status_code, 200) + self.assertEqual(resp.status_code, 200) self.assertTemplateUsed('browse/content.html') self.assertContains(resp, '') self.assertContains(resp, escape(stub_content_text_data['raw_data'])) split_path = stub_content_text_path_with_root_dir.split('/') root_dir_sha1 = split_path[0] filename = split_path[-1] path = stub_content_text_path_with_root_dir \ .replace(root_dir_sha1 + '/', '') \ .replace(filename, '') path_info = gen_path_info(path) root_dir_url = reverse('browse-directory', kwargs={'sha1_git': root_dir_sha1}) self.assertContains(resp, '
  • ', count=len(path_info)+1) self.assertContains(resp, '' + root_dir_sha1[:7] + '') for p in path_info: dir_url = reverse('browse-directory', kwargs={'sha1_git': root_dir_sha1, 'path': p['path']}) self.assertContains(resp, '' + p['name'] + '') self.assertContains(resp, '
  • ' + filename + '
  • ') url_raw = reverse('browse-content-raw', kwargs={'query_string': stub_content_text_data['checksums']['sha1']}, # noqa query_params={'filename': filename}) self.assertContains(resp, url_raw) @patch('swh.web.browse.views.content.request_content') def test_content_raw_text(self, mock_request_content): mock_request_content.return_value = stub_content_text_data url = reverse('browse-content-raw', kwargs={'query_string': stub_content_text_data['checksums']['sha1']}) # noqa resp = self.client.get(url) - self.assertEquals(resp.status_code, 200) + self.assertEqual(resp.status_code, 200) self.assertEqual(resp['Content-Type'], 'text/plain') self.assertEqual(resp['Content-disposition'], 'filename=%s_%s' % ('sha1', stub_content_text_data['checksums']['sha1'])) # noqa self.assertEqual(resp.content, stub_content_text_data['raw_data']) filename = stub_content_text_path_with_root_dir.split('/')[-1] url = reverse('browse-content-raw', kwargs={'query_string': stub_content_text_data['checksums']['sha1']}, # noqa query_params={'filename': filename}) resp = self.client.get(url) - self.assertEquals(resp.status_code, 200) + self.assertEqual(resp.status_code, 200) self.assertEqual(resp['Content-Type'], 'text/plain') self.assertEqual(resp['Content-disposition'], 'filename=%s' % filename) self.assertEqual(resp.content, stub_content_text_data['raw_data']) @patch('swh.web.browse.utils.service') def test_content_raw_no_utf8_text(self, mock_service): mock_service.lookup_content.return_value = \ non_utf8_encoded_content_data mock_service.lookup_content_raw.return_value = \ {'data': non_utf8_encoded_content} mock_service.lookup_content_filetype.return_value = None mock_service.lookup_content_language.return_value = None mock_service.lookup_content_license.return_value = None url = reverse('browse-content-raw', kwargs={'query_string': non_utf8_encoded_content_data['checksums']['sha1']}) # noqa resp = self.client.get(url) - self.assertEquals(resp.status_code, 200) + self.assertEqual(resp.status_code, 200) _, encoding = get_mimetype_and_encoding_for_content(resp.content) self.assertEqual(encoding, non_utf8_encoding) @patch('swh.web.browse.views.content.request_content') def test_content_raw_bin(self, mock_request_content): mock_request_content.return_value = stub_content_bin_data url = reverse('browse-content-raw', kwargs={'query_string': stub_content_bin_data['checksums']['sha1']}) # noqa resp = self.client.get(url) - self.assertEquals(resp.status_code, 200) + self.assertEqual(resp.status_code, 200) self.assertEqual(resp['Content-Type'], 'application/octet-stream') self.assertEqual(resp['Content-disposition'], 'attachment; filename=%s_%s' % ('sha1', stub_content_bin_data['checksums']['sha1'])) self.assertEqual(resp.content, stub_content_bin_data['raw_data']) url = reverse('browse-content-raw', kwargs={'query_string': stub_content_bin_data['checksums']['sha1']}, # noqa query_params={'filename': stub_content_bin_filename}) resp = self.client.get(url) - self.assertEquals(resp.status_code, 200) + self.assertEqual(resp.status_code, 200) self.assertEqual(resp['Content-Type'], 'application/octet-stream') self.assertEqual(resp['Content-disposition'], 'attachment; filename=%s' % stub_content_bin_filename) self.assertEqual(resp.content, stub_content_bin_data['raw_data']) @patch('swh.web.browse.views.content.request_content') def test_content_request_errors(self, mock_request_content): url = reverse('browse-content', kwargs={'query_string': '123456'}) resp = self.client.get(url) - self.assertEquals(resp.status_code, 400) + self.assertEqual(resp.status_code, 400) self.assertTemplateUsed('error.html') mock_request_content.side_effect = NotFoundExc('content not found') url = reverse('browse-content', kwargs={'query_string': stub_content_text_data['checksums']['sha1']}) # noqa resp = self.client.get(url) - self.assertEquals(resp.status_code, 404) + self.assertEqual(resp.status_code, 404) self.assertTemplateUsed('error.html') @patch('swh.web.browse.utils.service') def test_content_bytes_missing(self, mock_service): content_data = dict(stub_content_text_data) content_data['raw_data'] = None mock_service.lookup_content.return_value = content_data mock_service.lookup_content_raw.side_effect = NotFoundExc('Content bytes not available!') # noqa url = reverse('browse-content', kwargs={'query_string': content_data['checksums']['sha1']}) # noqa resp = self.client.get(url) - self.assertEquals(resp.status_code, 404) + self.assertEqual(resp.status_code, 404) self.assertTemplateUsed('browse/content.html') @patch('swh.web.browse.views.content.request_content') def test_content_too_large(self, mock_request_content): mock_request_content.return_value = stub_content_too_large_data url = reverse('browse-content', kwargs={'query_string': stub_content_too_large_data['checksums']['sha1']}) # noqa url_raw = reverse('browse-content-raw', kwargs={'query_string': stub_content_too_large_data['checksums']['sha1']}) # noqa resp = self.client.get(url) - self.assertEquals(resp.status_code, 200) + self.assertEqual(resp.status_code, 200) self.assertTemplateUsed('browse/content.html') self.assertContains(resp, 'Content is too large to be displayed') self.assertContains(resp, url_raw) diff --git a/swh/web/tests/browse/views/test_directory.py b/swh/web/tests/browse/views/test_directory.py index 6b90d9ca9..e7df1b919 100644 --- a/swh/web/tests/browse/views/test_directory.py +++ b/swh/web/tests/browse/views/test_directory.py @@ -1,135 +1,135 @@ # Copyright (C) 2017-2018 The Software Heritage developers # See the AUTHORS file at the top-level directory of this distribution # License: GNU Affero General Public License version 3, or any later version # See top-level LICENSE file for more information from unittest.mock import patch from swh.web.common.exc import BadInputExc, NotFoundExc from swh.web.common.utils import reverse, get_swh_persistent_id from swh.web.common.utils import gen_path_info from swh.web.tests.testcase import SWHWebTestCase from .data.directory_test_data import ( stub_root_directory_sha1, stub_root_directory_data, stub_sub_directory_path, stub_sub_directory_data ) class SwhBrowseDirectoryTest(SWHWebTestCase): def directory_view(self, root_directory_sha1, directory_entries, path=None): dirs = [e for e in directory_entries if e['type'] in ('dir', 'rev')] files = [e for e in directory_entries if e['type'] == 'file'] url_args = {'sha1_git': root_directory_sha1} if path: url_args['path'] = path url = reverse('browse-directory', kwargs=url_args) root_dir_url = reverse('browse-directory', kwargs={'sha1_git': root_directory_sha1}) resp = self.client.get(url) - self.assertEquals(resp.status_code, 200) + self.assertEqual(resp.status_code, 200) self.assertTemplateUsed('browse/directory.html') self.assertContains(resp, '' + root_directory_sha1[:7] + '') self.assertContains(resp, '', count=len(dirs)) self.assertContains(resp, '', count=len(files)) for d in dirs: if d['type'] == 'rev': dir_url = reverse('browse-revision', kwargs={'sha1_git': d['target']}) else: dir_path = d['name'] if path: dir_path = "%s/%s" % (path, d['name']) dir_url = reverse('browse-directory', kwargs={'sha1_git': root_directory_sha1, 'path': dir_path}) self.assertContains(resp, dir_url) for f in files: file_path = "%s/%s" % (root_directory_sha1, f['name']) if path: file_path = "%s/%s/%s" % (root_directory_sha1, path, f['name']) query_string = 'sha1_git:' + f['target'] file_url = reverse('browse-content', kwargs={'query_string': query_string}, query_params={'path': file_path}) self.assertContains(resp, file_url) path_info = gen_path_info(path) self.assertContains(resp, '
  • ', count=len(path_info)+1) self.assertContains(resp, '%s' % (root_dir_url, root_directory_sha1[:7])) for p in path_info: dir_url = reverse('browse-directory', kwargs={'sha1_git': root_directory_sha1, 'path': p['path']}) self.assertContains(resp, '%s' % (dir_url, p['name'])) self.assertContains(resp, 'vault-cook-directory') swh_dir_id = get_swh_persistent_id('directory', directory_entries[0]['dir_id']) # noqa swh_dir_id_url = reverse('browse-swh-id', kwargs={'swh_id': swh_dir_id}) self.assertContains(resp, swh_dir_id) self.assertContains(resp, swh_dir_id_url) @patch('swh.web.browse.utils.service') def test_root_directory_view(self, mock_service): mock_service.lookup_directory.return_value = \ stub_root_directory_data self.directory_view(stub_root_directory_sha1, stub_root_directory_data) @patch('swh.web.browse.utils.service') @patch('swh.web.browse.views.directory.service') def test_sub_directory_view(self, mock_directory_service, mock_utils_service): mock_utils_service.lookup_directory.return_value = \ stub_sub_directory_data mock_directory_service.lookup_directory_with_path.return_value = \ {'target': stub_sub_directory_data[0]['dir_id'], 'type': 'dir'} self.directory_view(stub_root_directory_sha1, stub_sub_directory_data, stub_sub_directory_path) @patch('swh.web.browse.utils.service') @patch('swh.web.browse.views.directory.service') def test_directory_request_errors(self, mock_directory_service, mock_utils_service): mock_utils_service.lookup_directory.side_effect = \ BadInputExc('directory not found') dir_url = reverse('browse-directory', kwargs={'sha1_git': '1253456'}) resp = self.client.get(dir_url) - self.assertEquals(resp.status_code, 400) + self.assertEqual(resp.status_code, 400) self.assertTemplateUsed('browse/error.html') mock_utils_service.lookup_directory.side_effect = \ NotFoundExc('directory not found') dir_url = reverse('browse-directory', kwargs={'sha1_git': '1253456'}) resp = self.client.get(dir_url) - self.assertEquals(resp.status_code, 404) + self.assertEqual(resp.status_code, 404) self.assertTemplateUsed('browse/error.html') diff --git a/swh/web/tests/browse/views/test_identifiers.py b/swh/web/tests/browse/views/test_identifiers.py index 844f38653..a2d8ea178 100644 --- a/swh/web/tests/browse/views/test_identifiers.py +++ b/swh/web/tests/browse/views/test_identifiers.py @@ -1,136 +1,136 @@ # Copyright (C) 2018 The Software Heritage developers # See the AUTHORS file at the top-level directory of this distribution # License: GNU Affero General Public License version 3, or any later version # See top-level LICENSE file for more information # flake8: noqa from unittest.mock import patch from swh.web.common.exc import BadInputExc from swh.web.common.utils import reverse from swh.web.tests.testcase import SWHWebTestCase from .data.content_test_data import stub_content_text_data from .data.directory_test_data import stub_root_directory_sha1 from .data.revision_test_data import revision_id_test from .data.release_test_data import stub_release swh_id_prefix = 'swh:1:' class SwhBrowseIdTest(SWHWebTestCase): def test_content_id_browse(self): cnt_sha1_git = stub_content_text_data['checksums']['sha1_git'] swh_id = swh_id_prefix + 'cnt:' + cnt_sha1_git url = reverse('browse-swh-id', kwargs={'swh_id': swh_id}) query_string = 'sha1_git:' + cnt_sha1_git content_browse_url = reverse('browse-content', kwargs={'query_string': query_string}) resp = self.client.get(url) - self.assertEquals(resp.status_code, 302) + self.assertEqual(resp.status_code, 302) self.assertEqual(resp['location'], content_browse_url) def test_directory_id_browse(self): swh_id = swh_id_prefix + 'dir:' + stub_root_directory_sha1 url = reverse('browse-swh-id', kwargs={'swh_id': swh_id}) directory_browse_url = reverse('browse-directory', kwargs={'sha1_git': stub_root_directory_sha1}) resp = self.client.get(url) - self.assertEquals(resp.status_code, 302) + self.assertEqual(resp.status_code, 302) self.assertEqual(resp['location'], directory_browse_url) def test_revision_id_browse(self): swh_id = swh_id_prefix + 'rev:' + revision_id_test url = reverse('browse-swh-id', kwargs={'swh_id': swh_id}) revision_browse_url = reverse('browse-revision', kwargs={'sha1_git': revision_id_test}) resp = self.client.get(url) - self.assertEquals(resp.status_code, 302) + self.assertEqual(resp.status_code, 302) self.assertEqual(resp['location'], revision_browse_url) query_params = {'origin_type': 'git', 'origin': 'https://github.com/webpack/webpack'} url = reverse('browse-swh-id', kwargs={'swh_id': swh_id}, query_params=query_params) revision_browse_url = reverse('browse-revision', kwargs={'sha1_git': revision_id_test}, query_params=query_params) resp = self.client.get(url) - self.assertEquals(resp.status_code, 302) + self.assertEqual(resp.status_code, 302) self.assertEqual(resp['location'], revision_browse_url) def test_release_id_browse(self): swh_id = swh_id_prefix + 'rel:' + stub_release['id'] url = reverse('browse-swh-id', kwargs={'swh_id': swh_id}) release_browse_url = reverse('browse-release', kwargs={'sha1_git': stub_release['id']}) resp = self.client.get(url) - self.assertEquals(resp.status_code, 302) + self.assertEqual(resp.status_code, 302) self.assertEqual(resp['location'], release_browse_url) query_params = {'origin_type': 'git', 'origin': 'https://github.com/python/cpython'} url = reverse('browse-swh-id', kwargs={'swh_id': swh_id}, query_params=query_params) release_browse_url = reverse('browse-release', kwargs={'sha1_git': stub_release['id']}, query_params=query_params) resp = self.client.get(url) - self.assertEquals(resp.status_code, 302) + self.assertEqual(resp.status_code, 302) self.assertEqual(resp['location'], release_browse_url) def test_bad_id_browse(self): swh_id = swh_id_prefix + 'foo:' + stub_release['id'] url = reverse('browse-swh-id', kwargs={'swh_id': swh_id}) resp = self.client.get(url) - self.assertEquals(resp.status_code, 400) + self.assertEqual(resp.status_code, 400) def test_content_id_optional_parts_browse(self): cnt_sha1_git = stub_content_text_data['checksums']['sha1_git'] optional_parts = ';lines=4-20;origin=https://github.com/user/repo' swh_id = swh_id_prefix + 'cnt:' + cnt_sha1_git + optional_parts url = reverse('browse-swh-id', kwargs={'swh_id': swh_id}) query_string = 'sha1_git:' + cnt_sha1_git content_browse_url = reverse('browse-content', kwargs={'query_string': query_string}, query_params={'origin' : 'https://github.com/user/repo'}) content_browse_url += '#L4-L20' resp = self.client.get(url) - self.assertEquals(resp.status_code, 302) + self.assertEqual(resp.status_code, 302) self.assertEqual(resp['location'], content_browse_url) diff --git a/swh/web/tests/browse/views/test_origin.py b/swh/web/tests/browse/views/test_origin.py index 70642553d..c70005cd6 100644 --- a/swh/web/tests/browse/views/test_origin.py +++ b/swh/web/tests/browse/views/test_origin.py @@ -1,883 +1,883 @@ # Copyright (C) 2017-2018 The Software Heritage developers # See the AUTHORS file at the top-level directory of this distribution # License: GNU Affero General Public License version 3, or any later version # See top-level LICENSE file for more information # flake8: noqa from unittest.mock import patch from django.utils.html import escape from swh.web.common.exc import NotFoundExc from swh.web.common.utils import ( reverse, gen_path_info, format_utc_iso_date, parse_timestamp, get_swh_persistent_id ) from swh.web.tests.testcase import SWHWebTestCase from .data.origin_test_data import ( origin_info_test_data, origin_visits_test_data, stub_content_origin_info, stub_content_origin_visit_id, stub_content_origin_visit_unix_ts, stub_content_origin_visit_iso_date, stub_content_origin_branch, stub_content_origin_visits, stub_content_origin_snapshot, stub_origin_info, stub_visit_id, stub_origin_visits, stub_origin_snapshot, stub_origin_root_directory_entries, stub_origin_master_branch, stub_origin_root_directory_sha1, stub_origin_sub_directory_path, stub_origin_sub_directory_entries, stub_visit_unix_ts, stub_visit_iso_date ) from .data.content_test_data import ( stub_content_root_dir, stub_content_text_data, stub_content_text_path ) stub_origin_info_no_type = dict(stub_origin_info) stub_origin_info_no_type['type'] = None def _to_snapshot_dict(branches=None, releases=None): snp = {'branches': {}} if branches: for b in branches: snp['branches'][b['name']] = { 'target': b['revision'], 'target_type': 'revision' } if releases: for r in releases: snp['branches'][r['branch_name']] = { 'target': r['id'], 'target_type': 'release' } return snp class SwhBrowseOriginTest(SWHWebTestCase): @patch('swh.web.browse.utils.service') @patch('swh.web.browse.utils.get_origin_visit_snapshot') @patch('swh.web.browse.utils.get_origin_visits') @patch('swh.web.browse.utils.get_origin_info') @patch('swh.web.browse.views.origin.get_origin_info') @patch('swh.web.browse.views.origin.get_origin_visits') @patch('swh.web.browse.views.origin.service') def test_origin_visits_browse(self, mock_service, mock_get_origin_visits, mock_get_origin_info, mock_get_origin_info_utils, mock_get_origin_visits_utils, mock_get_origin_visit_snapshot, mock_utils_service): mock_service.lookup_origin.return_value = origin_info_test_data mock_get_origin_info.return_value = origin_info_test_data mock_get_origin_info_utils.return_value = origin_info_test_data mock_get_origin_visits.return_value = origin_visits_test_data mock_get_origin_visits_utils.return_value = origin_visits_test_data mock_get_origin_visit_snapshot.return_value = stub_content_origin_snapshot mock_utils_service.lookup_snapshot_size.return_value = { 'revision': len(stub_content_origin_snapshot[0]), 'release': len(stub_content_origin_snapshot[1]) } url = reverse('browse-origin-visits', kwargs={'origin_type': origin_info_test_data['type'], 'origin_url': origin_info_test_data['url']}) resp = self.client.get(url) - self.assertEquals(resp.status_code, 200) + self.assertEqual(resp.status_code, 200) self.assertTemplateUsed('origin-visits.html') url = reverse('browse-origin-visits', kwargs={'origin_url': origin_info_test_data['url']}) resp = self.client.get(url) - self.assertEquals(resp.status_code, 200) + self.assertEqual(resp.status_code, 200) self.assertTemplateUsed('origin-visits.html') def origin_content_view_helper(self, origin_info, origin_visits, origin_branches, origin_releases, origin_branch, root_dir_sha1, content_sha1, content_sha1_git, content_path, content_data, content_language, visit_id=None, timestamp=None): url_args = {'origin_type': origin_info['type'], 'origin_url': origin_info['url'], 'path': content_path} if not visit_id: visit_id = origin_visits[-1]['visit'] query_params = {} if timestamp: url_args['timestamp'] = timestamp if visit_id: query_params['visit_id'] = visit_id url = reverse('browse-origin-content', kwargs=url_args, query_params=query_params) resp = self.client.get(url) - self.assertEquals(resp.status_code, 200) + self.assertEqual(resp.status_code, 200) self.assertTemplateUsed('content.html') self.assertContains(resp, '' % content_language) self.assertContains(resp, escape(content_data)) split_path = content_path.split('/') filename = split_path[-1] path = content_path.replace(filename, '')[:-1] path_info = gen_path_info(path) del url_args['path'] if timestamp: url_args['timestamp'] = \ format_utc_iso_date(parse_timestamp(timestamp).isoformat(), '%Y-%m-%dT%H:%M:%S') root_dir_url = reverse('browse-origin-directory', kwargs=url_args, query_params=query_params) self.assertContains(resp, '
  • ', count=len(path_info)+1) self.assertContains(resp, '%s' % (root_dir_url, root_dir_sha1[:7])) for p in path_info: url_args['path'] = p['path'] dir_url = reverse('browse-origin-directory', kwargs=url_args, query_params=query_params) self.assertContains(resp, '%s' % (dir_url, p['name'])) self.assertContains(resp, '
  • %s
  • ' % filename) query_string = 'sha1_git:' + content_sha1 url_raw = reverse('browse-content-raw', kwargs={'query_string': query_string}, query_params={'filename': filename}) self.assertContains(resp, url_raw) del url_args['path'] origin_branches_url = \ reverse('browse-origin-branches', kwargs=url_args, query_params=query_params) self.assertContains(resp, 'Branches (%s)' % (origin_branches_url, len(origin_branches))) origin_releases_url = \ reverse('browse-origin-releases', kwargs=url_args, query_params=query_params) self.assertContains(resp, 'Releases (%s)' % (origin_releases_url, len(origin_releases))) self.assertContains(resp, '
  • ', count=len(origin_branches)) url_args['path'] = content_path for branch in origin_branches: query_params['branch'] = branch['name'] root_dir_branch_url = \ reverse('browse-origin-content', kwargs=url_args, query_params=query_params) self.assertContains(resp, '' % root_dir_branch_url) self.assertContains(resp, '
  • ', count=len(origin_releases)) query_params['branch'] = None for release in origin_releases: query_params['release'] = release['name'] root_dir_release_url = \ reverse('browse-origin-content', kwargs=url_args, query_params=query_params) self.assertContains(resp, '' % root_dir_release_url) del url_args['origin_type'] url = reverse('browse-origin-content', kwargs=url_args, query_params=query_params) resp = self.client.get(url) - self.assertEquals(resp.status_code, 200) + self.assertEqual(resp.status_code, 200) self.assertTemplateUsed('content.html') swh_cnt_id = get_swh_persistent_id('content', content_sha1_git) swh_cnt_id_url = reverse('browse-swh-id', kwargs={'swh_id': swh_cnt_id}) self.assertContains(resp, swh_cnt_id) self.assertContains(resp, swh_cnt_id_url) @patch('swh.web.browse.utils.get_origin_visits') @patch('swh.web.browse.utils.get_origin_visit_snapshot') @patch('swh.web.browse.views.utils.snapshot_context.service') @patch('swh.web.browse.utils.service') @patch('swh.web.browse.views.utils.snapshot_context.request_content') def test_origin_content_view(self, mock_request_content, mock_utils_service, mock_service, mock_get_origin_visit_snapshot, mock_get_origin_visits): stub_content_text_sha1 = stub_content_text_data['checksums']['sha1'] stub_content_text_sha1_git = stub_content_text_data['checksums']['sha1_git'] mock_get_origin_visits.return_value = stub_content_origin_visits mock_get_origin_visit_snapshot.return_value = stub_content_origin_snapshot mock_service.lookup_directory_with_path.return_value = \ {'target': stub_content_text_sha1} mock_request_content.return_value = stub_content_text_data mock_utils_service.lookup_origin.return_value = stub_content_origin_info mock_utils_service.lookup_snapshot_size.return_value = { 'revision': len(stub_content_origin_snapshot[0]), 'release': len(stub_content_origin_snapshot[1]) } self.origin_content_view_helper(stub_content_origin_info, stub_content_origin_visits, stub_content_origin_snapshot[0], stub_content_origin_snapshot[1], stub_content_origin_branch, stub_content_root_dir, stub_content_text_sha1, stub_content_text_sha1_git, stub_content_text_path, stub_content_text_data['raw_data'], 'cpp') self.origin_content_view_helper(stub_content_origin_info, stub_content_origin_visits, stub_content_origin_snapshot[0], stub_content_origin_snapshot[1], stub_content_origin_branch, stub_content_root_dir, stub_content_text_sha1, stub_content_text_sha1_git, stub_content_text_path, stub_content_text_data['raw_data'], 'cpp', visit_id=stub_content_origin_visit_id) self.origin_content_view_helper(stub_content_origin_info, stub_content_origin_visits, stub_content_origin_snapshot[0], stub_content_origin_snapshot[1], stub_content_origin_branch, stub_content_root_dir, stub_content_text_sha1, stub_content_text_sha1_git, stub_content_text_path, stub_content_text_data['raw_data'], 'cpp', timestamp=stub_content_origin_visit_unix_ts) self.origin_content_view_helper(stub_content_origin_info, stub_content_origin_visits, stub_content_origin_snapshot[0], stub_content_origin_snapshot[1], stub_content_origin_branch, stub_content_root_dir, stub_content_text_sha1, stub_content_text_sha1_git, stub_content_text_path, stub_content_text_data['raw_data'], 'cpp', timestamp=stub_content_origin_visit_iso_date) def origin_directory_view_helper(self, origin_info, origin_visits, origin_branches, origin_releases, origin_branch, root_directory_sha1, directory_entries, visit_id=None, timestamp=None, path=None): dirs = [e for e in directory_entries if e['type'] in ('dir', 'rev')] files = [e for e in directory_entries if e['type'] == 'file'] if not visit_id: visit_id = origin_visits[-1]['visit'] url_args = {'origin_url': origin_info['url']} query_params = {} if timestamp: url_args['timestamp'] = timestamp else: query_params['visit_id'] = visit_id if path: url_args['path'] = path url = reverse('browse-origin-directory', kwargs=url_args, query_params=query_params) resp = self.client.get(url) - self.assertEquals(resp.status_code, 200) + self.assertEqual(resp.status_code, 200) self.assertTemplateUsed('directory.html') - self.assertEquals(resp.status_code, 200) + self.assertEqual(resp.status_code, 200) self.assertTemplateUsed('directory.html') self.assertContains(resp, '', count=len(dirs)) self.assertContains(resp, '', count=len(files)) if timestamp: url_args['timestamp'] = \ format_utc_iso_date(parse_timestamp(timestamp).isoformat(), '%Y-%m-%dT%H:%M:%S') for d in dirs: if d['type'] == 'rev': dir_url = reverse('browse-revision', kwargs={'sha1_git': d['target']}) else: dir_path = d['name'] if path: dir_path = "%s/%s" % (path, d['name']) dir_url_args = dict(url_args) dir_url_args['path'] = dir_path dir_url = reverse('browse-origin-directory', kwargs=dir_url_args, query_params=query_params) self.assertContains(resp, dir_url) for f in files: file_path = f['name'] if path: file_path = "%s/%s" % (path, f['name']) file_url_args = dict(url_args) file_url_args['path'] = file_path file_url = reverse('browse-origin-content', kwargs=file_url_args, query_params=query_params) self.assertContains(resp, file_url) if 'path' in url_args: del url_args['path'] root_dir_branch_url = \ reverse('browse-origin-directory', kwargs=url_args, query_params=query_params) nb_bc_paths = 1 if path: nb_bc_paths = len(path.split('/')) + 1 self.assertContains(resp, '
  • ', count=nb_bc_paths) self.assertContains(resp, '%s' % (root_dir_branch_url, root_directory_sha1[:7])) origin_branches_url = \ reverse('browse-origin-branches', kwargs=url_args, query_params=query_params) self.assertContains(resp, 'Branches (%s)' % (origin_branches_url, len(origin_branches))) origin_releases_url = \ reverse('browse-origin-releases', kwargs=url_args, query_params=query_params) self.assertContains(resp, 'Releases (%s)' % (origin_releases_url, len(origin_releases))) if path: url_args['path'] = path self.assertContains(resp, '
  • ', count=len(origin_branches)) for branch in origin_branches: query_params['branch'] = branch['name'] root_dir_branch_url = \ reverse('browse-origin-directory', kwargs=url_args, query_params=query_params) self.assertContains(resp, '' % root_dir_branch_url) self.assertContains(resp, '
  • ', count=len(origin_releases)) query_params['branch'] = None for release in origin_releases: query_params['release'] = release['name'] root_dir_release_url = \ reverse('browse-origin-directory', kwargs=url_args, query_params=query_params) self.assertContains(resp, '' % root_dir_release_url) self.assertContains(resp, 'vault-cook-directory') self.assertContains(resp, 'vault-cook-revision') swh_dir_id = get_swh_persistent_id('directory', directory_entries[0]['dir_id']) # noqa swh_dir_id_url = reverse('browse-swh-id', kwargs={'swh_id': swh_dir_id}) self.assertContains(resp, swh_dir_id) self.assertContains(resp, swh_dir_id_url) @patch('swh.web.browse.utils.get_origin_visits') @patch('swh.web.browse.utils.get_origin_visit_snapshot') @patch('swh.web.browse.utils.service') @patch('swh.web.browse.views.origin.service') def test_origin_root_directory_view(self, mock_origin_service, mock_utils_service, mock_get_origin_visit_snapshot, mock_get_origin_visits): mock_get_origin_visits.return_value = stub_origin_visits mock_get_origin_visit_snapshot.return_value = stub_origin_snapshot mock_utils_service.lookup_directory.return_value = \ stub_origin_root_directory_entries mock_utils_service.lookup_origin.return_value = stub_origin_info mock_utils_service.lookup_snapshot_size.return_value = { 'revision': len(stub_origin_snapshot[0]), 'release': len(stub_origin_snapshot[1]) } self.origin_directory_view_helper(stub_origin_info, stub_origin_visits, stub_origin_snapshot[0], stub_origin_snapshot[1], stub_origin_master_branch, stub_origin_root_directory_sha1, stub_origin_root_directory_entries) self.origin_directory_view_helper(stub_origin_info, stub_origin_visits, stub_origin_snapshot[0], stub_origin_snapshot[1], stub_origin_master_branch, stub_origin_root_directory_sha1, stub_origin_root_directory_entries, visit_id=stub_visit_id) self.origin_directory_view_helper(stub_origin_info, stub_origin_visits, stub_origin_snapshot[0], stub_origin_snapshot[1], stub_origin_master_branch, stub_origin_root_directory_sha1, stub_origin_root_directory_entries, timestamp=stub_visit_unix_ts) self.origin_directory_view_helper(stub_origin_info, stub_origin_visits, stub_origin_snapshot[0], stub_origin_snapshot[1], stub_origin_master_branch, stub_origin_root_directory_sha1, stub_origin_root_directory_entries, timestamp=stub_visit_iso_date) self.origin_directory_view_helper(stub_origin_info_no_type, stub_origin_visits, stub_origin_snapshot[0], stub_origin_snapshot[1], stub_origin_master_branch, stub_origin_root_directory_sha1, stub_origin_root_directory_entries) self.origin_directory_view_helper(stub_origin_info_no_type, stub_origin_visits, stub_origin_snapshot[0], stub_origin_snapshot[1], stub_origin_master_branch, stub_origin_root_directory_sha1, stub_origin_root_directory_entries, visit_id=stub_visit_id) self.origin_directory_view_helper(stub_origin_info_no_type, stub_origin_visits, stub_origin_snapshot[0], stub_origin_snapshot[1], stub_origin_master_branch, stub_origin_root_directory_sha1, stub_origin_root_directory_entries, timestamp=stub_visit_unix_ts) self.origin_directory_view_helper(stub_origin_info_no_type, stub_origin_visits, stub_origin_snapshot[0], stub_origin_snapshot[1], stub_origin_master_branch, stub_origin_root_directory_sha1, stub_origin_root_directory_entries, timestamp=stub_visit_iso_date) @patch('swh.web.browse.utils.get_origin_visits') @patch('swh.web.browse.utils.get_origin_visit_snapshot') @patch('swh.web.browse.utils.service') @patch('swh.web.browse.views.utils.snapshot_context.service') def test_origin_sub_directory_view(self, mock_origin_service, mock_utils_service, mock_get_origin_visit_snapshot, mock_get_origin_visits): mock_get_origin_visits.return_value = stub_origin_visits mock_get_origin_visit_snapshot.return_value = stub_origin_snapshot mock_utils_service.lookup_directory.return_value = \ stub_origin_sub_directory_entries mock_origin_service.lookup_directory_with_path.return_value = \ {'target': stub_origin_sub_directory_entries[0]['dir_id'], 'type' : 'dir'} mock_utils_service.lookup_origin.return_value = stub_origin_info mock_utils_service.lookup_snapshot_size.return_value = { 'revision': len(stub_origin_snapshot[0]), 'release': len(stub_origin_snapshot[1]) } self.origin_directory_view_helper(stub_origin_info, stub_origin_visits, stub_origin_snapshot[0], stub_origin_snapshot[1], stub_origin_master_branch, stub_origin_root_directory_sha1, stub_origin_sub_directory_entries, path=stub_origin_sub_directory_path) self.origin_directory_view_helper(stub_origin_info, stub_origin_visits, stub_origin_snapshot[0], stub_origin_snapshot[1], stub_origin_master_branch, stub_origin_root_directory_sha1, stub_origin_sub_directory_entries, visit_id=stub_visit_id, path=stub_origin_sub_directory_path) self.origin_directory_view_helper(stub_origin_info, stub_origin_visits, stub_origin_snapshot[0], stub_origin_snapshot[1], stub_origin_master_branch, stub_origin_root_directory_sha1, stub_origin_sub_directory_entries, timestamp=stub_visit_unix_ts, path=stub_origin_sub_directory_path) self.origin_directory_view_helper(stub_origin_info, stub_origin_visits, stub_origin_snapshot[0], stub_origin_snapshot[1], stub_origin_master_branch, stub_origin_root_directory_sha1, stub_origin_sub_directory_entries, timestamp=stub_visit_iso_date, path=stub_origin_sub_directory_path) self.origin_directory_view_helper(stub_origin_info_no_type, stub_origin_visits, stub_origin_snapshot[0], stub_origin_snapshot[1], stub_origin_master_branch, stub_origin_root_directory_sha1, stub_origin_sub_directory_entries, path=stub_origin_sub_directory_path) self.origin_directory_view_helper(stub_origin_info_no_type, stub_origin_visits, stub_origin_snapshot[0], stub_origin_snapshot[1], stub_origin_master_branch, stub_origin_root_directory_sha1, stub_origin_sub_directory_entries, visit_id=stub_visit_id, path=stub_origin_sub_directory_path) self.origin_directory_view_helper(stub_origin_info_no_type, stub_origin_visits, stub_origin_snapshot[0], stub_origin_snapshot[1], stub_origin_master_branch, stub_origin_root_directory_sha1, stub_origin_sub_directory_entries, timestamp=stub_visit_unix_ts, path=stub_origin_sub_directory_path) self.origin_directory_view_helper(stub_origin_info_no_type, stub_origin_visits, stub_origin_snapshot[0], stub_origin_snapshot[1], stub_origin_master_branch, stub_origin_root_directory_sha1, stub_origin_sub_directory_entries, timestamp=stub_visit_iso_date, path=stub_origin_sub_directory_path) @patch('swh.web.browse.views.utils.snapshot_context.request_content') @patch('swh.web.browse.utils.get_origin_visits') @patch('swh.web.browse.utils.get_origin_visit_snapshot') @patch('swh.web.browse.utils.service') @patch('swh.web.browse.views.origin.service') @patch('swh.web.browse.views.utils.snapshot_context.service') @patch('swh.web.browse.views.origin.get_origin_info') def test_origin_request_errors(self, mock_get_origin_info, mock_snapshot_service, mock_origin_service, mock_utils_service, mock_get_origin_visit_snapshot, mock_get_origin_visits, mock_request_content): mock_get_origin_info.side_effect = \ NotFoundExc('origin not found') url = reverse('browse-origin-visits', kwargs={'origin_type': 'foo', 'origin_url': 'bar'}) resp = self.client.get(url) - self.assertEquals(resp.status_code, 404) + self.assertEqual(resp.status_code, 404) self.assertTemplateUsed('error.html') self.assertContains(resp, 'origin not found', status_code=404) mock_utils_service.lookup_origin.side_effect = None mock_utils_service.lookup_origin.return_value = origin_info_test_data mock_get_origin_visits.return_value = [] url = reverse('browse-origin-directory', kwargs={'origin_type': 'foo', 'origin_url': 'bar'}) resp = self.client.get(url) - self.assertEquals(resp.status_code, 404) + self.assertEqual(resp.status_code, 404) self.assertTemplateUsed('error.html') self.assertContains(resp, "No SWH visit", status_code=404) mock_get_origin_visits.return_value = stub_origin_visits mock_get_origin_visit_snapshot.side_effect = \ NotFoundExc('visit not found') url = reverse('browse-origin-directory', kwargs={'origin_type': 'foo', 'origin_url': 'bar'}, query_params={'visit_id': len(stub_origin_visits)+1}) resp = self.client.get(url) - self.assertEquals(resp.status_code, 404) + self.assertEqual(resp.status_code, 404) self.assertTemplateUsed('error.html') self.assertRegex(resp.content.decode('utf-8'), 'Visit.*not found') mock_get_origin_visits.return_value = stub_origin_visits mock_get_origin_visit_snapshot.side_effect = None mock_get_origin_visit_snapshot.return_value = ([], []) url = reverse('browse-origin-directory', kwargs={'origin_type': 'foo', 'origin_url': 'bar'}) resp = self.client.get(url) - self.assertEquals(resp.status_code, 404) + self.assertEqual(resp.status_code, 404) self.assertTemplateUsed('error.html') self.assertRegex(resp.content.decode('utf-8'), 'Origin.*has an empty list of branches') mock_get_origin_visit_snapshot.return_value = stub_origin_snapshot mock_utils_service.lookup_directory.side_effect = \ NotFoundExc('Directory not found') url = reverse('browse-origin-directory', kwargs={'origin_type': 'foo', 'origin_url': 'bar'}) resp = self.client.get(url) - self.assertEquals(resp.status_code, 404) + self.assertEqual(resp.status_code, 404) self.assertTemplateUsed('error.html') self.assertContains(resp, 'Directory not found', status_code=404) mock_origin_service.lookup_origin.side_effect = None mock_origin_service.lookup_origin.return_value = origin_info_test_data mock_get_origin_visits.return_value = [] url = reverse('browse-origin-content', kwargs={'origin_type': 'foo', 'origin_url': 'bar', 'path': 'foo'}) resp = self.client.get(url) - self.assertEquals(resp.status_code, 404) + self.assertEqual(resp.status_code, 404) self.assertTemplateUsed('error.html') self.assertContains(resp, "No SWH visit", status_code=404) mock_get_origin_visits.return_value = stub_origin_visits mock_get_origin_visit_snapshot.side_effect = \ NotFoundExc('visit not found') url = reverse('browse-origin-content', kwargs={'origin_type': 'foo', 'origin_url': 'bar', 'path': 'foo'}, query_params={'visit_id': len(stub_origin_visits)+1}) resp = self.client.get(url) - self.assertEquals(resp.status_code, 404) + self.assertEqual(resp.status_code, 404) self.assertTemplateUsed('error.html') self.assertRegex(resp.content.decode('utf-8'), 'Visit.*not found') mock_get_origin_visits.return_value = stub_origin_visits mock_get_origin_visit_snapshot.side_effect = None mock_get_origin_visit_snapshot.return_value = ([], []) url = reverse('browse-origin-content', kwargs={'origin_type': 'foo', 'origin_url': 'bar', 'path': 'baz'}) resp = self.client.get(url) - self.assertEquals(resp.status_code, 404) + self.assertEqual(resp.status_code, 404) self.assertTemplateUsed('error.html') self.assertRegex(resp.content.decode('utf-8'), 'Origin.*has an empty list of branches') mock_get_origin_visit_snapshot.return_value = stub_origin_snapshot mock_snapshot_service.lookup_directory_with_path.return_value = \ {'target': stub_content_text_data['checksums']['sha1']} mock_request_content.side_effect = \ NotFoundExc('Content not found') url = reverse('browse-origin-content', kwargs={'origin_type': 'foo', 'origin_url': 'bar', 'path': 'baz'}) resp = self.client.get(url) - self.assertEquals(resp.status_code, 404) + self.assertEqual(resp.status_code, 404) self.assertTemplateUsed('error.html') self.assertContains(resp, 'Content not found', status_code=404) def origin_branches_helper(self, origin_info, origin_snapshot): url_args = {'origin_type': origin_info['type'], 'origin_url': origin_info['url']} url = reverse('browse-origin-branches', kwargs=url_args) resp = self.client.get(url) - self.assertEquals(resp.status_code, 200) + self.assertEqual(resp.status_code, 200) self.assertTemplateUsed('branches.html') origin_branches = origin_snapshot[0] origin_releases = origin_snapshot[1] origin_branches_url = \ reverse('browse-origin-branches', kwargs=url_args) self.assertContains(resp, 'Branches (%s)' % (origin_branches_url, len(origin_branches))) origin_releases_url = \ reverse('browse-origin-releases', kwargs=url_args) self.assertContains(resp, 'Releases (%s)' % (origin_releases_url, len(origin_releases))) self.assertContains(resp, '', count=len(origin_branches)) for branch in origin_branches: browse_branch_url = reverse('browse-origin-directory', kwargs={'origin_type': origin_info['type'], 'origin_url': origin_info['url']}, query_params={'branch': branch['name']}) self.assertContains(resp, '%s' % (escape(browse_branch_url), branch['name'])) browse_revision_url = reverse('browse-revision', kwargs={'sha1_git': branch['revision']}, query_params={'origin_type': origin_info['type'], 'origin': origin_info['url']}) self.assertContains(resp, '%s' % (escape(browse_revision_url), branch['revision'][:7])) @patch('swh.web.browse.views.utils.snapshot_context.process_snapshot_branches') @patch('swh.web.browse.views.utils.snapshot_context.service') @patch('swh.web.browse.utils.get_origin_visits') @patch('swh.web.browse.utils.get_origin_visit_snapshot') @patch('swh.web.browse.utils.service') @patch('swh.web.browse.views.origin.service') def test_origin_branches(self, mock_origin_service, mock_utils_service, mock_get_origin_visit_snapshot, mock_get_origin_visits, mock_snp_ctx_service, mock_snp_ctx_process_branches): mock_get_origin_visits.return_value = stub_origin_visits mock_get_origin_visit_snapshot.return_value = stub_origin_snapshot mock_utils_service.lookup_origin.return_value = stub_origin_info mock_utils_service.lookup_snapshot_size.return_value = \ {'revision': len(stub_origin_snapshot[0]), 'release': len(stub_origin_snapshot[1])} mock_snp_ctx_service.lookup_snapshot.return_value = \ _to_snapshot_dict(branches=stub_origin_snapshot[0]) mock_snp_ctx_process_branches.return_value = stub_origin_snapshot self.origin_branches_helper(stub_origin_info, stub_origin_snapshot) self.origin_branches_helper(stub_origin_info_no_type, stub_origin_snapshot) def origin_releases_helper(self, origin_info, origin_snapshot): url_args = {'origin_type': origin_info['type'], 'origin_url': origin_info['url']} url = reverse('browse-origin-releases', kwargs=url_args) resp = self.client.get(url) - self.assertEquals(resp.status_code, 200) + self.assertEqual(resp.status_code, 200) self.assertTemplateUsed('releases.html') origin_branches = origin_snapshot[0] origin_releases = origin_snapshot[1] origin_branches_url = \ reverse('browse-origin-branches', kwargs=url_args) self.assertContains(resp, 'Branches (%s)' % (origin_branches_url, len(origin_branches))) origin_releases_url = \ reverse('browse-origin-releases', kwargs=url_args) self.assertContains(resp, 'Releases (%s)' % (origin_releases_url, len(origin_releases))) self.assertContains(resp, '', count=len(origin_releases)) for release in origin_releases: browse_release_url = reverse('browse-release', kwargs={'sha1_git': release['id']}, query_params={'origin_type': origin_info['type'], 'origin': origin_info['url']}) self.assertContains(resp, '%s' % (escape(browse_release_url), release['name'])) @patch('swh.web.browse.views.utils.snapshot_context.process_snapshot_branches') @patch('swh.web.browse.views.utils.snapshot_context.service') @patch('swh.web.browse.utils.get_origin_visits') @patch('swh.web.browse.utils.get_origin_visit_snapshot') @patch('swh.web.browse.utils.service') @patch('swh.web.browse.views.origin.service') def test_origin_releases(self, mock_origin_service, mock_utils_service, mock_get_origin_visit_snapshot, mock_get_origin_visits, mock_snp_ctx_service, mock_snp_ctx_process_branches): mock_get_origin_visits.return_value = stub_origin_visits mock_get_origin_visit_snapshot.return_value = stub_origin_snapshot mock_utils_service.lookup_origin.return_value = stub_origin_info mock_utils_service.lookup_snapshot_size.return_value = \ {'revision': len(stub_origin_snapshot[0]), 'release': len(stub_origin_snapshot[1])} mock_snp_ctx_service.lookup_snapshot.return_value = \ _to_snapshot_dict(releases=stub_origin_snapshot[1]) mock_snp_ctx_process_branches.return_value = stub_origin_snapshot self.origin_releases_helper(stub_origin_info, stub_origin_snapshot) self.origin_releases_helper(stub_origin_info_no_type, stub_origin_snapshot) diff --git a/swh/web/tests/browse/views/test_person.py b/swh/web/tests/browse/views/test_person.py index 12e7b80c9..c0bb3e571 100644 --- a/swh/web/tests/browse/views/test_person.py +++ b/swh/web/tests/browse/views/test_person.py @@ -1,52 +1,52 @@ # Copyright (C) 2017-2018 The Software Heritage developers # See the AUTHORS file at the top-level directory of this distribution # License: GNU Affero General Public License version 3, or any later version # See top-level LICENSE file for more information from unittest.mock import patch from swh.web.common.exc import NotFoundExc from swh.web.common.utils import reverse from swh.web.tests.testcase import SWHWebTestCase class SwhBrowsePersonTest(SWHWebTestCase): @patch('swh.web.browse.views.person.service') def test_person_browse(self, mock_service): test_person_data = \ { "email": "j.adams440@gmail.com", "fullname": "oysterCrusher ", "id": 457587, "name": "oysterCrusher" } mock_service.lookup_person.return_value = test_person_data url = reverse('browse-person', kwargs={'person_id': 457587}) resp = self.client.get(url) - self.assertEquals(resp.status_code, 200) + self.assertEqual(resp.status_code, 200) self.assertTemplateUsed('browse/person.html') self.assertContains(resp, '
    %s
    ' % test_person_data['id']) self.assertContains(resp, '
    %s
    ' % test_person_data['name']) self.assertContains(resp, '
    %s
    ' % (test_person_data['email'], test_person_data['email'])) self.assertContains(resp, '
    %s <%s>
    ' % # noqa (test_person_data['name'], test_person_data['email'], test_person_data['email'])) @patch('swh.web.browse.views.person.service') def test_person_request_error(self, mock_service): mock_service.lookup_person.side_effect = \ NotFoundExc('Person not found') url = reverse('browse-person', kwargs={'person_id': 457587}) resp = self.client.get(url) - self.assertEquals(resp.status_code, 404) + self.assertEqual(resp.status_code, 404) self.assertTemplateUsed('error.html') self.assertContains(resp, 'Person not found', status_code=404) diff --git a/swh/web/tests/browse/views/test_release.py b/swh/web/tests/browse/views/test_release.py index 4de4cc04b..8c6a39a2a 100644 --- a/swh/web/tests/browse/views/test_release.py +++ b/swh/web/tests/browse/views/test_release.py @@ -1,111 +1,111 @@ # Copyright (C) 2018 The Software Heritage developers # See the AUTHORS file at the top-level directory of this distribution # License: GNU Affero General Public License version 3, or any later version # See top-level LICENSE file for more information # flake8: noqa from unittest.mock import patch from swh.web.common.exc import NotFoundExc from swh.web.common.utils import ( reverse, format_utc_iso_date, get_swh_persistent_id ) from swh.web.tests.testcase import SWHWebTestCase from .data.release_test_data import ( stub_release ) from .data.origin_test_data import stub_origin_visits class SwhBrowseReleaseTest(SWHWebTestCase): @patch('swh.web.browse.views.release.service') @patch('swh.web.browse.utils.service') @patch('swh.web.common.utils.service') def test_release_browse(self, mock_service_common, mock_service_utils, mock_service): mock_service.lookup_release.return_value = stub_release url = reverse('browse-release', kwargs={'sha1_git': stub_release['id']}) release_id = stub_release['id'] release_name = stub_release['name'] author_id = stub_release['author']['id'] author_name = stub_release['author']['name'] author_url = reverse('browse-person', kwargs={'person_id': author_id}) release_date = stub_release['date'] message = stub_release['message'] target_type = stub_release['target_type'] target = stub_release['target'] target_url = reverse('browse-revision', kwargs={'sha1_git': target}) message_lines = stub_release['message'].split('\n') resp = self.client.get(url) - self.assertEquals(resp.status_code, 200) + self.assertEqual(resp.status_code, 200) self.assertTemplateUsed('browse/release.html') self.assertContains(resp, '%s' % (author_url, author_name)) self.assertContains(resp, format_utc_iso_date(release_date)) self.assertContains(resp, '
    %s
    %s' % (message_lines[0], '\n'.join(message_lines[1:]))) self.assertContains(resp, release_id) self.assertContains(resp, release_name) self.assertContains(resp, target_type) self.assertContains(resp, '%s' % (target_url, target)) swh_rel_id = get_swh_persistent_id('release', release_id) swh_rel_id_url = reverse('browse-swh-id', kwargs={'swh_id': swh_rel_id}) self.assertContains(resp, swh_rel_id) self.assertContains(resp, swh_rel_id_url) origin_info = { 'id': 13706355, 'type': 'git', 'url': 'https://github.com/python/cpython' } mock_service_utils.lookup_origin.return_value = origin_info mock_service_common.lookup_origin_visits.return_value = stub_origin_visits mock_service_common.MAX_LIMIT = 20 url = reverse('browse-release', kwargs={'sha1_git': stub_release['id']}, query_params={'origin': origin_info['url']}) resp = self.client.get(url) - self.assertEquals(resp.status_code, 200) + self.assertEqual(resp.status_code, 200) self.assertTemplateUsed('browse/release.html') self.assertContains(resp, author_url) self.assertContains(resp, author_name) self.assertContains(resp, format_utc_iso_date(release_date)) self.assertContains(resp, '
    %s
    %s' % (message_lines[0], '\n'.join(message_lines[1:]))) self.assertContains(resp, release_id) self.assertContains(resp, release_name) self.assertContains(resp, target_type) target_url = reverse('browse-revision', kwargs={'sha1_git': target}, query_params={'origin': origin_info['url']}) self.assertContains(resp, '%s' % (target_url, target)) mock_service.lookup_release.side_effect = \ NotFoundExc('Release not found') url = reverse('browse-release', kwargs={'sha1_git': 'ffff'}) resp = self.client.get(url) - self.assertEquals(resp.status_code, 404) + self.assertEqual(resp.status_code, 404) self.assertTemplateUsed('error.html') self.assertContains(resp, 'Release not found', status_code=404) diff --git a/swh/web/tests/browse/views/test_revision.py b/swh/web/tests/browse/views/test_revision.py index 88be9be19..ddf9b3b1e 100644 --- a/swh/web/tests/browse/views/test_revision.py +++ b/swh/web/tests/browse/views/test_revision.py @@ -1,273 +1,273 @@ # Copyright (C) 2017-2018 The Software Heritage developers # See the AUTHORS file at the top-level directory of this distribution # License: GNU Affero General Public License version 3, or any later version # See top-level LICENSE file for more information # flake8: noqa from unittest.mock import patch from django.utils.html import escape from swh.web.common.exc import NotFoundExc from swh.web.common.utils import ( reverse, format_utc_iso_date, get_swh_persistent_id ) from swh.web.tests.testcase import SWHWebTestCase from .data.revision_test_data import ( revision_id_test, revision_metadata_test, revision_history_log_test ) from .data.origin_test_data import stub_origin_visits class SwhBrowseRevisionTest(SWHWebTestCase): @patch('swh.web.browse.views.revision.service') @patch('swh.web.browse.utils.service') @patch('swh.web.common.utils.service') def test_revision_browse(self, mock_service_common, mock_service_utils, mock_service): mock_service.lookup_revision.return_value = revision_metadata_test url = reverse('browse-revision', kwargs={'sha1_git': revision_id_test}) author_id = revision_metadata_test['author']['id'] author_name = revision_metadata_test['author']['name'] committer_id = revision_metadata_test['committer']['id'] committer_name = revision_metadata_test['committer']['name'] dir_id = revision_metadata_test['directory'] author_url = reverse('browse-person', kwargs={'person_id': author_id}) committer_url = reverse('browse-person', kwargs={'person_id': committer_id}) directory_url = reverse('browse-directory', kwargs={'sha1_git': dir_id}) history_url = reverse('browse-revision-log', kwargs={'sha1_git': revision_id_test}) resp = self.client.get(url) - self.assertEquals(resp.status_code, 200) + self.assertEqual(resp.status_code, 200) self.assertTemplateUsed('browse/revision.html') self.assertContains(resp, '%s' % (author_url, author_name)) self.assertContains(resp, '%s' % (committer_url, committer_name)) self.assertContains(resp, directory_url) self.assertContains(resp, history_url) for parent in revision_metadata_test['parents']: parent_url = reverse('browse-revision', kwargs={'sha1_git': parent}) self.assertContains(resp, '%s' % (parent_url, parent)) author_date = revision_metadata_test['date'] committer_date = revision_metadata_test['committer_date'] message_lines = revision_metadata_test['message'].split('\n') self.assertContains(resp, format_utc_iso_date(author_date)) self.assertContains(resp, format_utc_iso_date(committer_date)) self.assertContains(resp, message_lines[0]) self.assertContains(resp, '\n'.join(message_lines[1:])) origin_info = { 'id': '7416001', 'type': 'git', 'url': 'https://github.com/webpack/webpack' } mock_service_utils.lookup_origin.return_value = origin_info mock_service_common.lookup_origin_visits.return_value = stub_origin_visits mock_service_common.MAX_LIMIT = 20 origin_directory_url = reverse('browse-origin-directory', kwargs={'origin_type': origin_info['type'], 'origin_url': origin_info['url']}, query_params={'revision': revision_id_test}) origin_revision_log_url = reverse('browse-origin-log', kwargs={'origin_type': origin_info['type'], 'origin_url': origin_info['url']}, query_params={'revision': revision_id_test}) url = reverse('browse-revision', kwargs={'sha1_git': revision_id_test}, query_params={'origin_type': origin_info['type'], 'origin': origin_info['url']}) resp = self.client.get(url) self.assertContains(resp, origin_directory_url) self.assertContains(resp, origin_revision_log_url) for parent in revision_metadata_test['parents']: parent_url = reverse('browse-revision', kwargs={'sha1_git': parent}, query_params={'origin_type': origin_info['type'], 'origin': origin_info['url']}) self.assertContains(resp, '%s' % (parent_url, parent)) self.assertContains(resp, 'vault-cook-directory') self.assertContains(resp, 'vault-cook-revision') swh_rev_id = get_swh_persistent_id('revision', revision_id_test) swh_rev_id_url = reverse('browse-swh-id', kwargs={'swh_id': swh_rev_id}) self.assertContains(resp, swh_rev_id) self.assertContains(resp, swh_rev_id_url) swh_dir_id = get_swh_persistent_id('directory', dir_id) swh_dir_id_url = reverse('browse-swh-id', kwargs={'swh_id': swh_dir_id}) self.assertContains(resp, swh_dir_id) self.assertContains(resp, swh_dir_id_url) @patch('swh.web.browse.views.revision.service') def test_revision_log_browse(self, mock_service): per_page = 10 mock_service.lookup_revision_log.return_value = \ revision_history_log_test[:per_page+1] url = reverse('browse-revision-log', kwargs={'sha1_git': revision_id_test}, query_params={'per_page': per_page}) resp = self.client.get(url) prev_rev = revision_history_log_test[per_page]['id'] next_page_url = reverse('browse-revision-log', kwargs={'sha1_git': prev_rev}, query_params={'revs_breadcrumb': revision_id_test, 'per_page': per_page}) - self.assertEquals(resp.status_code, 200) + self.assertEqual(resp.status_code, 200) self.assertTemplateUsed('browse/revision-log.html') self.assertContains(resp, '', count=per_page) self.assertContains(resp, '
  • Newer
  • ') self.assertContains(resp, '
  • Older
  • ' % escape(next_page_url)) for log in revision_history_log_test[:per_page]: author_url = reverse('browse-person', kwargs={'person_id': log['author']['id']}) revision_url = reverse('browse-revision', kwargs={'sha1_git': log['id']}) directory_url = reverse('browse-directory', kwargs={'sha1_git': log['directory']}) self.assertContains(resp, '%s' % (author_url, log['author']['name'])) self.assertContains(resp, '%s' % (revision_url, log['id'][:7])) self.assertContains(resp, directory_url) mock_service.lookup_revision_log.return_value = \ revision_history_log_test[per_page:2*per_page+1] resp = self.client.get(next_page_url) prev_prev_rev = revision_history_log_test[2*per_page]['id'] prev_page_url = reverse('browse-revision-log', kwargs={'sha1_git': revision_id_test}, query_params={'per_page': per_page}) next_page_url = reverse('browse-revision-log', kwargs={'sha1_git': prev_prev_rev}, query_params={'revs_breadcrumb': revision_id_test + '/' + prev_rev, 'per_page': per_page}) - self.assertEquals(resp.status_code, 200) + self.assertEqual(resp.status_code, 200) self.assertTemplateUsed('browse/revision-log.html') self.assertContains(resp, '', count=per_page) self.assertContains(resp, '
  • Newer
  • ' % escape(prev_page_url)) self.assertContains(resp, '
  • Older
  • ' % escape(next_page_url)) mock_service.lookup_revision_log.return_value = \ revision_history_log_test[2*per_page:3*per_page+1] resp = self.client.get(next_page_url) prev_prev_prev_rev = revision_history_log_test[3*per_page]['id'] prev_page_url = reverse('browse-revision-log', kwargs={'sha1_git': prev_rev}, query_params={'revs_breadcrumb': revision_id_test, 'per_page': per_page}) next_page_url = reverse('browse-revision-log', kwargs={'sha1_git': prev_prev_prev_rev}, query_params={'revs_breadcrumb': revision_id_test + '/' + prev_rev + '/' + prev_prev_rev, 'per_page': per_page}) - self.assertEquals(resp.status_code, 200) + self.assertEqual(resp.status_code, 200) self.assertTemplateUsed('browse/revision-log.html') self.assertContains(resp, '', count=per_page) self.assertContains(resp, '
  • Newer
  • ' % escape(prev_page_url)) self.assertContains(resp, '
  • Older
  • ' % escape(next_page_url)) mock_service.lookup_revision_log.return_value = \ revision_history_log_test[3*per_page:3*per_page+per_page//2] resp = self.client.get(next_page_url) prev_page_url = reverse('browse-revision-log', kwargs={'sha1_git': prev_prev_rev}, query_params={'revs_breadcrumb': revision_id_test + '/' + prev_rev, 'per_page': per_page}) - self.assertEquals(resp.status_code, 200) + self.assertEqual(resp.status_code, 200) self.assertTemplateUsed('browse/revision-log.html') self.assertContains(resp, '', count=per_page//2) self.assertContains(resp, '
  • Older
  • ') self.assertContains(resp, '
  • Newer
  • ' % escape(prev_page_url)) @patch('swh.web.browse.utils.service') @patch('swh.web.browse.views.revision.service') def test_revision_request_errors(self, mock_service, mock_utils_service): mock_service.lookup_revision.side_effect = \ NotFoundExc('Revision not found') url = reverse('browse-revision', kwargs={'sha1_git': revision_id_test}) resp = self.client.get(url) - self.assertEquals(resp.status_code, 404) + self.assertEqual(resp.status_code, 404) self.assertTemplateUsed('error.html') self.assertContains(resp, 'Revision not found', status_code=404) mock_service.lookup_revision_log.side_effect = \ NotFoundExc('Revision not found') url = reverse('browse-revision-log', kwargs={'sha1_git': revision_id_test}) resp = self.client.get(url) - self.assertEquals(resp.status_code, 404) + self.assertEqual(resp.status_code, 404) self.assertTemplateUsed('error.html') self.assertContains(resp, 'Revision not found', status_code=404) url = reverse('browse-revision', kwargs={'sha1_git': revision_id_test}, query_params={'origin_type': 'git', 'origin': 'https://github.com/foo/bar'}) mock_service.lookup_revision.side_effect = None mock_utils_service.lookup_origin.side_effect = \ NotFoundExc('Origin not found') resp = self.client.get(url) - self.assertEquals(resp.status_code, 404) + self.assertEqual(resp.status_code, 404) self.assertTemplateUsed('error.html') self.assertContains(resp, 'Origin not found', status_code=404) diff --git a/swh/web/tests/common/test_converters.py b/swh/web/tests/common/test_converters.py index 6310b430d..25ad6840f 100644 --- a/swh/web/tests/common/test_converters.py +++ b/swh/web/tests/common/test_converters.py @@ -1,785 +1,785 @@ # Copyright (C) 2015-2018 The Software Heritage developers # See the AUTHORS file at the top-level directory of this distribution # License: GNU Affero General Public License version 3, or any later version # See top-level LICENSE file for more information import datetime from swh.model import hashutil from swh.web.common import converters from swh.web.tests.testcase import SWHWebTestCase class ConvertersTestCase(SWHWebTestCase): def test_fmap(self): - self.assertEquals([2, 3, None, 4], - converters.fmap(lambda x: x+1, [1, 2, None, 3])) - self.assertEquals([11, 12, 13], - list(converters.fmap(lambda x: x+10, - map(lambda x: x, [1, 2, 3])))) - self.assertEquals({'a': 2, 'b': 4}, - converters.fmap(lambda x: x*2, {'a': 1, 'b': 2})) - self.assertEquals(100, - converters.fmap(lambda x: x*10, 10)) - self.assertEquals({'a': [2, 6], 'b': 4}, + self.assertEqual([2, 3, None, 4], + converters.fmap(lambda x: x+1, [1, 2, None, 3])) + self.assertEqual([11, 12, 13], + list(converters.fmap(lambda x: x+10, + map(lambda x: x, [1, 2, 3])))) + self.assertEqual({'a': 2, 'b': 4}, + converters.fmap(lambda x: x*2, {'a': 1, 'b': 2})) + self.assertEqual(100, + converters.fmap(lambda x: x*10, 10)) + self.assertEqual({'a': [2, 6], 'b': 4}, converters.fmap(lambda x: x*2, {'a': [1, 3], 'b': 2})) # noqa self.assertIsNone(converters.fmap(lambda x: x, None)) def test_from_swh(self): some_input = { 'a': 'something', 'b': 'someone', 'c': b'sharp-0.3.4.tgz', 'd': hashutil.hash_to_bytes( 'b04caf10e9535160d90e874b45aa426de762f19f'), 'e': b'sharp.html/doc_002dS_005fISREG.html', 'g': [b'utf-8-to-decode', b'another-one'], 'h': 'something filtered', 'i': {'e': b'something'}, 'j': { 'k': { 'l': [b'bytes thing', b'another thingy', b''], 'n': 'dont care either' }, 'm': 'dont care' }, 'o': 'something', 'p': b'foo', 'q': {'extra-headers': [['a', b'intact']]}, 'w': None, 'r': {'p': 'also intact', 'q': 'bar'}, 's': { 'timestamp': 42, 'offset': -420, 'negative_utc': None, }, 's1': { 'timestamp': {'seconds': 42, 'microseconds': 0}, 'offset': -420, 'negative_utc': None, }, 's2': datetime.datetime( 2013, 7, 1, 20, 0, 0, tzinfo=datetime.timezone.utc), 't': None, 'u': None, 'v': None, 'x': None, } expected_output = { 'a': 'something', 'b': 'someone', 'c': 'sharp-0.3.4.tgz', 'd': 'b04caf10e9535160d90e874b45aa426de762f19f', 'e': 'sharp.html/doc_002dS_005fISREG.html', 'g': ['utf-8-to-decode', 'another-one'], 'i': {'e': 'something'}, 'j': { 'k': { 'l': ['bytes thing', 'another thingy', ''] } }, 'p': 'foo', 'q': {'extra-headers': [['a', 'intact']]}, 'w': {}, 'r': {'p': 'also intact', 'q': 'bar'}, 's': '1969-12-31T17:00:42-07:00', 's1': '1969-12-31T17:00:42-07:00', 's2': '2013-07-01T20:00:00+00:00', 'u': {}, 'v': [], 'x': None, } actual_output = converters.from_swh( some_input, hashess={'d', 'o', 'x'}, bytess={'c', 'e', 'g', 'l'}, dates={'s', 's1', 's2'}, blacklist={'h', 'm', 'n', 'o'}, removables_if_empty={'t'}, empty_dict={'u'}, empty_list={'v'}, convert={'p', 'q', 'w'}, convert_fn=converters.convert_revision_metadata) - self.assertEquals(expected_output, actual_output) + self.assertEqual(expected_output, actual_output) def test_from_swh_edge_cases_do_no_conversion_if_none_or_not_bytes(self): some_input = { 'a': 'something', 'b': None, 'c': 'someone', 'd': None, 'e': None } expected_output = { 'a': 'something', 'b': None, 'c': 'someone', 'd': None, 'e': None } actual_output = converters.from_swh(some_input, hashess={'a', 'b'}, bytess={'c', 'd'}, dates={'e'}) - self.assertEquals(expected_output, actual_output) + self.assertEqual(expected_output, actual_output) def test_from_swh_edge_cases_convert_invalid_utf8_bytes(self): some_input = { 'a': 'something', 'b': 'someone', 'c': b'a name \xff', 'd': b'an email \xff', } expected_output = { 'a': 'something', 'b': 'someone', 'c': 'a name \\xff', 'd': 'an email \\xff', 'decoding_failures': ['c', 'd'] } actual_output = converters.from_swh(some_input, hashess={'a', 'b'}, bytess={'c', 'd'}) for v in ['a', 'b', 'c', 'd']: self.assertEqual(expected_output[v], actual_output[v]) self.assertEqual(len(expected_output['decoding_failures']), len(actual_output['decoding_failures'])) for v in expected_output['decoding_failures']: self.assertTrue(v in actual_output['decoding_failures']) def test_from_swh_empty(self): # when - self.assertEquals({}, converters.from_swh({})) + self.assertEqual({}, converters.from_swh({})) def test_from_swh_none(self): # when self.assertIsNone(converters.from_swh(None)) def test_from_provenance(self): # given input_provenance = { 'origin': 10, 'visit': 1, 'content': hashutil.hash_to_bytes( '321caf10e9535160d90e874b45aa426de762f19f'), 'revision': hashutil.hash_to_bytes( '123caf10e9535160d90e874b45aa426de762f19f'), 'path': b'octave-3.4.0/doc/interpreter/octave/doc_002dS_005fISREG' } expected_provenance = { 'origin': 10, 'visit': 1, 'content': '321caf10e9535160d90e874b45aa426de762f19f', 'revision': '123caf10e9535160d90e874b45aa426de762f19f', 'path': 'octave-3.4.0/doc/interpreter/octave/doc_002dS_005fISREG' } # when actual_provenance = converters.from_provenance(input_provenance) # then self.assertEqual(actual_provenance, expected_provenance) def test_from_origin(self): # given origin_input = { 'id': 9, 'type': 'ftp', 'url': 'rsync://ftp.gnu.org/gnu/octave', } expected_origin = { 'id': 9, 'type': 'ftp', 'url': 'rsync://ftp.gnu.org/gnu/octave', } # when actual_origin = converters.from_origin(origin_input) # then self.assertEqual(actual_origin, expected_origin) def test_from_origin_visit(self): snap_hash = 'b5f0b7f716735ebffe38505c60145c4fd9da6ca3' for snap in [snap_hash, None]: # given visit = { 'date': { 'timestamp': datetime.datetime( 2015, 1, 1, 22, 0, 0, tzinfo=datetime.timezone.utc).timestamp(), 'offset': 0, 'negative_utc': False, }, 'origin': 10, 'visit': 100, 'metadata': None, 'status': 'full', 'snapshot': hashutil.hash_to_bytes(snap) if snap else snap, } expected_visit = { 'date': '2015-01-01T22:00:00+00:00', 'origin': 10, 'visit': 100, 'metadata': {}, 'status': 'full', 'snapshot': snap_hash if snap else snap } # when actual_visit = converters.from_origin_visit(visit) # then self.assertEqual(actual_visit, expected_visit) def test_from_release(self): release_input = { 'id': hashutil.hash_to_bytes( 'aad23fa492a0c5fed0708a6703be875448c86884'), 'target': hashutil.hash_to_bytes( '5e46d564378afc44b31bb89f99d5675195fbdf67'), 'target_type': 'revision', 'date': { 'timestamp': datetime.datetime( 2015, 1, 1, 22, 0, 0, tzinfo=datetime.timezone.utc).timestamp(), 'offset': 0, 'negative_utc': False, }, 'author': { 'name': b'author name', 'fullname': b'Author Name author@email', 'email': b'author@email', }, 'name': b'v0.0.1', 'message': b'some comment on release', 'synthetic': True, } expected_release = { 'id': 'aad23fa492a0c5fed0708a6703be875448c86884', 'target': '5e46d564378afc44b31bb89f99d5675195fbdf67', 'target_type': 'revision', 'date': '2015-01-01T22:00:00+00:00', 'author': { 'name': 'author name', 'fullname': 'Author Name author@email', 'email': 'author@email', }, 'name': 'v0.0.1', 'message': 'some comment on release', 'target_type': 'revision', 'synthetic': True, } # when actual_release = converters.from_release(release_input) # then self.assertEqual(actual_release, expected_release) def test_from_release_no_revision(self): release_input = { 'id': hashutil.hash_to_bytes( 'b2171ee2bdf119cd99a7ec7eff32fa8013ef9a4e'), 'target': None, 'date': { 'timestamp': datetime.datetime( 2016, 3, 2, 10, 0, 0, tzinfo=datetime.timezone.utc).timestamp(), 'offset': 0, 'negative_utc': True, }, 'name': b'v0.1.1', 'message': b'comment on release', 'synthetic': False, 'author': { 'name': b'bob', 'fullname': b'Bob bob@alice.net', 'email': b'bob@alice.net', }, } expected_release = { 'id': 'b2171ee2bdf119cd99a7ec7eff32fa8013ef9a4e', 'target': None, 'date': '2016-03-02T10:00:00-00:00', 'name': 'v0.1.1', 'message': 'comment on release', 'synthetic': False, 'author': { 'name': 'bob', 'fullname': 'Bob bob@alice.net', 'email': 'bob@alice.net', }, } # when actual_release = converters.from_release(release_input) # then self.assertEqual(actual_release, expected_release) def test_from_revision(self): revision_input = { 'id': hashutil.hash_to_bytes( '18d8be353ed3480476f032475e7c233eff7371d5'), 'directory': hashutil.hash_to_bytes( '7834ef7e7c357ce2af928115c6c6a42b7e2a44e6'), 'author': { 'name': b'Software Heritage', 'fullname': b'robot robot@softwareheritage.org', 'email': b'robot@softwareheritage.org', }, 'committer': { 'name': b'Software Heritage', 'fullname': b'robot robot@softwareheritage.org', 'email': b'robot@softwareheritage.org', }, 'message': b'synthetic revision message', 'date': { 'timestamp': datetime.datetime( 2000, 1, 17, 11, 23, 54, tzinfo=datetime.timezone.utc).timestamp(), 'offset': 0, 'negative_utc': False, }, 'committer_date': { 'timestamp': datetime.datetime( 2000, 1, 17, 11, 23, 54, tzinfo=datetime.timezone.utc).timestamp(), 'offset': 0, 'negative_utc': False, }, 'synthetic': True, 'type': 'tar', 'parents': [ hashutil.hash_to_bytes( '29d8be353ed3480476f032475e7c244eff7371d5'), hashutil.hash_to_bytes( '30d8be353ed3480476f032475e7c244eff7371d5') ], 'children': [ hashutil.hash_to_bytes( '123546353ed3480476f032475e7c244eff7371d5'), ], 'metadata': { 'extra_headers': [['gpgsig', b'some-signature']], 'original_artifact': [{ 'archive_type': 'tar', 'name': 'webbase-5.7.0.tar.gz', 'sha1': '147f73f369733d088b7a6fa9c4e0273dcd3c7ccd', 'sha1_git': '6a15ea8b881069adedf11feceec35588f2cfe8f1', 'sha256': '401d0df797110bea805d358b85bcc1ced29549d3d73f' '309d36484e7edf7bb912', }] }, } expected_revision = { 'id': '18d8be353ed3480476f032475e7c233eff7371d5', 'directory': '7834ef7e7c357ce2af928115c6c6a42b7e2a44e6', 'author': { 'name': 'Software Heritage', 'fullname': 'robot robot@softwareheritage.org', 'email': 'robot@softwareheritage.org', }, 'committer': { 'name': 'Software Heritage', 'fullname': 'robot robot@softwareheritage.org', 'email': 'robot@softwareheritage.org', }, 'message': 'synthetic revision message', 'date': "2000-01-17T11:23:54+00:00", 'committer_date': "2000-01-17T11:23:54+00:00", 'children': [ '123546353ed3480476f032475e7c244eff7371d5' ], 'parents': [ '29d8be353ed3480476f032475e7c244eff7371d5', '30d8be353ed3480476f032475e7c244eff7371d5' ], 'type': 'tar', 'synthetic': True, 'metadata': { 'extra_headers': [['gpgsig', 'some-signature']], 'original_artifact': [{ 'archive_type': 'tar', 'name': 'webbase-5.7.0.tar.gz', 'sha1': '147f73f369733d088b7a6fa9c4e0273dcd3c7ccd', 'sha1_git': '6a15ea8b881069adedf11feceec35588f2cfe8f1', 'sha256': '401d0df797110bea805d358b85bcc1ced29549d3d73f' '309d36484e7edf7bb912' }] }, 'merge': True } # when actual_revision = converters.from_revision(revision_input) # then self.assertEqual(actual_revision, expected_revision) def test_from_revision_nomerge(self): revision_input = { 'id': hashutil.hash_to_bytes( '18d8be353ed3480476f032475e7c233eff7371d5'), 'parents': [ hashutil.hash_to_bytes( '29d8be353ed3480476f032475e7c244eff7371d5') ] } expected_revision = { 'id': '18d8be353ed3480476f032475e7c233eff7371d5', 'parents': [ '29d8be353ed3480476f032475e7c244eff7371d5' ], 'merge': False } # when actual_revision = converters.from_revision(revision_input) # then self.assertEqual(actual_revision, expected_revision) def test_from_revision_noparents(self): revision_input = { 'id': hashutil.hash_to_bytes( '18d8be353ed3480476f032475e7c233eff7371d5'), 'directory': hashutil.hash_to_bytes( '7834ef7e7c357ce2af928115c6c6a42b7e2a44e6'), 'author': { 'name': b'Software Heritage', 'fullname': b'robot robot@softwareheritage.org', 'email': b'robot@softwareheritage.org', }, 'committer': { 'name': b'Software Heritage', 'fullname': b'robot robot@softwareheritage.org', 'email': b'robot@softwareheritage.org', }, 'message': b'synthetic revision message', 'date': { 'timestamp': datetime.datetime( 2000, 1, 17, 11, 23, 54, tzinfo=datetime.timezone.utc).timestamp(), 'offset': 0, 'negative_utc': False, }, 'committer_date': { 'timestamp': datetime.datetime( 2000, 1, 17, 11, 23, 54, tzinfo=datetime.timezone.utc).timestamp(), 'offset': 0, 'negative_utc': False, }, 'synthetic': True, 'type': 'tar', 'children': [ hashutil.hash_to_bytes( '123546353ed3480476f032475e7c244eff7371d5'), ], 'metadata': { 'original_artifact': [{ 'archive_type': 'tar', 'name': 'webbase-5.7.0.tar.gz', 'sha1': '147f73f369733d088b7a6fa9c4e0273dcd3c7ccd', 'sha1_git': '6a15ea8b881069adedf11feceec35588f2cfe8f1', 'sha256': '401d0df797110bea805d358b85bcc1ced29549d3d73f' '309d36484e7edf7bb912', }] }, } expected_revision = { 'id': '18d8be353ed3480476f032475e7c233eff7371d5', 'directory': '7834ef7e7c357ce2af928115c6c6a42b7e2a44e6', 'author': { 'name': 'Software Heritage', 'fullname': 'robot robot@softwareheritage.org', 'email': 'robot@softwareheritage.org', }, 'committer': { 'name': 'Software Heritage', 'fullname': 'robot robot@softwareheritage.org', 'email': 'robot@softwareheritage.org', }, 'message': 'synthetic revision message', 'date': "2000-01-17T11:23:54+00:00", 'committer_date': "2000-01-17T11:23:54+00:00", 'children': [ '123546353ed3480476f032475e7c244eff7371d5' ], 'type': 'tar', 'synthetic': True, 'metadata': { 'original_artifact': [{ 'archive_type': 'tar', 'name': 'webbase-5.7.0.tar.gz', 'sha1': '147f73f369733d088b7a6fa9c4e0273dcd3c7ccd', 'sha1_git': '6a15ea8b881069adedf11feceec35588f2cfe8f1', 'sha256': '401d0df797110bea805d358b85bcc1ced29549d3d73f' '309d36484e7edf7bb912' }] } } # when actual_revision = converters.from_revision(revision_input) # then self.assertEqual(actual_revision, expected_revision) def test_from_revision_invalid(self): revision_input = { 'id': hashutil.hash_to_bytes( '18d8be353ed3480476f032475e7c233eff7371d5'), 'directory': hashutil.hash_to_bytes( '7834ef7e7c357ce2af928115c6c6a42b7e2a44e6'), 'author': { 'name': b'Software Heritage', 'fullname': b'robot robot@softwareheritage.org', 'email': b'robot@softwareheritage.org', }, 'committer': { 'name': b'Software Heritage', 'fullname': b'robot robot@softwareheritage.org', 'email': b'robot@softwareheritage.org', }, 'message': b'invalid message \xff', 'date': { 'timestamp': datetime.datetime( 2000, 1, 17, 11, 23, 54, tzinfo=datetime.timezone.utc).timestamp(), 'offset': 0, 'negative_utc': False, }, 'committer_date': { 'timestamp': datetime.datetime( 2000, 1, 17, 11, 23, 54, tzinfo=datetime.timezone.utc).timestamp(), 'offset': 0, 'negative_utc': False, }, 'synthetic': True, 'type': 'tar', 'parents': [ hashutil.hash_to_bytes( '29d8be353ed3480476f032475e7c244eff7371d5'), hashutil.hash_to_bytes( '30d8be353ed3480476f032475e7c244eff7371d5') ], 'children': [ hashutil.hash_to_bytes( '123546353ed3480476f032475e7c244eff7371d5'), ], 'metadata': { 'original_artifact': [{ 'archive_type': 'tar', 'name': 'webbase-5.7.0.tar.gz', 'sha1': '147f73f369733d088b7a6fa9c4e0273dcd3c7ccd', 'sha1_git': '6a15ea8b881069adedf11feceec35588f2cfe8f1', 'sha256': '401d0df797110bea805d358b85bcc1ced29549d3d73f' '309d36484e7edf7bb912', }] }, } expected_revision = { 'id': '18d8be353ed3480476f032475e7c233eff7371d5', 'directory': '7834ef7e7c357ce2af928115c6c6a42b7e2a44e6', 'author': { 'name': 'Software Heritage', 'fullname': 'robot robot@softwareheritage.org', 'email': 'robot@softwareheritage.org', }, 'committer': { 'name': 'Software Heritage', 'fullname': 'robot robot@softwareheritage.org', 'email': 'robot@softwareheritage.org', }, 'message': None, 'message_decoding_failed': True, 'date': "2000-01-17T11:23:54+00:00", 'committer_date': "2000-01-17T11:23:54+00:00", 'children': [ '123546353ed3480476f032475e7c244eff7371d5' ], 'parents': [ '29d8be353ed3480476f032475e7c244eff7371d5', '30d8be353ed3480476f032475e7c244eff7371d5' ], 'type': 'tar', 'synthetic': True, 'metadata': { 'original_artifact': [{ 'archive_type': 'tar', 'name': 'webbase-5.7.0.tar.gz', 'sha1': '147f73f369733d088b7a6fa9c4e0273dcd3c7ccd', 'sha1_git': '6a15ea8b881069adedf11feceec35588f2cfe8f1', 'sha256': '401d0df797110bea805d358b85bcc1ced29549d3d73f' '309d36484e7edf7bb912' }] }, 'merge': True } # when actual_revision = converters.from_revision(revision_input) # then self.assertEqual(actual_revision, expected_revision) def test_from_content_none(self): self.assertIsNone(converters.from_content(None)) def test_from_content(self): content_input = { 'sha1': hashutil.hash_to_bytes( '5c6f0e2750f48fa0bd0c4cf5976ba0b9e02ebda5'), 'sha256': hashutil.hash_to_bytes( '39007420ca5de7cb3cfc15196335507e' 'e76c98930e7e0afa4d2747d3bf96c926'), 'blake2s256': hashutil.hash_to_bytes( '49007420ca5de7cb3cfc15196335507e' 'e76c98930e7e0afa4d2747d3bf96c926'), 'sha1_git': hashutil.hash_to_bytes( '40e71b8614fcd89ccd17ca2b1d9e66c5b00a6d03'), 'ctime': 'something-which-is-filtered-out', 'data': b'data in bytes', 'length': 10, 'status': 'hidden', } # 'status' is filtered expected_content = { 'checksums': { 'sha1': '5c6f0e2750f48fa0bd0c4cf5976ba0b9e02ebda5', 'sha256': '39007420ca5de7cb3cfc15196335507ee76c98' '930e7e0afa4d2747d3bf96c926', 'blake2s256': '49007420ca5de7cb3cfc15196335507ee7' '6c98930e7e0afa4d2747d3bf96c926', 'sha1_git': '40e71b8614fcd89ccd17ca2b1d9e66c5b00a6d03', }, 'data': b'data in bytes', 'length': 10, 'status': 'absent', } # when actual_content = converters.from_content(content_input) # then self.assertEqual(actual_content, expected_content) def test_from_person(self): person_input = { 'id': 10, 'anything': 'else', 'name': b'bob', 'fullname': b'bob bob@alice.net', 'email': b'bob@foo.alice', } expected_person = { 'id': 10, 'anything': 'else', 'name': 'bob', 'fullname': 'bob bob@alice.net', 'email': 'bob@foo.alice', } # when actual_person = converters.from_person(person_input) # then self.assertEqual(actual_person, expected_person) def test_from_directory_entries(self): dir_entries_input = { 'sha1': hashutil.hash_to_bytes( '5c6f0e2750f48fa0bd0c4cf5976ba0b9e02ebda5'), 'sha256': hashutil.hash_to_bytes( '39007420ca5de7cb3cfc15196335507e' 'e76c98930e7e0afa4d2747d3bf96c926'), 'sha1_git': hashutil.hash_to_bytes( '40e71b8614fcd89ccd17ca2b1d9e66c5b00a6d03'), 'blake2s256': hashutil.hash_to_bytes( '685395c5dc57cada459364f0946d3dd45bad5fcbab' 'c1048edb44380f1d31d0aa'), 'target': hashutil.hash_to_bytes( '40e71b8614fcd89ccd17ca2b1d9e66c5b00a6d03'), 'dir_id': hashutil.hash_to_bytes( '40e71b8614fcd89ccd17ca2b1d9e66c5b00a6d03'), 'name': b'bob', 'type': 10, 'status': 'hidden', } expected_dir_entries = { 'checksums': { 'sha1': '5c6f0e2750f48fa0bd0c4cf5976ba0b9e02ebda5', 'sha256': '39007420ca5de7cb3cfc15196335507ee76c98' '930e7e0afa4d2747d3bf96c926', 'sha1_git': '40e71b8614fcd89ccd17ca2b1d9e66c5b00a6d03', 'blake2s256': '685395c5dc57cada459364f0946d3dd45bad5f' 'cbabc1048edb44380f1d31d0aa', }, 'target': '40e71b8614fcd89ccd17ca2b1d9e66c5b00a6d03', 'dir_id': '40e71b8614fcd89ccd17ca2b1d9e66c5b00a6d03', 'name': 'bob', 'type': 10, 'status': 'absent', } # when actual_dir_entries = converters.from_directory_entry(dir_entries_input) # then self.assertEqual(actual_dir_entries, expected_dir_entries) def test_from_filetype(self): content_filetype = { 'id': hashutil.hash_to_bytes( '5c6f0e2750f48fa0bd0c4cf5976ba0b9e02ebda5'), 'encoding': b'utf-8', 'mimetype': b'text/plain', } expected_content_filetype = { 'id': '5c6f0e2750f48fa0bd0c4cf5976ba0b9e02ebda5', 'encoding': 'utf-8', 'mimetype': 'text/plain', } # when actual_content_filetype = converters.from_filetype(content_filetype) # then self.assertEqual(actual_content_filetype, expected_content_filetype) diff --git a/swh/web/tests/common/test_highlightjs.py b/swh/web/tests/common/test_highlightjs.py index e51844357..fb5f26f09 100644 --- a/swh/web/tests/common/test_highlightjs.py +++ b/swh/web/tests/common/test_highlightjs.py @@ -1,126 +1,126 @@ # Copyright (C) 2017-2018 The Software Heritage developers # See the AUTHORS file at the top-level directory of this distribution # License: GNU Affero General Public License version 3, or any later version # See top-level LICENSE file for more information from swh.web.common import highlightjs from swh.web.tests.testcase import SWHWebTestCase class HighlightJsTestCase(SWHWebTestCase): def test_get_hljs_language_from_mime_type(self): lang = highlightjs.get_hljs_language_from_mime_type('text/plain') - self.assertEquals(lang, None) + self.assertEqual(lang, None) lang = highlightjs.get_hljs_language_from_mime_type('text/x-c') - self.assertEquals(lang, 'cpp') + self.assertEqual(lang, 'cpp') lang = highlightjs.get_hljs_language_from_mime_type('text/x-c++') - self.assertEquals(lang, 'cpp') + self.assertEqual(lang, 'cpp') lang = highlightjs.get_hljs_language_from_mime_type('text/x-perl') - self.assertEquals(lang, 'perl') + self.assertEqual(lang, 'perl') lang = highlightjs.get_hljs_language_from_mime_type('text/x-python') - self.assertEquals(lang, 'python') + self.assertEqual(lang, 'python') lang = highlightjs.get_hljs_language_from_mime_type('text/x-msdos-batch') # noqa - self.assertEquals(lang, 'dos') + self.assertEqual(lang, 'dos') lang = highlightjs.get_hljs_language_from_mime_type('text/x-tex') - self.assertEquals(lang, 'tex') + self.assertEqual(lang, 'tex') lang = highlightjs.get_hljs_language_from_mime_type('text/x-lisp') - self.assertEquals(lang, 'lisp') + self.assertEqual(lang, 'lisp') lang = highlightjs.get_hljs_language_from_mime_type('text/x-java') - self.assertEquals(lang, 'java') + self.assertEqual(lang, 'java') lang = highlightjs.get_hljs_language_from_mime_type('text/x-makefile') - self.assertEquals(lang, 'makefile') + self.assertEqual(lang, 'makefile') lang = highlightjs.get_hljs_language_from_mime_type('text/x-shellscript') # noqa - self.assertEquals(lang, 'bash') + self.assertEqual(lang, 'bash') lang = highlightjs.get_hljs_language_from_mime_type('image/png') - self.assertEquals(lang, None) + self.assertEqual(lang, None) def test_get_hljs_language_from_filename(self): lang = highlightjs.get_hljs_language_from_filename('foo') - self.assertEquals(lang, None) + self.assertEqual(lang, None) lang = highlightjs.get_hljs_language_from_filename('foo.h') - self.assertEquals(lang, 'cpp') + self.assertEqual(lang, 'cpp') lang = highlightjs.get_hljs_language_from_filename('foo.c') - self.assertEquals(lang, 'cpp') + self.assertEqual(lang, 'cpp') lang = highlightjs.get_hljs_language_from_filename('foo.c.in') - self.assertEquals(lang, 'cpp') + self.assertEqual(lang, 'cpp') lang = highlightjs.get_hljs_language_from_filename('foo.cpp') - self.assertEquals(lang, 'cpp') + self.assertEqual(lang, 'cpp') lang = highlightjs.get_hljs_language_from_filename('foo.pl') - self.assertEquals(lang, 'perl') + self.assertEqual(lang, 'perl') lang = highlightjs.get_hljs_language_from_filename('foo.py') - self.assertEquals(lang, 'python') + self.assertEqual(lang, 'python') lang = highlightjs.get_hljs_language_from_filename('foo.md') - self.assertEquals(lang, 'markdown') + self.assertEqual(lang, 'markdown') lang = highlightjs.get_hljs_language_from_filename('foo.js') - self.assertEquals(lang, 'javascript') + self.assertEqual(lang, 'javascript') lang = highlightjs.get_hljs_language_from_filename('foo.bat') - self.assertEquals(lang, 'dos') + self.assertEqual(lang, 'dos') lang = highlightjs.get_hljs_language_from_filename('foo.json') - self.assertEquals(lang, 'json') + self.assertEqual(lang, 'json') lang = highlightjs.get_hljs_language_from_filename('foo.yml') - self.assertEquals(lang, 'yaml') + self.assertEqual(lang, 'yaml') lang = highlightjs.get_hljs_language_from_filename('foo.ini') - self.assertEquals(lang, 'ini') + self.assertEqual(lang, 'ini') lang = highlightjs.get_hljs_language_from_filename('foo.cfg') - self.assertEquals(lang, 'ini') + self.assertEqual(lang, 'ini') lang = highlightjs.get_hljs_language_from_filename('foo.hy') - self.assertEquals(lang, 'hy') + self.assertEqual(lang, 'hy') lang = highlightjs.get_hljs_language_from_filename('foo.lisp') - self.assertEquals(lang, 'lisp') + self.assertEqual(lang, 'lisp') lang = highlightjs.get_hljs_language_from_filename('foo.java') - self.assertEquals(lang, 'java') + self.assertEqual(lang, 'java') lang = highlightjs.get_hljs_language_from_filename('foo.sh') - self.assertEquals(lang, 'bash') + self.assertEqual(lang, 'bash') lang = highlightjs.get_hljs_language_from_filename('foo.cmake') - self.assertEquals(lang, 'cmake') + self.assertEqual(lang, 'cmake') lang = highlightjs.get_hljs_language_from_filename('foo.ml') - self.assertEquals(lang, 'ocaml') + self.assertEqual(lang, 'ocaml') lang = highlightjs.get_hljs_language_from_filename('foo.mli') - self.assertEquals(lang, 'ocaml') + self.assertEqual(lang, 'ocaml') lang = highlightjs.get_hljs_language_from_filename('foo.rb') - self.assertEquals(lang, 'ruby') + self.assertEqual(lang, 'ruby') lang = highlightjs.get_hljs_language_from_filename('foo.jl') - self.assertEquals(lang, 'julia') + self.assertEqual(lang, 'julia') lang = highlightjs.get_hljs_language_from_filename('Makefile') - self.assertEquals(lang, 'makefile') + self.assertEqual(lang, 'makefile') lang = highlightjs.get_hljs_language_from_filename('CMakeLists.txt') - self.assertEquals(lang, 'cmake') + self.assertEqual(lang, 'cmake') diff --git a/swh/web/tests/common/test_query.py b/swh/web/tests/common/test_query.py index 3341f900b..e3086ed36 100644 --- a/swh/web/tests/common/test_query.py +++ b/swh/web/tests/common/test_query.py @@ -1,124 +1,124 @@ # Copyright (C) 2015-2018 The Software Heritage developers # See the AUTHORS file at the top-level directory of this distribution # License: GNU Affero General Public License version 3, or any later version # See top-level LICENSE file for more information from unittest.mock import patch from swh.model import hashutil from swh.web.common import query from swh.web.common.exc import BadInputExc from swh.web.tests.testcase import SWHWebTestCase class QueryTestCase(SWHWebTestCase): def test_parse_hash_malformed_query_with_more_than_2_parts(self): with self.assertRaises(BadInputExc): query.parse_hash('sha1:1234567890987654:other-stuff') def test_parse_hash_guess_sha1(self): h = 'f1d2d2f924e986ac86fdf7b36c94bcdf32beec15' r = query.parse_hash(h) - self.assertEquals(r, ('sha1', hashutil.hash_to_bytes(h))) + self.assertEqual(r, ('sha1', hashutil.hash_to_bytes(h))) def test_parse_hash_guess_sha256(self): h = '084C799CD551DD1D8D5C5F9A5D593B2' \ 'E931F5E36122ee5c793c1d08a19839cc0' r = query.parse_hash(h) - self.assertEquals(r, ('sha256', hashutil.hash_to_bytes(h))) + self.assertEqual(r, ('sha256', hashutil.hash_to_bytes(h))) def test_parse_hash_guess_algo_malformed_hash(self): with self.assertRaises(BadInputExc): query.parse_hash('1234567890987654') def test_parse_hash_check_sha1(self): h = 'f1d2d2f924e986ac86fdf7b36c94bcdf32beec15' r = query.parse_hash('sha1:' + h) - self.assertEquals(r, ('sha1', hashutil.hash_to_bytes(h))) + self.assertEqual(r, ('sha1', hashutil.hash_to_bytes(h))) def test_parse_hash_check_sha1_git(self): h = 'e1d2d2f924e986ac86fdf7b36c94bcdf32beec15' r = query.parse_hash('sha1_git:' + h) - self.assertEquals(r, ('sha1_git', hashutil.hash_to_bytes(h))) + self.assertEqual(r, ('sha1_git', hashutil.hash_to_bytes(h))) def test_parse_hash_check_sha256(self): h = '084C799CD551DD1D8D5C5F9A5D593B2E931F5E36122ee5c793c1d08a19839cc0' r = query.parse_hash('sha256:' + h) - self.assertEquals(r, ('sha256', hashutil.hash_to_bytes(h))) + self.assertEqual(r, ('sha256', hashutil.hash_to_bytes(h))) def test_parse_hash_check_algo_malformed_sha1_hash(self): with self.assertRaises(BadInputExc): query.parse_hash('sha1:1234567890987654') def test_parse_hash_check_algo_malformed_sha1_git_hash(self): with self.assertRaises(BadInputExc): query.parse_hash('sha1_git:1234567890987654') def test_parse_hash_check_algo_malformed_sha256_hash(self): with self.assertRaises(BadInputExc): query.parse_hash('sha256:1234567890987654') def test_parse_hash_check_algo_unknown_one(self): with self.assertRaises(BadInputExc): query.parse_hash('sha2:1234567890987654') @patch('swh.web.common.query.parse_hash') def test_parse_hash_with_algorithms_or_throws_bad_query(self, mock_hash): # given mock_hash.side_effect = BadInputExc('Error input') # when with self.assertRaises(BadInputExc) as cm: query.parse_hash_with_algorithms_or_throws( 'sha1:blah', ['sha1'], 'useless error message for this use case') self.assertIn('Error input', cm.exception.args[0]) mock_hash.assert_called_once_with('sha1:blah') @patch('swh.web.common.query.parse_hash') def test_parse_hash_with_algorithms_or_throws_bad_algo(self, mock_hash): # given mock_hash.return_value = 'sha1', '123' # when with self.assertRaises(BadInputExc) as cm: query.parse_hash_with_algorithms_or_throws( 'sha1:431', ['sha1_git'], 'Only sha1_git!') self.assertIn('Only sha1_git!', cm.exception.args[0]) mock_hash.assert_called_once_with('sha1:431') @patch('swh.web.common.query.parse_hash') def test_parse_hash_with_algorithms(self, mock_hash): # given mock_hash.return_value = ('sha256', b'123') # when algo, sha = query.parse_hash_with_algorithms_or_throws( 'sha256:123', ['sha256', 'sha1_git'], 'useless error message for this use case') - self.assertEquals(algo, 'sha256') - self.assertEquals(sha, b'123') + self.assertEqual(algo, 'sha256') + self.assertEqual(sha, b'123') mock_hash.assert_called_once_with('sha256:123') def test_parse_uuid4(self): # when actual_uuid = query.parse_uuid4('7c33636b-8f11-4bda-89d9-ba8b76a42cec') # then - self.assertEquals(actual_uuid, '7c33636b-8f11-4bda-89d9-ba8b76a42cec') + self.assertEqual(actual_uuid, '7c33636b-8f11-4bda-89d9-ba8b76a42cec') def test_parse_uuid4_ko(self): # when with self.assertRaises(BadInputExc) as cm: query.parse_uuid4('7c33636b-8f11-4bda-89d9-ba8b76a42') self.assertIn('badly formed hexadecimal UUID string', cm.exception.args[0]) diff --git a/swh/web/tests/common/test_service.py b/swh/web/tests/common/test_service.py index 3ec5f8c16..b7cca942f 100644 --- a/swh/web/tests/common/test_service.py +++ b/swh/web/tests/common/test_service.py @@ -1,2011 +1,2011 @@ # Copyright (C) 2015-2018 The Software Heritage developers # See the AUTHORS file at the top-level directory of this distribution # License: GNU Affero General Public License version 3, or any later version # See top-level LICENSE file for more information import datetime from unittest.mock import MagicMock, patch, call from swh.model.hashutil import hash_to_bytes, hash_to_hex from swh.web.common import service from swh.web.common.exc import BadInputExc, NotFoundExc from swh.web.tests.testcase import SWHWebTestCase class ServiceTestCase(SWHWebTestCase): def setUp(self): self.BLAKE2S256_SAMPLE = ('685395c5dc57cada459364f0946d3dd45b' 'ad5fcbabc1048edb44380f1d31d0aa') self.BLAKE2S256_SAMPLE_BIN = hash_to_bytes(self.BLAKE2S256_SAMPLE) self.SHA1_SAMPLE = '40e71b8614fcd89ccd17ca2b1d9e66c5b00a6d03' self.SHA1_SAMPLE_BIN = hash_to_bytes(self.SHA1_SAMPLE) self.SHA256_SAMPLE = ('8abb0aa566452620ecce816eecdef4792d77a' '293ad8ea82a4d5ecb4d36f7e560') self.SHA256_SAMPLE_BIN = hash_to_bytes(self.SHA256_SAMPLE) self.SHA1GIT_SAMPLE = '25d1a2e8f32937b0f498a5ca87f823d8df013c01' self.SHA1GIT_SAMPLE_BIN = hash_to_bytes(self.SHA1GIT_SAMPLE) self.DIRECTORY_ID = '7834ef7e7c357ce2af928115c6c6a42b7e2a44e6' self.DIRECTORY_ID_BIN = hash_to_bytes(self.DIRECTORY_ID) self.AUTHOR_ID_BIN = { 'name': b'author', 'email': b'author@company.org', } self.AUTHOR_ID = { 'name': 'author', 'email': 'author@company.org', } self.COMMITTER_ID_BIN = { 'name': b'committer', 'email': b'committer@corp.org', } self.COMMITTER_ID = { 'name': 'committer', 'email': 'committer@corp.org', } self.SAMPLE_DATE_RAW = { 'timestamp': datetime.datetime( 2000, 1, 17, 11, 23, 54, tzinfo=datetime.timezone.utc, ).timestamp(), 'offset': 0, 'negative_utc': False, } self.SAMPLE_DATE = '2000-01-17T11:23:54+00:00' self.SAMPLE_MESSAGE_BIN = b'elegant fix for bug 31415957' self.SAMPLE_MESSAGE = 'elegant fix for bug 31415957' self.SAMPLE_REVISION = { 'id': self.SHA1_SAMPLE, 'directory': self.DIRECTORY_ID, 'author': self.AUTHOR_ID, 'committer': self.COMMITTER_ID, 'message': self.SAMPLE_MESSAGE, 'date': self.SAMPLE_DATE, 'committer_date': self.SAMPLE_DATE, 'synthetic': False, 'type': 'git', 'parents': [], 'metadata': {}, 'merge': False } self.SAMPLE_REVISION_RAW = { 'id': self.SHA1_SAMPLE_BIN, 'directory': self.DIRECTORY_ID_BIN, 'author': self.AUTHOR_ID_BIN, 'committer': self.COMMITTER_ID_BIN, 'message': self.SAMPLE_MESSAGE_BIN, 'date': self.SAMPLE_DATE_RAW, 'committer_date': self.SAMPLE_DATE_RAW, 'synthetic': False, 'type': 'git', 'parents': [], 'metadata': [], } self.SAMPLE_CONTENT = { 'checksums': { 'blake2s256': self.BLAKE2S256_SAMPLE, 'sha1': self.SHA1_SAMPLE, 'sha256': self.SHA256_SAMPLE, 'sha1_git': self.SHA1GIT_SAMPLE, }, 'length': 190, 'status': 'absent' } self.SAMPLE_CONTENT_RAW = { 'blake2s256': self.BLAKE2S256_SAMPLE_BIN, 'sha1': self.SHA1_SAMPLE_BIN, 'sha256': self.SHA256_SAMPLE_BIN, 'sha1_git': self.SHA1GIT_SAMPLE_BIN, 'length': 190, 'status': 'hidden' } self.date_origin_visit1 = datetime.datetime( 2015, 1, 1, 22, 0, 0, tzinfo=datetime.timezone.utc) self.origin_visit1 = { 'date': self.date_origin_visit1, 'origin': 1, 'visit': 1 } @patch('swh.web.common.service.storage') def test_lookup_multiple_hashes_ball_missing(self, mock_storage): # given mock_storage.content_missing_per_sha1 = MagicMock(return_value=[]) # when actual_lookup = service.lookup_multiple_hashes( [{'filename': 'a', 'sha1': '456caf10e9535160d90e874b45aa426de762f19f'}, {'filename': 'b', 'sha1': '745bab676c8f3cec8016e0c39ea61cf57e518865'}]) # then - self.assertEquals(actual_lookup, [ + self.assertEqual(actual_lookup, [ {'filename': 'a', 'sha1': '456caf10e9535160d90e874b45aa426de762f19f', 'found': True}, {'filename': 'b', 'sha1': '745bab676c8f3cec8016e0c39ea61cf57e518865', 'found': True} ]) @patch('swh.web.common.service.storage') def test_lookup_multiple_hashes_some_missing(self, mock_storage): # given mock_storage.content_missing_per_sha1 = MagicMock(return_value=[ hash_to_bytes('456caf10e9535160d90e874b45aa426de762f19f') ]) # when actual_lookup = service.lookup_multiple_hashes( [{'filename': 'a', 'sha1': '456caf10e9535160d90e874b45aa426de762f19f'}, {'filename': 'b', 'sha1': '745bab676c8f3cec8016e0c39ea61cf57e518865'}]) # then - self.assertEquals(actual_lookup, [ + self.assertEqual(actual_lookup, [ {'filename': 'a', 'sha1': '456caf10e9535160d90e874b45aa426de762f19f', 'found': False}, {'filename': 'b', 'sha1': '745bab676c8f3cec8016e0c39ea61cf57e518865', 'found': True} ]) @patch('swh.web.common.service.storage') def test_lookup_hash_does_not_exist(self, mock_storage): # given mock_storage.content_find = MagicMock(return_value=None) # when actual_lookup = service.lookup_hash( 'sha1_git:123caf10e9535160d90e874b45aa426de762f19f') # then - self.assertEquals({'found': None, - 'algo': 'sha1_git'}, actual_lookup) + self.assertEqual({'found': None, + 'algo': 'sha1_git'}, actual_lookup) # check the function has been called with parameters mock_storage.content_find.assert_called_with( {'sha1_git': hash_to_bytes('123caf10e9535160d90e874b45aa426de762f19f')}) @patch('swh.web.common.service.storage') def test_lookup_hash_exist(self, mock_storage): # given stub_content = { 'sha1': hash_to_bytes( '456caf10e9535160d90e874b45aa426de762f19f') } mock_storage.content_find = MagicMock(return_value=stub_content) # when actual_lookup = service.lookup_hash( 'sha1:456caf10e9535160d90e874b45aa426de762f19f') # then - self.assertEquals({'found': stub_content, - 'algo': 'sha1'}, actual_lookup) + self.assertEqual({'found': stub_content, + 'algo': 'sha1'}, actual_lookup) mock_storage.content_find.assert_called_with( {'sha1': hash_to_bytes('456caf10e9535160d90e874b45aa426de762f19f')} ) @patch('swh.web.common.service.storage') def test_search_hash_does_not_exist(self, mock_storage): # given mock_storage.content_find = MagicMock(return_value=None) # when actual_lookup = service.search_hash( 'sha1_git:123caf10e9535160d90e874b45aa426de762f19f') # then - self.assertEquals({'found': False}, actual_lookup) + self.assertEqual({'found': False}, actual_lookup) # check the function has been called with parameters mock_storage.content_find.assert_called_with( {'sha1_git': hash_to_bytes('123caf10e9535160d90e874b45aa426de762f19f')}) @patch('swh.web.common.service.storage') def test_search_hash_exist(self, mock_storage): # given stub_content = { 'sha1': hash_to_bytes( '456caf10e9535160d90e874b45aa426de762f19f') } mock_storage.content_find = MagicMock(return_value=stub_content) # when actual_lookup = service.search_hash( 'sha1:456caf10e9535160d90e874b45aa426de762f19f') # then - self.assertEquals({'found': True}, actual_lookup) + self.assertEqual({'found': True}, actual_lookup) mock_storage.content_find.assert_called_with( {'sha1': hash_to_bytes('456caf10e9535160d90e874b45aa426de762f19f')}, ) @patch('swh.web.common.service.idx_storage') def test_lookup_content_ctags(self, mock_idx_storage): # given mock_idx_storage.content_ctags_get = MagicMock( return_value=[{ 'id': hash_to_bytes( '123caf10e9535160d90e874b45aa426de762f19f'), 'line': 100, 'name': 'hello', 'kind': 'function', 'tool_name': 'ctags', 'tool_version': 'some-version', }]) expected_ctags = [{ 'id': '123caf10e9535160d90e874b45aa426de762f19f', 'line': 100, 'name': 'hello', 'kind': 'function', 'tool_name': 'ctags', 'tool_version': 'some-version', }] # when actual_ctags = list(service.lookup_content_ctags( 'sha1:123caf10e9535160d90e874b45aa426de762f19f')) # then self.assertEqual(actual_ctags, expected_ctags) mock_idx_storage.content_ctags_get.assert_called_with( [hash_to_bytes('123caf10e9535160d90e874b45aa426de762f19f')]) @patch('swh.web.common.service.idx_storage') def test_lookup_content_ctags_no_hash(self, mock_idx_storage): # given mock_idx_storage.content_ctags_get = MagicMock(return_value=[]) # when actual_ctags = list(service.lookup_content_ctags( 'sha1:123caf10e9535160d90e874b45aa426de762f19f')) # then self.assertEqual(actual_ctags, []) @patch('swh.web.common.service.idx_storage') def test_lookup_content_filetype(self, mock_idx_storage): # given mock_idx_storage.content_mimetype_get = MagicMock( return_value=[{ 'id': hash_to_bytes( '123caf10e9535160d90e874b45aa426de762f19f'), 'mimetype': b'text/x-c++', 'encoding': b'us-ascii', }]) expected_filetype = { 'id': '123caf10e9535160d90e874b45aa426de762f19f', 'mimetype': 'text/x-c++', 'encoding': 'us-ascii', } # when actual_filetype = service.lookup_content_filetype( 'sha1:123caf10e9535160d90e874b45aa426de762f19f') # then self.assertEqual(actual_filetype, expected_filetype) mock_idx_storage.content_mimetype_get.assert_called_with( [hash_to_bytes('123caf10e9535160d90e874b45aa426de762f19f')]) @patch('swh.web.common.service.idx_storage') @patch('swh.web.common.service.storage') def test_lookup_content_filetype_2(self, mock_storage, mock_idx_storage): # given mock_storage.content_find = MagicMock( return_value={ 'sha1': hash_to_bytes( '123caf10e9535160d90e874b45aa426de762f19f') } ) mock_idx_storage.content_mimetype_get = MagicMock( return_value=[{ 'id': hash_to_bytes( '123caf10e9535160d90e874b45aa426de762f19f'), 'mimetype': b'text/x-python', 'encoding': b'us-ascii', }] ) expected_filetype = { 'id': '123caf10e9535160d90e874b45aa426de762f19f', 'mimetype': 'text/x-python', 'encoding': 'us-ascii', } # when actual_filetype = service.lookup_content_filetype( 'sha1_git:456caf10e9535160d90e874b45aa426de762f19f') # then self.assertEqual(actual_filetype, expected_filetype) mock_storage.content_find( 'sha1_git', hash_to_bytes( '456caf10e9535160d90e874b45aa426de762f19f') ) mock_idx_storage.content_mimetype_get.assert_called_with( [hash_to_bytes('123caf10e9535160d90e874b45aa426de762f19f')]) @patch('swh.web.common.service.idx_storage') def test_lookup_content_language(self, mock_idx_storage): # given mock_idx_storage.content_language_get = MagicMock( return_value=[{ 'id': hash_to_bytes( '123caf10e9535160d90e874b45aa426de762f19f'), 'lang': 'python', }]) expected_language = { 'id': '123caf10e9535160d90e874b45aa426de762f19f', 'lang': 'python', } # when actual_language = service.lookup_content_language( 'sha1:123caf10e9535160d90e874b45aa426de762f19f') # then self.assertEqual(actual_language, expected_language) mock_idx_storage.content_language_get.assert_called_with( [hash_to_bytes('123caf10e9535160d90e874b45aa426de762f19f')]) @patch('swh.web.common.service.idx_storage') @patch('swh.web.common.service.storage') def test_lookup_content_language_2(self, mock_storage, mock_idx_storage): # given mock_storage.content_find = MagicMock( return_value={ 'sha1': hash_to_bytes( '123caf10e9535160d90e874b45aa426de762f19f') } ) mock_idx_storage.content_language_get = MagicMock( return_value=[{ 'id': hash_to_bytes( '123caf10e9535160d90e874b45aa426de762f19f'), 'lang': 'haskell', }] ) expected_language = { 'id': '123caf10e9535160d90e874b45aa426de762f19f', 'lang': 'haskell', } # when actual_language = service.lookup_content_language( 'sha1_git:456caf10e9535160d90e874b45aa426de762f19f') # then self.assertEqual(actual_language, expected_language) mock_storage.content_find( 'sha1_git', hash_to_bytes( '456caf10e9535160d90e874b45aa426de762f19f') ) mock_idx_storage.content_language_get.assert_called_with( [hash_to_bytes('123caf10e9535160d90e874b45aa426de762f19f')]) @patch('swh.web.common.service.idx_storage') def test_lookup_expression(self, mock_idx_storage): # given mock_idx_storage.content_ctags_search = MagicMock( return_value=[{ 'id': hash_to_bytes( '123caf10e9535160d90e874b45aa426de762f19f'), 'name': 'foobar', 'kind': 'variable', 'lang': 'C', 'line': 10 }]) expected_ctags = [{ 'sha1': '123caf10e9535160d90e874b45aa426de762f19f', 'name': 'foobar', 'kind': 'variable', 'lang': 'C', 'line': 10 }] # when actual_ctags = list(service.lookup_expression( 'foobar', last_sha1='hash', per_page=10)) # then self.assertEqual(actual_ctags, expected_ctags) mock_idx_storage.content_ctags_search.assert_called_with( 'foobar', last_sha1='hash', limit=10) @patch('swh.web.common.service.idx_storage') def test_lookup_expression_no_result(self, mock_idx_storage): # given mock_idx_storage.content_ctags_search = MagicMock( return_value=[]) expected_ctags = [] # when actual_ctags = list(service.lookup_expression( 'barfoo', last_sha1='hash', per_page=10)) # then self.assertEqual(actual_ctags, expected_ctags) mock_idx_storage.content_ctags_search.assert_called_with( 'barfoo', last_sha1='hash', limit=10) @patch('swh.web.common.service.idx_storage') def test_lookup_content_license(self, mock_idx_storage): # given mock_idx_storage.content_fossology_license_get = MagicMock( return_value=[{ hash_to_bytes('123caf10e9535160d90e874b45aa426de762f19f'): [{ 'licenses': ['GPL-3.0+'], 'tool': {} }] }]) expected_license = { 'id': '123caf10e9535160d90e874b45aa426de762f19f', 'facts': [{ 'licenses': ['GPL-3.0+'], 'tool': {} }] } # when actual_license = service.lookup_content_license( 'sha1:123caf10e9535160d90e874b45aa426de762f19f') # then self.assertEqual(actual_license, expected_license) mock_idx_storage.content_fossology_license_get.assert_called_with( [hash_to_bytes('123caf10e9535160d90e874b45aa426de762f19f')]) @patch('swh.web.common.service.idx_storage') @patch('swh.web.common.service.storage') def test_lookup_content_license_2(self, mock_storage, mock_idx_storage): # given mock_storage.content_find = MagicMock( return_value={ 'sha1': hash_to_bytes( '123caf10e9535160d90e874b45aa426de762f19f') } ) mock_idx_storage.content_fossology_license_get = MagicMock( return_value=[{ hash_to_bytes('123caf10e9535160d90e874b45aa426de762f19f'): [{ 'licenses': ['BSD-2-Clause'], 'tool': {} }] }] ) expected_license = { 'id': '123caf10e9535160d90e874b45aa426de762f19f', 'facts': [{ 'licenses': ['BSD-2-Clause'], 'tool': {} }] } # when actual_license = service.lookup_content_license( 'sha1_git:456caf10e9535160d90e874b45aa426de762f19f') # then self.assertEqual(actual_license, expected_license) mock_storage.content_find( 'sha1_git', hash_to_bytes( '456caf10e9535160d90e874b45aa426de762f19f') ) mock_idx_storage.content_fossology_license_get.assert_called_with( [hash_to_bytes('123caf10e9535160d90e874b45aa426de762f19f')]) @patch('swh.web.common.service.storage') def test_lookup_content_provenance(self, mock_storage): # given mock_storage.content_find_provenance = MagicMock( return_value=(p for p in [{ 'content': hash_to_bytes( '123caf10e9535160d90e874b45aa426de762f19f'), 'revision': hash_to_bytes( '456caf10e9535160d90e874b45aa426de762f19f'), 'origin': 100, 'visit': 1, 'path': b'octavio-3.4.0/octave.html/doc_002dS_005fISREG.html' }])) expected_provenances = [{ 'content': '123caf10e9535160d90e874b45aa426de762f19f', 'revision': '456caf10e9535160d90e874b45aa426de762f19f', 'origin': 100, 'visit': 1, 'path': 'octavio-3.4.0/octave.html/doc_002dS_005fISREG.html' }] # when actual_provenances = service.lookup_content_provenance( 'sha1_git:123caf10e9535160d90e874b45aa426de762f19f') # then self.assertEqual(list(actual_provenances), expected_provenances) mock_storage.content_find_provenance.assert_called_with( {'sha1_git': hash_to_bytes('123caf10e9535160d90e874b45aa426de762f19f')}) @patch('swh.web.common.service.storage') def test_lookup_content_provenance_not_found(self, mock_storage): # given mock_storage.content_find_provenance = MagicMock(return_value=None) # when actual_provenances = service.lookup_content_provenance( 'sha1_git:456caf10e9535160d90e874b45aa426de762f19f') # then self.assertIsNone(actual_provenances) mock_storage.content_find_provenance.assert_called_with( {'sha1_git': hash_to_bytes('456caf10e9535160d90e874b45aa426de762f19f')}) @patch('swh.web.common.service.storage') def test_stat_counters(self, mock_storage): # given input_stats = { "content": 1770830, "directory": 211683, "directory_entry_dir": 209167, "directory_entry_file": 1807094, "directory_entry_rev": 0, "entity": 0, "entity_history": 0, "origin": 1096, "person": 0, "release": 8584, "revision": 7792, "revision_history": 0, "skipped_content": 0 } mock_storage.stat_counters = MagicMock(return_value=input_stats) # when actual_stats = service.stat_counters() # then expected_stats = input_stats self.assertEqual(actual_stats, expected_stats) mock_storage.stat_counters.assert_called_with() @patch('swh.web.common.service._lookup_origin_visits') def test_lookup_origin_visits(self, mock_lookup_visits): # given date_origin_visit2 = datetime.datetime( 2013, 7, 1, 20, 0, 0, tzinfo=datetime.timezone.utc) date_origin_visit3 = datetime.datetime( 2015, 1, 1, 21, 0, 0, tzinfo=datetime.timezone.utc) stub_result = [self.origin_visit1, { 'date': date_origin_visit2, 'origin': 1, 'visit': 2, 'target': hash_to_bytes( '65a55bbdf3629f916219feb3dcc7393ded1bc8db'), 'branch': b'master', 'target_type': 'release', 'metadata': None, }, { 'date': date_origin_visit3, 'origin': 1, 'visit': 3 }] mock_lookup_visits.return_value = stub_result # when expected_origin_visits = [{ 'date': self.origin_visit1['date'].isoformat(), 'origin': self.origin_visit1['origin'], 'visit': self.origin_visit1['visit'] }, { 'date': date_origin_visit2.isoformat(), 'origin': 1, 'visit': 2, 'target': '65a55bbdf3629f916219feb3dcc7393ded1bc8db', 'branch': 'master', 'target_type': 'release', 'metadata': {}, }, { 'date': date_origin_visit3.isoformat(), 'origin': 1, 'visit': 3 }] actual_origin_visits = service.lookup_origin_visits(6) # then self.assertEqual(list(actual_origin_visits), expected_origin_visits) mock_lookup_visits.assert_called_once_with( 6, last_visit=None, limit=10) @patch('swh.web.common.service.storage') def test_lookup_origin_visit(self, mock_storage): # given stub_result = self.origin_visit1 mock_storage.origin_visit_get_by.return_value = stub_result expected_origin_visit = { 'date': self.origin_visit1['date'].isoformat(), 'origin': self.origin_visit1['origin'], 'visit': self.origin_visit1['visit'] } # when actual_origin_visit = service.lookup_origin_visit(1, 1) # then self.assertEqual(actual_origin_visit, expected_origin_visit) mock_storage.origin_visit_get_by.assert_called_once_with(1, 1) @patch('swh.web.common.service.storage') def test_lookup_origin(self, mock_storage): # given mock_storage.origin_get = MagicMock(return_value={ 'id': 'origin-id', 'url': 'ftp://some/url/to/origin', 'type': 'ftp'}) # when actual_origin = service.lookup_origin({'id': 'origin-id'}) # then self.assertEqual(actual_origin, {'id': 'origin-id', 'url': 'ftp://some/url/to/origin', 'type': 'ftp'}) mock_storage.origin_get.assert_called_with({'id': 'origin-id'}) @patch('swh.web.common.service.storage') def test_lookup_release_ko_id_checksum_not_a_sha1(self, mock_storage): # given mock_storage.release_get = MagicMock() with self.assertRaises(BadInputExc) as cm: # when service.lookup_release('not-a-sha1') self.assertIn('invalid checksum', cm.exception.args[0].lower()) mock_storage.release_get.called = False @patch('swh.web.common.service.storage') def test_lookup_release_ko_id_checksum_too_long(self, mock_storage): # given mock_storage.release_get = MagicMock() # when with self.assertRaises(BadInputExc) as cm: service.lookup_release( '13c1d34d138ec13b5ebad226dc2528dc7506c956e4646f62d4daf5' '1aea892abe') self.assertEqual('Only sha1_git is supported.', cm.exception.args[0]) mock_storage.release_get.called = False @patch('swh.web.common.service.storage') def test_lookup_directory_with_path_not_found(self, mock_storage): # given mock_storage.lookup_directory_with_path = MagicMock(return_value=None) sha1_git = '65a55bbdf3629f916219feb3dcc7393ded1bc8db' # when actual_directory = mock_storage.lookup_directory_with_path( sha1_git, 'some/path/here') self.assertIsNone(actual_directory) @patch('swh.web.common.service.storage') def test_lookup_directory_with_path_found(self, mock_storage): # given sha1_git = '65a55bbdf3629f916219feb3dcc7393ded1bc8db' entry = {'id': 'dir-id', 'type': 'dir', 'name': 'some/path/foo'} mock_storage.lookup_directory_with_path = MagicMock(return_value=entry) # when actual_directory = mock_storage.lookup_directory_with_path( sha1_git, 'some/path/here') self.assertEqual(entry, actual_directory) @patch('swh.web.common.service.storage') def test_lookup_release(self, mock_storage): # given mock_storage.release_get = MagicMock(return_value=[{ 'id': hash_to_bytes('65a55bbdf3629f916219feb3dcc7393ded1bc8db'), 'target': None, 'date': { 'timestamp': datetime.datetime( 2015, 1, 1, 22, 0, 0, tzinfo=datetime.timezone.utc).timestamp(), 'offset': 0, 'negative_utc': True, }, 'name': b'v0.0.1', 'message': b'synthetic release', 'synthetic': True, }]) # when actual_release = service.lookup_release( '65a55bbdf3629f916219feb3dcc7393ded1bc8db') # then self.assertEqual(actual_release, { 'id': '65a55bbdf3629f916219feb3dcc7393ded1bc8db', 'target': None, 'date': '2015-01-01T22:00:00-00:00', 'name': 'v0.0.1', 'message': 'synthetic release', 'synthetic': True, }) mock_storage.release_get.assert_called_with( [hash_to_bytes('65a55bbdf3629f916219feb3dcc7393ded1bc8db')]) def test_lookup_revision_with_context_ko_not_a_sha1_1(self): # given sha1_git = '13c1d34d138ec13b5ebad226dc2528dc7506c956e4646f62d4' \ 'daf51aea892abe' sha1_git_root = '65a55bbdf3629f916219feb3dcc7393ded1bc8db' # when with self.assertRaises(BadInputExc) as cm: service.lookup_revision_with_context(sha1_git_root, sha1_git) self.assertIn('Only sha1_git is supported', cm.exception.args[0]) def test_lookup_revision_with_context_ko_not_a_sha1_2(self): # given sha1_git_root = '65a55bbdf3629f916219feb3dcc7393ded1bc8db' sha1_git = '13c1d34d138ec13b5ebad226dc2528dc7506c956e4646f6' \ '2d4daf51aea892abe' # when with self.assertRaises(BadInputExc) as cm: service.lookup_revision_with_context(sha1_git_root, sha1_git) self.assertIn('Only sha1_git is supported', cm.exception.args[0]) @patch('swh.web.common.service.storage') def test_lookup_revision_with_context_ko_sha1_git_does_not_exist( self, mock_storage): # given sha1_git_root = '65a55bbdf3629f916219feb3dcc7393ded1bc8db' sha1_git = '777777bdf3629f916219feb3dcc7393ded1bc8db' sha1_git_bin = hash_to_bytes(sha1_git) mock_storage.revision_get.return_value = None # when with self.assertRaises(NotFoundExc) as cm: service.lookup_revision_with_context(sha1_git_root, sha1_git) self.assertIn('Revision 777777bdf3629f916219feb3dcc7393ded1bc8db' ' not found', cm.exception.args[0]) mock_storage.revision_get.assert_called_once_with( [sha1_git_bin]) @patch('swh.web.common.service.storage') def test_lookup_revision_with_context_ko_root_sha1_git_does_not_exist( self, mock_storage): # given sha1_git_root = '65a55bbdf3629f916219feb3dcc7393ded1bc8db' sha1_git = '777777bdf3629f916219feb3dcc7393ded1bc8db' sha1_git_root_bin = hash_to_bytes(sha1_git_root) sha1_git_bin = hash_to_bytes(sha1_git) mock_storage.revision_get.side_effect = ['foo', None] # when with self.assertRaises(NotFoundExc) as cm: service.lookup_revision_with_context(sha1_git_root, sha1_git) self.assertIn('Revision root 65a55bbdf3629f916219feb3dcc7393ded1bc8db' ' not found', cm.exception.args[0]) mock_storage.revision_get.assert_has_calls([call([sha1_git_bin]), call([sha1_git_root_bin])]) @patch('swh.web.common.service.storage') @patch('swh.web.common.service.query') def test_lookup_revision_with_context(self, mock_query, mock_storage): # given sha1_git_root = '666' sha1_git = '883' sha1_git_root_bin = b'666' sha1_git_bin = b'883' sha1_git_root_dict = { 'id': sha1_git_root_bin, 'parents': [b'999'], } sha1_git_dict = { 'id': sha1_git_bin, 'parents': [], 'directory': b'278', } stub_revisions = [ sha1_git_root_dict, { 'id': b'999', 'parents': [b'777', b'883', b'888'], }, { 'id': b'777', 'parents': [b'883'], }, sha1_git_dict, { 'id': b'888', 'parents': [b'889'], }, { 'id': b'889', 'parents': [], }, ] # inputs ok mock_query.parse_hash_with_algorithms_or_throws.side_effect = [ ('sha1', sha1_git_bin), ('sha1', sha1_git_root_bin) ] # lookup revision first 883, then 666 (both exists) mock_storage.revision_get.return_value = [ sha1_git_dict, sha1_git_root_dict ] mock_storage.revision_log = MagicMock( return_value=stub_revisions) # when actual_revision = service.lookup_revision_with_context( sha1_git_root, sha1_git) # then - self.assertEquals(actual_revision, { + self.assertEqual(actual_revision, { 'id': hash_to_hex(sha1_git_bin), 'parents': [], 'children': [hash_to_hex(b'999'), hash_to_hex(b'777')], 'directory': hash_to_hex(b'278'), 'merge': False }) mock_query.parse_hash_with_algorithms_or_throws.assert_has_calls( [call(sha1_git, ['sha1'], 'Only sha1_git is supported.'), call(sha1_git_root, ['sha1'], 'Only sha1_git is supported.')]) mock_storage.revision_log.assert_called_with( [sha1_git_root_bin], 100) @patch('swh.web.common.service.storage') @patch('swh.web.common.service.query') def test_lookup_revision_with_context_retrieved_as_dict( self, mock_query, mock_storage): # given sha1_git = '883' sha1_git_root_bin = b'666' sha1_git_bin = b'883' sha1_git_root_dict = { 'id': sha1_git_root_bin, 'parents': [b'999'], } sha1_git_dict = { 'id': sha1_git_bin, 'parents': [], 'directory': b'278', } stub_revisions = [ sha1_git_root_dict, { 'id': b'999', 'parents': [b'777', b'883', b'888'], }, { 'id': b'777', 'parents': [b'883'], }, sha1_git_dict, { 'id': b'888', 'parents': [b'889'], }, { 'id': b'889', 'parents': [], }, ] # inputs ok mock_query.parse_hash_with_algorithms_or_throws.return_value = ( 'sha1', sha1_git_bin) # lookup only on sha1 mock_storage.revision_get.return_value = [sha1_git_dict] mock_storage.revision_log.return_value = stub_revisions # when actual_revision = service.lookup_revision_with_context( {'id': sha1_git_root_bin}, sha1_git) # then - self.assertEquals(actual_revision, { + self.assertEqual(actual_revision, { 'id': hash_to_hex(sha1_git_bin), 'parents': [], 'children': [hash_to_hex(b'999'), hash_to_hex(b'777')], 'directory': hash_to_hex(b'278'), 'merge': False }) mock_query.parse_hash_with_algorithms_or_throws.assert_called_once_with( # noqa sha1_git, ['sha1'], 'Only sha1_git is supported.') mock_storage.revision_get.assert_called_once_with([sha1_git_bin]) mock_storage.revision_log.assert_called_with( [sha1_git_root_bin], 100) @patch('swh.web.common.service.storage') @patch('swh.web.common.service.query') def test_lookup_directory_with_revision_not_found(self, mock_query, mock_storage): # given mock_query.parse_hash_with_algorithms_or_throws.return_value = ('sha1', b'123') mock_storage.revision_get.return_value = None # when with self.assertRaises(NotFoundExc) as cm: service.lookup_directory_with_revision('123') self.assertIn('Revision 123 not found', cm.exception.args[0]) mock_query.parse_hash_with_algorithms_or_throws.assert_called_once_with ('123', ['sha1'], 'Only sha1_git is supported.') mock_storage.revision_get.assert_called_once_with([b'123']) @patch('swh.web.common.service.storage') @patch('swh.web.common.service.query') def test_lookup_directory_with_revision_ko_revision_with_path_to_nowhere( self, mock_query, mock_storage): # given mock_query.parse_hash_with_algorithms_or_throws.return_value = ('sha1', b'123') dir_id = b'dir-id-as-sha1' mock_storage.revision_get.return_value = [{ 'directory': dir_id, }] mock_storage.directory_entry_get_by_path.return_value = None # when with self.assertRaises(NotFoundExc) as cm: service.lookup_directory_with_revision( '123', 'path/to/something/unknown') exception_text = cm.exception.args[0].lower() self.assertIn('directory or file', exception_text) self.assertIn('path/to/something/unknown', exception_text) self.assertIn('revision 123', exception_text) self.assertIn('not found', exception_text) mock_query.parse_hash_with_algorithms_or_throws.assert_called_once_with ('123', ['sha1'], 'Only sha1_git is supported.') mock_storage.revision_get.assert_called_once_with([b'123']) mock_storage.directory_entry_get_by_path.assert_called_once_with( b'dir-id-as-sha1', [b'path', b'to', b'something', b'unknown']) @patch('swh.web.common.service.storage') @patch('swh.web.common.service.query') def test_lookup_directory_with_revision_ko_type_not_implemented( self, mock_query, mock_storage): # given mock_query.parse_hash_with_algorithms_or_throws.return_value = ('sha1', b'123') dir_id = b'dir-id-as-sha1' mock_storage.revision_get.return_value = [{ 'directory': dir_id, }] mock_storage.directory_entry_get_by_path.return_value = { 'type': 'rev', 'name': b'some/path/to/rev', 'target': b'456' } stub_content = { 'id': b'12', 'type': 'file' } mock_storage.content_get.return_value = stub_content # when with self.assertRaises(NotImplementedError) as cm: service.lookup_directory_with_revision( '123', 'some/path/to/rev') self.assertIn("Entity of type rev not implemented.", cm.exception.args[0]) # then mock_query.parse_hash_with_algorithms_or_throws.assert_called_once_with ('123', ['sha1'], 'Only sha1_git is supported.') mock_storage.revision_get.assert_called_once_with([b'123']) mock_storage.directory_entry_get_by_path.assert_called_once_with( b'dir-id-as-sha1', [b'some', b'path', b'to', b'rev']) @patch('swh.web.common.service.storage') @patch('swh.web.common.service.query') def test_lookup_directory_with_revision_revision_without_path( self, mock_query, mock_storage, ): # given mock_query.parse_hash_with_algorithms_or_throws.return_value = ('sha1', b'123') dir_id = b'dir-id-as-sha1' mock_storage.revision_get.return_value = [{ 'directory': dir_id, }] stub_dir_entries = [{ 'id': b'123', 'type': 'dir' }, { 'id': b'456', 'type': 'file' }] mock_storage.directory_ls.return_value = stub_dir_entries # when actual_directory_entries = service.lookup_directory_with_revision( '123') self.assertEqual(actual_directory_entries['type'], 'dir') self.assertEqual(list(actual_directory_entries['content']), stub_dir_entries) mock_query.parse_hash_with_algorithms_or_throws.assert_called_once_with ('123', ['sha1'], 'Only sha1_git is supported.') mock_storage.revision_get.assert_called_once_with([b'123']) mock_storage.directory_ls.assert_called_once_with(dir_id) @patch('swh.web.common.service.storage') @patch('swh.web.common.service.query') def test_lookup_directory_with_revision_with_path_to_dir(self, mock_query, mock_storage): # given mock_query.parse_hash_with_algorithms_or_throws.return_value = ('sha1', b'123') dir_id = b'dir-id-as-sha1' mock_storage.revision_get.return_value = [{ 'directory': dir_id, }] stub_dir_entries = [{ 'id': b'12', 'type': 'dir' }, { 'id': b'34', 'type': 'file' }] mock_storage.directory_entry_get_by_path.return_value = { 'type': 'dir', 'name': b'some/path', 'target': b'456' } mock_storage.directory_ls.return_value = stub_dir_entries # when actual_directory_entries = service.lookup_directory_with_revision( '123', 'some/path') self.assertEqual(actual_directory_entries['type'], 'dir') self.assertEqual(actual_directory_entries['revision'], '123') self.assertEqual(actual_directory_entries['path'], 'some/path') self.assertEqual(list(actual_directory_entries['content']), stub_dir_entries) mock_query.parse_hash_with_algorithms_or_throws.assert_called_once_with ('123', ['sha1'], 'Only sha1_git is supported.') mock_storage.revision_get.assert_called_once_with([b'123']) mock_storage.directory_entry_get_by_path.assert_called_once_with( dir_id, [b'some', b'path']) mock_storage.directory_ls.assert_called_once_with(b'456') @patch('swh.web.common.service.storage') @patch('swh.web.common.service.query') def test_lookup_directory_with_revision_with_path_to_file_wo_data( self, mock_query, mock_storage): # given mock_query.parse_hash_with_algorithms_or_throws.return_value = ('sha1', b'123') dir_id = b'dir-id-as-sha1' mock_storage.revision_get.return_value = [{ 'directory': dir_id, }] mock_storage.directory_entry_get_by_path.return_value = { 'type': 'file', 'name': b'some/path/to/file', 'target': b'789' } stub_content = { 'status': 'visible', } mock_storage.content_find.return_value = stub_content # when actual_content = service.lookup_directory_with_revision( '123', 'some/path/to/file') # then self.assertEqual(actual_content, {'type': 'file', 'revision': '123', 'path': 'some/path/to/file', 'content': stub_content}) mock_query.parse_hash_with_algorithms_or_throws.assert_called_once_with ('123', ['sha1'], 'Only sha1_git is supported.') mock_storage.revision_get.assert_called_once_with([b'123']) mock_storage.directory_entry_get_by_path.assert_called_once_with( b'dir-id-as-sha1', [b'some', b'path', b'to', b'file']) mock_storage.content_find.assert_called_once_with({'sha1_git': b'789'}) @patch('swh.web.common.service.storage') @patch('swh.web.common.service.query') def test_lookup_directory_with_revision_with_path_to_file_w_data( self, mock_query, mock_storage): # given mock_query.parse_hash_with_algorithms_or_throws.return_value = ('sha1', b'123') dir_id = b'dir-id-as-sha1' mock_storage.revision_get.return_value = [{ 'directory': dir_id, }] mock_storage.directory_entry_get_by_path.return_value = { 'type': 'file', 'name': b'some/path/to/file', 'target': b'789' } stub_content = { 'status': 'visible', 'sha1': b'content-sha1' } mock_storage.content_find.return_value = stub_content mock_storage.content_get.return_value = [{ 'sha1': b'content-sha1', 'data': b'some raw data' }] expected_content = { 'status': 'visible', 'checksums': { 'sha1': hash_to_hex(b'content-sha1'), }, 'data': b'some raw data' } # when actual_content = service.lookup_directory_with_revision( '123', 'some/path/to/file', with_data=True) # then self.assertEqual(actual_content, {'type': 'file', 'revision': '123', 'path': 'some/path/to/file', 'content': expected_content}) mock_query.parse_hash_with_algorithms_or_throws.assert_called_once_with ('123', ['sha1'], 'Only sha1_git is supported.') mock_storage.revision_get.assert_called_once_with([b'123']) mock_storage.directory_entry_get_by_path.assert_called_once_with( b'dir-id-as-sha1', [b'some', b'path', b'to', b'file']) mock_storage.content_find.assert_called_once_with({'sha1_git': b'789'}) mock_storage.content_get.assert_called_once_with([b'content-sha1']) @patch('swh.web.common.service.storage') def test_lookup_revision(self, mock_storage): # given mock_storage.revision_get = MagicMock( return_value=[self.SAMPLE_REVISION_RAW]) # when actual_revision = service.lookup_revision( self.SHA1_SAMPLE) # then self.assertEqual(actual_revision, self.SAMPLE_REVISION) mock_storage.revision_get.assert_called_with( [self.SHA1_SAMPLE_BIN]) @patch('swh.web.common.service.storage') def test_lookup_revision_invalid_msg(self, mock_storage): # given stub_rev = self.SAMPLE_REVISION_RAW stub_rev['message'] = b'elegant fix for bug \xff' expected_revision = self.SAMPLE_REVISION expected_revision['message'] = None expected_revision['message_decoding_failed'] = True mock_storage.revision_get = MagicMock(return_value=[stub_rev]) # when actual_revision = service.lookup_revision( self.SHA1_SAMPLE) # then self.assertEqual(actual_revision, expected_revision) mock_storage.revision_get.assert_called_with( [self.SHA1_SAMPLE_BIN]) @patch('swh.web.common.service.storage') def test_lookup_revision_msg_ok(self, mock_storage): # given mock_storage.revision_get.return_value = [self.SAMPLE_REVISION_RAW] # when rv = service.lookup_revision_message( self.SHA1_SAMPLE) # then - self.assertEquals(rv, {'message': self.SAMPLE_MESSAGE_BIN}) + self.assertEqual(rv, {'message': self.SAMPLE_MESSAGE_BIN}) mock_storage.revision_get.assert_called_with( [self.SHA1_SAMPLE_BIN]) @patch('swh.web.common.service.storage') def test_lookup_revision_msg_absent(self, mock_storage): # given stub_revision = self.SAMPLE_REVISION_RAW del stub_revision['message'] mock_storage.revision_get.return_value = stub_revision # when with self.assertRaises(NotFoundExc) as cm: service.lookup_revision_message( self.SHA1_SAMPLE) # then mock_storage.revision_get.assert_called_with( [self.SHA1_SAMPLE_BIN]) self.assertEqual( cm.exception.args[0], 'No message for revision with sha1_git %s.' % self.SHA1_SAMPLE, ) @patch('swh.web.common.service.storage') def test_lookup_revision_msg_norev(self, mock_storage): # given mock_storage.revision_get.return_value = None # when with self.assertRaises(NotFoundExc) as cm: service.lookup_revision_message( self.SHA1_SAMPLE) # then mock_storage.revision_get.assert_called_with( [self.SHA1_SAMPLE_BIN]) self.assertEqual( cm.exception.args[0], 'Revision with sha1_git %s not found.' % self.SHA1_SAMPLE, ) @patch('swh.web.common.service.storage') def test_lookup_revision_multiple(self, mock_storage): # given sha1 = self.SHA1_SAMPLE sha1_other = 'adc83b19e793491b1c6ea0fd8b46cd9f32e592fc' stub_revisions = [ self.SAMPLE_REVISION_RAW, { 'id': hash_to_bytes(sha1_other), 'directory': 'abcdbe353ed3480476f032475e7c233eff7371d5', 'author': { 'name': b'name', 'email': b'name@surname.org', }, 'committer': { 'name': b'name', 'email': b'name@surname.org', }, 'message': b'ugly fix for bug 42', 'date': { 'timestamp': datetime.datetime( 2000, 1, 12, 5, 23, 54, tzinfo=datetime.timezone.utc).timestamp(), 'offset': 0, 'negative_utc': False }, 'date_offset': 0, 'committer_date': { 'timestamp': datetime.datetime( 2000, 1, 12, 5, 23, 54, tzinfo=datetime.timezone.utc).timestamp(), 'offset': 0, 'negative_utc': False }, 'committer_date_offset': 0, 'synthetic': False, 'type': 'git', 'parents': [], 'metadata': [], } ] mock_storage.revision_get.return_value = stub_revisions # when actual_revisions = service.lookup_revision_multiple( [sha1, sha1_other]) # then self.assertEqual(list(actual_revisions), [ self.SAMPLE_REVISION, { 'id': sha1_other, 'directory': 'abcdbe353ed3480476f032475e7c233eff7371d5', 'author': { 'name': 'name', 'email': 'name@surname.org', }, 'committer': { 'name': 'name', 'email': 'name@surname.org', }, 'message': 'ugly fix for bug 42', 'date': '2000-01-12T05:23:54+00:00', 'date_offset': 0, 'committer_date': '2000-01-12T05:23:54+00:00', 'committer_date_offset': 0, 'synthetic': False, 'type': 'git', 'parents': [], 'metadata': {}, 'merge': False } ]) self.assertEqual( list(mock_storage.revision_get.call_args[0][0]), [hash_to_bytes(sha1), hash_to_bytes(sha1_other)]) @patch('swh.web.common.service.storage') def test_lookup_revision_multiple_none_found(self, mock_storage): # given sha1_bin = self.SHA1_SAMPLE sha1_other = 'adc83b19e793491b1c6ea0fd8b46cd9f32e592fc' mock_storage.revision_get.return_value = [] # then actual_revisions = service.lookup_revision_multiple( [sha1_bin, sha1_other]) self.assertEqual(list(actual_revisions), []) self.assertEqual( list(mock_storage.revision_get.call_args[0][0]), [hash_to_bytes(self.SHA1_SAMPLE), hash_to_bytes(sha1_other)]) @patch('swh.web.common.service.storage') def test_lookup_revision_log(self, mock_storage): # given stub_revision_log = [self.SAMPLE_REVISION_RAW] mock_storage.revision_log = MagicMock(return_value=stub_revision_log) # when actual_revision = service.lookup_revision_log( 'abcdbe353ed3480476f032475e7c233eff7371d5', limit=25) # then self.assertEqual(list(actual_revision), [self.SAMPLE_REVISION]) mock_storage.revision_log.assert_called_with( [hash_to_bytes('abcdbe353ed3480476f032475e7c233eff7371d5')], 25) @patch('swh.web.common.service.storage') def test_lookup_revision_log_by(self, mock_storage): # given stub_revision_log = [self.SAMPLE_REVISION_RAW] mock_storage.revision_log_by = MagicMock( return_value=stub_revision_log) # when actual_log = service.lookup_revision_log_by( 1, 'refs/heads/master', None, limit=100) # then self.assertEqual(list(actual_log), [self.SAMPLE_REVISION]) mock_storage.revision_log_by.assert_called_with( 1, 'refs/heads/master', None, limit=100) @patch('swh.web.common.service.storage') def test_lookup_revision_log_by_nolog(self, mock_storage): # given mock_storage.revision_log_by = MagicMock(return_value=None) # when res = service.lookup_revision_log_by( 1, 'refs/heads/master', None, limit=100) # then - self.assertEquals(res, None) + self.assertEqual(res, None) mock_storage.revision_log_by.assert_called_with( 1, 'refs/heads/master', None, limit=100) @patch('swh.web.common.service.storage') def test_lookup_content_raw_not_found(self, mock_storage): # given mock_storage.content_find = MagicMock(return_value=None) # when with self.assertRaises(NotFoundExc) as cm: service.lookup_content_raw('sha1:' + self.SHA1_SAMPLE) self.assertIn(cm.exception.args[0], 'Content with %s checksum equals to %s not found!' % ('sha1', self.SHA1_SAMPLE)) mock_storage.content_find.assert_called_with( {'sha1': hash_to_bytes(self.SHA1_SAMPLE)}) @patch('swh.web.common.service.storage') def test_lookup_content_raw(self, mock_storage): # given mock_storage.content_find = MagicMock(return_value={ 'sha1': self.SHA1_SAMPLE, }) mock_storage.content_get = MagicMock(return_value=[{ 'data': b'binary data'}]) # when actual_content = service.lookup_content_raw( 'sha256:%s' % self.SHA256_SAMPLE) # then - self.assertEquals(actual_content, {'data': b'binary data'}) + self.assertEqual(actual_content, {'data': b'binary data'}) mock_storage.content_find.assert_called_once_with( {'sha256': self.SHA256_SAMPLE_BIN}) mock_storage.content_get.assert_called_once_with( [self.SHA1_SAMPLE]) @patch('swh.web.common.service.storage') def test_lookup_content_not_found(self, mock_storage): # given mock_storage.content_find = MagicMock(return_value=None) # when with self.assertRaises(NotFoundExc) as cm: # then service.lookup_content('sha1:%s' % self.SHA1_SAMPLE) self.assertIn(cm.exception.args[0], 'Content with %s checksum equals to %s not found!' % ('sha1', self.SHA1_SAMPLE)) mock_storage.content_find.assert_called_with( {'sha1': self.SHA1_SAMPLE_BIN}) @patch('swh.web.common.service.storage') def test_lookup_content_with_sha1(self, mock_storage): # given mock_storage.content_find = MagicMock( return_value=self.SAMPLE_CONTENT_RAW) # when actual_content = service.lookup_content( 'sha1:%s' % self.SHA1_SAMPLE) # then self.assertEqual(actual_content, self.SAMPLE_CONTENT) mock_storage.content_find.assert_called_with( {'sha1': hash_to_bytes(self.SHA1_SAMPLE)}) @patch('swh.web.common.service.storage') def test_lookup_content_with_sha256(self, mock_storage): # given stub_content = self.SAMPLE_CONTENT_RAW stub_content['status'] = 'visible' expected_content = self.SAMPLE_CONTENT expected_content['status'] = 'visible' mock_storage.content_find = MagicMock( return_value=stub_content) # when actual_content = service.lookup_content( 'sha256:%s' % self.SHA256_SAMPLE) # then self.assertEqual(actual_content, expected_content) mock_storage.content_find.assert_called_with( {'sha256': self.SHA256_SAMPLE_BIN}) @patch('swh.web.common.service.storage') def test_lookup_person(self, mock_storage): # given mock_storage.person_get = MagicMock(return_value=[{ 'id': 'person_id', 'name': b'some_name', 'email': b'some-email', }]) # when actual_person = service.lookup_person('person_id') # then self.assertEqual(actual_person, { 'id': 'person_id', 'name': 'some_name', 'email': 'some-email', }) mock_storage.person_get.assert_called_with(['person_id']) @patch('swh.web.common.service.storage') def test_lookup_directory_bad_checksum(self, mock_storage): # given mock_storage.directory_ls = MagicMock() # when with self.assertRaises(BadInputExc): service.lookup_directory('directory_id') # then mock_storage.directory_ls.called = False @patch('swh.web.common.service.storage') @patch('swh.web.common.service.query') def test_lookup_directory_not_found(self, mock_query, mock_storage): # given mock_query.parse_hash_with_algorithms_or_throws.return_value = ( 'sha1', 'directory-id-bin') mock_storage.directory_ls.return_value = [] # when with self.assertRaises(NotFoundExc) as cm: service.lookup_directory('directory_id') self.assertIn('Directory with sha1_git directory_id not found', cm.exception.args[0]) # then mock_query.parse_hash_with_algorithms_or_throws.assert_called_with( 'directory_id', ['sha1'], 'Only sha1_git is supported.') mock_storage.directory_ls.assert_called_with('directory-id-bin') @patch('swh.web.common.service.storage') @patch('swh.web.common.service.query') def test_lookup_directory(self, mock_query, mock_storage): mock_query.parse_hash_with_algorithms_or_throws.return_value = ( 'sha1', 'directory-sha1-bin') # given stub_dir_entries = [{ 'sha1': self.SHA1_SAMPLE_BIN, 'sha256': self.SHA256_SAMPLE_BIN, 'sha1_git': self.SHA1GIT_SAMPLE_BIN, 'blake2s256': self.BLAKE2S256_SAMPLE_BIN, 'target': hash_to_bytes( '40e71b8614fcd89ccd17ca2b1d9e66c5b00a6d03'), 'dir_id': self.DIRECTORY_ID_BIN, 'name': b'bob', 'type': 10, }] expected_dir_entries = [{ 'checksums': { 'sha1': self.SHA1_SAMPLE, 'sha256': self.SHA256_SAMPLE, 'sha1_git': self.SHA1GIT_SAMPLE, 'blake2s256': self.BLAKE2S256_SAMPLE }, 'target': '40e71b8614fcd89ccd17ca2b1d9e66c5b00a6d03', 'dir_id': self.DIRECTORY_ID, 'name': 'bob', 'type': 10, }] mock_storage.directory_ls.return_value = stub_dir_entries # when actual_directory_ls = list(service.lookup_directory( 'directory-sha1')) # then self.assertEqual(actual_directory_ls, expected_dir_entries) mock_query.parse_hash_with_algorithms_or_throws.assert_called_with( 'directory-sha1', ['sha1'], 'Only sha1_git is supported.') mock_storage.directory_ls.assert_called_with( 'directory-sha1-bin') @patch('swh.web.common.service.storage') def test_lookup_directory_empty(self, mock_storage): empty_dir_sha1 = '4b825dc642cb6eb9a060e54bf8d69288fbee4904' mock_storage.directory_ls.return_value = [] # when actual_directory_ls = list(service.lookup_directory(empty_dir_sha1)) # then self.assertEqual(actual_directory_ls, []) self.assertFalse(mock_storage.directory_ls.called) @patch('swh.web.common.service.storage') def test_lookup_revision_by_nothing_found(self, mock_storage): # given mock_storage.revision_get_by.return_value = None # when with self.assertRaises(NotFoundExc): service.lookup_revision_by(1) # then mock_storage.revision_get_by.assert_called_with(1, 'refs/heads/master', # noqa limit=1, timestamp=None) @patch('swh.web.common.service.storage') def test_lookup_revision_by(self, mock_storage): # given stub_rev = self.SAMPLE_REVISION_RAW expected_rev = self.SAMPLE_REVISION mock_storage.revision_get_by.return_value = [stub_rev] # when actual_revision = service.lookup_revision_by(10, 'master2', 'some-ts') # then - self.assertEquals(actual_revision, expected_rev) + self.assertEqual(actual_revision, expected_rev) mock_storage.revision_get_by.assert_called_with(10, 'master2', limit=1, timestamp='some-ts') @patch('swh.web.common.service.storage') def test_lookup_revision_by_nomerge(self, mock_storage): # given stub_rev = self.SAMPLE_REVISION_RAW stub_rev['parents'] = [ hash_to_bytes('adc83b19e793491b1c6ea0fd8b46cd9f32e592fc')] expected_rev = self.SAMPLE_REVISION expected_rev['parents'] = ['adc83b19e793491b1c6ea0fd8b46cd9f32e592fc'] mock_storage.revision_get_by.return_value = [stub_rev] # when actual_revision = service.lookup_revision_by(10, 'master2', 'some-ts') # then - self.assertEquals(actual_revision, expected_rev) + self.assertEqual(actual_revision, expected_rev) mock_storage.revision_get_by.assert_called_with(10, 'master2', limit=1, timestamp='some-ts') @patch('swh.web.common.service.storage') def test_lookup_revision_by_merge(self, mock_storage): # given stub_rev = self.SAMPLE_REVISION_RAW stub_rev['parents'] = [ hash_to_bytes('adc83b19e793491b1c6ea0fd8b46cd9f32e592fc'), hash_to_bytes('ffff3b19e793491b1c6db0fd8b46cd9f32e592fc') ] expected_rev = self.SAMPLE_REVISION expected_rev['parents'] = [ 'adc83b19e793491b1c6ea0fd8b46cd9f32e592fc', 'ffff3b19e793491b1c6db0fd8b46cd9f32e592fc' ] expected_rev['merge'] = True mock_storage.revision_get_by.return_value = [stub_rev] # when actual_revision = service.lookup_revision_by(10, 'master2', 'some-ts') # then - self.assertEquals(actual_revision, expected_rev) + self.assertEqual(actual_revision, expected_rev) mock_storage.revision_get_by.assert_called_with(10, 'master2', limit=1, timestamp='some-ts') @patch('swh.web.common.service.storage') def test_lookup_revision_with_context_by_ko(self, mock_storage): # given mock_storage.revision_get_by.return_value = None # when origin_id = 1 branch_name = 'master3' ts = None with self.assertRaises(NotFoundExc) as cm: service.lookup_revision_with_context_by(origin_id, branch_name, ts, 'sha1') # then self.assertIn( 'Revision with (origin_id: %s, branch_name: %s' ', ts: %s) not found.' % (origin_id, branch_name, ts), cm.exception.args[0]) mock_storage.revision_get_by.assert_called_once_with( origin_id, branch_name, limit=1, timestamp=ts) @patch('swh.web.common.service.lookup_revision_with_context') @patch('swh.web.common.service.storage') def test_lookup_revision_with_context_by( self, mock_storage, mock_lookup_revision_with_context, ): # given stub_root_rev = {'id': 'root-rev-id'} mock_storage.revision_get_by.return_value = [{'id': 'root-rev-id'}] stub_rev = {'id': 'rev-found'} mock_lookup_revision_with_context.return_value = stub_rev # when origin_id = 1 branch_name = 'master3' ts = None sha1_git = 'sha1' actual_root_rev, actual_rev = service.lookup_revision_with_context_by( origin_id, branch_name, ts, sha1_git) # then - self.assertEquals(actual_root_rev, stub_root_rev) - self.assertEquals(actual_rev, stub_rev) + self.assertEqual(actual_root_rev, stub_root_rev) + self.assertEqual(actual_rev, stub_rev) mock_storage.revision_get_by.assert_called_once_with( origin_id, branch_name, limit=1, timestamp=ts) mock_lookup_revision_with_context.assert_called_once_with( stub_root_rev, sha1_git, 100) @patch('swh.web.common.service.storage') @patch('swh.web.common.service.query') def test_lookup_entity_by_uuid(self, mock_query, mock_storage): # given uuid_test = 'correct-uuid' mock_query.parse_uuid4.return_value = uuid_test stub_entities = [{'uuid': uuid_test}] mock_storage.entity_get.return_value = stub_entities # when actual_entities = list(service.lookup_entity_by_uuid(uuid_test)) # then - self.assertEquals(actual_entities, stub_entities) + self.assertEqual(actual_entities, stub_entities) mock_query.parse_uuid4.assert_called_once_with(uuid_test) mock_storage.entity_get.assert_called_once_with(uuid_test) def test_lookup_revision_through_ko_not_implemented(self): # then with self.assertRaises(NotImplementedError): service.lookup_revision_through({ 'something-unknown': 10, }) @patch('swh.web.common.service.lookup_revision_with_context_by') def test_lookup_revision_through_with_context_by(self, mock_lookup): # given stub_rev = {'id': 'rev'} mock_lookup.return_value = stub_rev # when actual_revision = service.lookup_revision_through({ 'origin_id': 1, 'branch_name': 'master', 'ts': None, 'sha1_git': 'sha1-git' }, limit=1000) # then - self.assertEquals(actual_revision, stub_rev) + self.assertEqual(actual_revision, stub_rev) mock_lookup.assert_called_once_with( 1, 'master', None, 'sha1-git', 1000) @patch('swh.web.common.service.lookup_revision_by') def test_lookup_revision_through_with_revision_by(self, mock_lookup): # given stub_rev = {'id': 'rev'} mock_lookup.return_value = stub_rev # when actual_revision = service.lookup_revision_through({ 'origin_id': 2, 'branch_name': 'master2', 'ts': 'some-ts', }, limit=10) # then - self.assertEquals(actual_revision, stub_rev) + self.assertEqual(actual_revision, stub_rev) mock_lookup.assert_called_once_with( 2, 'master2', 'some-ts') @patch('swh.web.common.service.lookup_revision_with_context') def test_lookup_revision_through_with_context(self, mock_lookup): # given stub_rev = {'id': 'rev'} mock_lookup.return_value = stub_rev # when actual_revision = service.lookup_revision_through({ 'sha1_git_root': 'some-sha1-root', 'sha1_git': 'some-sha1', }) # then - self.assertEquals(actual_revision, stub_rev) + self.assertEqual(actual_revision, stub_rev) mock_lookup.assert_called_once_with( 'some-sha1-root', 'some-sha1', 100) @patch('swh.web.common.service.lookup_revision') def test_lookup_revision_through_with_revision(self, mock_lookup): # given stub_rev = {'id': 'rev'} mock_lookup.return_value = stub_rev # when actual_revision = service.lookup_revision_through({ 'sha1_git': 'some-sha1', }) # then - self.assertEquals(actual_revision, stub_rev) + self.assertEqual(actual_revision, stub_rev) mock_lookup.assert_called_once_with( 'some-sha1') @patch('swh.web.common.service.lookup_revision_through') def test_lookup_directory_through_revision_ko_not_found( self, mock_lookup_rev): # given mock_lookup_rev.return_value = None # when with self.assertRaises(NotFoundExc): service.lookup_directory_through_revision( {'id': 'rev'}, 'some/path', 100) mock_lookup_rev.assert_called_once_with({'id': 'rev'}, 100) @patch('swh.web.common.service.lookup_revision_through') @patch('swh.web.common.service.lookup_directory_with_revision') def test_lookup_directory_through_revision_ok_with_data( self, mock_lookup_dir, mock_lookup_rev): # given mock_lookup_rev.return_value = {'id': 'rev-id'} mock_lookup_dir.return_value = {'type': 'dir', 'content': []} # when rev_id, dir_result = service.lookup_directory_through_revision( {'id': 'rev'}, 'some/path', 100) # then - self.assertEquals(rev_id, 'rev-id') - self.assertEquals(dir_result, {'type': 'dir', - 'content': []}) + self.assertEqual(rev_id, 'rev-id') + self.assertEqual(dir_result, {'type': 'dir', + 'content': []}) mock_lookup_rev.assert_called_once_with({'id': 'rev'}, 100) mock_lookup_dir.assert_called_once_with('rev-id', 'some/path', False) @patch('swh.web.common.service.lookup_revision_through') @patch('swh.web.common.service.lookup_directory_with_revision') def test_lookup_directory_through_revision_ok_with_content( self, mock_lookup_dir, mock_lookup_rev): # given mock_lookup_rev.return_value = {'id': 'rev-id'} stub_result = {'type': 'file', 'revision': 'rev-id', 'content': {'data': b'blah', 'sha1': 'sha1'}} mock_lookup_dir.return_value = stub_result # when rev_id, dir_result = service.lookup_directory_through_revision( {'id': 'rev'}, 'some/path', 10, with_data=True) # then - self.assertEquals(rev_id, 'rev-id') - self.assertEquals(dir_result, stub_result) + self.assertEqual(rev_id, 'rev-id') + self.assertEqual(dir_result, stub_result) mock_lookup_rev.assert_called_once_with({'id': 'rev'}, 10) mock_lookup_dir.assert_called_once_with('rev-id', 'some/path', True) diff --git a/swh/web/tests/common/test_templatetags.py b/swh/web/tests/common/test_templatetags.py index 29daaf55f..6b77d5ffd 100644 --- a/swh/web/tests/common/test_templatetags.py +++ b/swh/web/tests/common/test_templatetags.py @@ -1,60 +1,63 @@ # Copyright (C) 2015-2018 The Software Heritage developers # See the AUTHORS file at the top-level directory of this distribution # License: GNU Affero General Public License version 3, or any later version # See top-level LICENSE file for more information +import pytest from swh.web.common import swh_templatetags from swh.web.tests.testcase import SWHWebTestCase class SWHTemplateTagsTest(SWHWebTestCase): def test_urlize_api_links_api(self): # update api link with html links content with links content = '{"url": "/api/1/abc/"}' expected_content = ('{"url": "/api/1/abc/"}') - self.assertEquals(swh_templatetags.urlize_links_and_mails(content), - expected_content) + self.assertEqual(swh_templatetags.urlize_links_and_mails(content), + expected_content) def test_urlize_api_links_browse(self): # update /browse link with html links content with links content = '{"url": "/browse/def/"}' expected_content = ('{"url": "' '/browse/def/"}') - self.assertEquals(swh_templatetags.urlize_links_and_mails(content), - expected_content) + self.assertEqual(swh_templatetags.urlize_links_and_mails(content), + expected_content) def test_urlize_header_links(self): # update api link with html links content with links content = """; rel="next" ; rel="prev" """ expected_content = """</api/1/abc/>; rel="next" </api/1/def/>; rel="prev" """ - self.assertEquals(swh_templatetags.urlize_header_links(content), - expected_content) + self.assertEqual(swh_templatetags.urlize_header_links(content), + expected_content) + # remove deprecation warnings related to docutils + @pytest.mark.filterwarnings('ignore:.*U.*mode is deprecated:DeprecationWarning') # noqa def test_safe_docstring_display(self): # update api link with html links content with links docstring = """This is my list header: - Here is item 1, with a continuation line right here - Here is item 2 Here is something that is not part of the list""" expected_docstring = """

    This is my list header:

    • Here is item 1, with a continuation line right here
    • Here is item 2

    Here is something that is not part of the list

    """ - self.assertEquals(swh_templatetags.safe_docstring_display(docstring), - expected_docstring) + self.assertEqual(swh_templatetags.safe_docstring_display(docstring), + expected_docstring) diff --git a/swh/web/tests/common/test_utils.py b/swh/web/tests/common/test_utils.py index 78c653789..ecb480eea 100644 --- a/swh/web/tests/common/test_utils.py +++ b/swh/web/tests/common/test_utils.py @@ -1,150 +1,150 @@ # Copyright (C) 2017-2018 The Software Heritage developers # See the AUTHORS file at the top-level directory of this distribution # License: GNU Affero General Public License version 3, or any later version # See top-level LICENSE file for more information import datetime from unittest.mock import patch from swh.web.common import utils from swh.web.common.exc import BadInputExc from swh.web.tests.testcase import SWHWebTestCase class UtilsTestCase(SWHWebTestCase): def test_shorten_path_noop(self): noops = [ '/api/', '/browse/', '/content/symbol/foobar/' ] for noop in noops: self.assertEqual( utils.shorten_path(noop), noop ) def test_shorten_path_sha1(self): sha1 = 'aafb16d69fd30ff58afdd69036a26047f3aebdc6' short_sha1 = sha1[:8] + '...' templates = [ '/api/1/content/sha1:%s/', '/api/1/content/sha1_git:%s/', '/api/1/directory/%s/', '/api/1/content/sha1:%s/ctags/', ] for template in templates: self.assertEqual( utils.shorten_path(template % sha1), template % short_sha1 ) def test_shorten_path_sha256(self): sha256 = ('aafb16d69fd30ff58afdd69036a26047' '213add102934013a014dfca031c41aef') short_sha256 = sha256[:8] + '...' templates = [ '/api/1/content/sha256:%s/', '/api/1/directory/%s/', '/api/1/content/sha256:%s/filetype/', ] for template in templates: self.assertEqual( utils.shorten_path(template % sha256), template % short_sha256 ) def test_parse_timestamp(self): input_timestamps = [ None, '2016-01-12', '2016-01-12T09:19:12+0100', 'Today is January 1, 2047 at 8:21:00AM', '1452591542', ] output_dates = [ None, datetime.datetime(2016, 1, 12, 0, 0), datetime.datetime(2016, 1, 12, 8, 19, 12, tzinfo=datetime.timezone.utc), datetime.datetime(2047, 1, 1, 8, 21), datetime.datetime(2016, 1, 12, 9, 39, 2, tzinfo=datetime.timezone.utc), ] for ts, exp_date in zip(input_timestamps, output_dates): - self.assertEquals(utils.parse_timestamp(ts), exp_date) + self.assertEqual(utils.parse_timestamp(ts), exp_date) def test_format_utc_iso_date(self): self.assertEqual(utils.format_utc_iso_date('2017-05-04T13:27:13+02:00'), # noqa '04 May 2017, 11:27 UTC') def test_gen_path_info(self): input_path = '/home/user/swh-environment/swh-web/' expected_result = [ {'name': 'home', 'path': 'home'}, {'name': 'user', 'path': 'home/user'}, {'name': 'swh-environment', 'path': 'home/user/swh-environment'}, {'name': 'swh-web', 'path': 'home/user/swh-environment/swh-web'} ] path_info = utils.gen_path_info(input_path) - self.assertEquals(path_info, expected_result) + self.assertEqual(path_info, expected_result) input_path = 'home/user/swh-environment/swh-web' path_info = utils.gen_path_info(input_path) - self.assertEquals(path_info, expected_result) + self.assertEqual(path_info, expected_result) @patch('swh.web.common.utils.service') def test_get_origin_visits(self, mock_service): mock_service.MAX_LIMIT = 2 def _lookup_origin_visits(*args, **kwargs): if kwargs['last_visit'] is None: return [{'visit': 1, 'date': '2017-05-06T00:59:10+00:00', 'metadata': {}}, {'visit': 2, 'date': '2017-08-06T00:59:10+00:00', 'metadata': {}} ] else: return [{'visit': 3, 'date': '2017-09-06T00:59:10+00:00', 'metadata': {}} ] mock_service.lookup_origin_visits.side_effect = _lookup_origin_visits origin_info = { 'id': 1, 'type': 'git', 'url': 'https://github.com/foo/bar', } origin_visits = utils.get_origin_visits(origin_info) self.assertEqual(len(origin_visits), 3) def test_get_swh_persisent_id(self): swh_object_type = 'content' sha1_git = 'aafb16d69fd30ff58afdd69036a26047f3aebdc6' expected_swh_id = 'swh:1:cnt:' + sha1_git self.assertEqual(utils.get_swh_persistent_id(swh_object_type, sha1_git), # noqa expected_swh_id) with self.assertRaises(BadInputExc) as cm: utils.get_swh_persistent_id('foo', sha1_git) self.assertIn('Invalid object', cm.exception.args[0]) with self.assertRaises(BadInputExc) as cm: utils.get_swh_persistent_id(swh_object_type, 'not a valid id') self.assertIn('Invalid object', cm.exception.args[0])