Use pytest (bug 1090184)
This commit is contained in:
Родитель
c70fd33560
Коммит
7c9c856873
|
@ -46,3 +46,6 @@ media/marketplace-stats
|
|||
*.po~
|
||||
site-static/*
|
||||
user-media/*
|
||||
.tox/
|
||||
.cache/
|
||||
MANIFEST
|
||||
|
|
14
.travis.yml
14
.travis.yml
|
@ -1,7 +1,12 @@
|
|||
language: python
|
||||
python:
|
||||
- "2.6"
|
||||
- "2.7"
|
||||
env:
|
||||
- TOX_ENV=flake8
|
||||
- TOX_ENV=docs
|
||||
- TOX_ENV=es
|
||||
- TOX_ENV=addons-devhub-editors
|
||||
- TOX_ENV=main
|
||||
services:
|
||||
- memcached
|
||||
before_install:
|
||||
|
@ -9,14 +14,11 @@ before_install:
|
|||
- wget https://download.elasticsearch.org/elasticsearch/elasticsearch/elasticsearch-1.3.2.deb && sudo dpkg -i elasticsearch-1.3.2.deb
|
||||
- sudo /usr/share/elasticsearch/bin/elasticsearch -d -D es.path.data=/tmp -D es.gateway.type=none -D es.index.store.type=memory -D es.discovery.zen.ping.multicast.enabled=false
|
||||
install:
|
||||
- make update_deps
|
||||
- npm install
|
||||
- pip install tox
|
||||
before_script:
|
||||
- mysql -e 'create database olympia;'
|
||||
- make update_assets
|
||||
script:
|
||||
- DJANGO_SETTINGS_MODULE=settings_ci make flake8 && DJANGO_SETTINGS_MODULE=settings_ci make test
|
||||
- make docs SPHINXOPTS='-nW'
|
||||
- tox -v -e $TOX_ENV --recreate
|
||||
notifications:
|
||||
irc:
|
||||
channels:
|
||||
|
|
16
Makefile
16
Makefile
|
@ -1,4 +1,4 @@
|
|||
.PHONY: help docs test test_force_db tdd test_failed initialize_db populate_data update_code update_deps update_db update_assets full_init full_update reindex flake8
|
||||
.PHONY: help docs test test_es test_no_es test_force_db tdd test_failed initialize_db populate_data update_code update_deps update_db update_assets full_init full_update reindex flake8
|
||||
NUM_ADDONS=10
|
||||
NUM_THEMES=$(NUM_ADDONS)
|
||||
|
||||
|
@ -26,16 +26,22 @@ docs:
|
|||
$(MAKE) -C docs html
|
||||
|
||||
test:
|
||||
REUSE_DB=1 python manage.py test --with-blockage --noinput --logging-clear-handlers --with-id -v 2 $(ARGS)
|
||||
py.test $(ARGS)
|
||||
|
||||
test_es:
|
||||
py.test -m es_tests $(ARGS)
|
||||
|
||||
test_no_es:
|
||||
py.test -m "not es_tests" $(ARGS)
|
||||
|
||||
test_force_db:
|
||||
python manage.py test --with-blockage --noinput --logging-clear-handlers --with-id -v 2 $(ARGS)
|
||||
py.test --create-db $(ARGS)
|
||||
|
||||
tdd:
|
||||
REUSE_DB=1 python manage.py test --with-blockage --noinput --failfast --pdb --with-id -v 2 $(ARGS)
|
||||
py.test -x --pdb $(ARGS)
|
||||
|
||||
test_failed:
|
||||
REUSE_DB=1 python manage.py test --with-blockage --noinput --logging-clear-handlers --with-id -v 2 --failed $(ARGS)
|
||||
py.test --lf $(ARGS)
|
||||
|
||||
initialize_db:
|
||||
python manage.py reset_db
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
from django.http import HttpRequest
|
||||
|
||||
import mock
|
||||
import pytest
|
||||
from nose.tools import assert_false
|
||||
|
||||
import amo
|
||||
|
@ -14,6 +15,9 @@ from .acl import (action_allowed, check_addon_ownership, check_ownership,
|
|||
match_rules)
|
||||
|
||||
|
||||
pytestmark = pytest.mark.django_db
|
||||
|
||||
|
||||
def test_match_rules():
|
||||
"""
|
||||
Unit tests for the match_rules method.
|
||||
|
|
|
@ -0,0 +1,858 @@
|
|||
[
|
||||
{
|
||||
"pk": 1,
|
||||
"model": "addons.addon",
|
||||
"fields": {
|
||||
"dev_agreement": false,
|
||||
"eula": null,
|
||||
"last_updated": "2011-07-06T13:29:18",
|
||||
"view_source": true,
|
||||
"enable_thankyou": false,
|
||||
"total_downloads": 0,
|
||||
"premium_type": 0,
|
||||
"developer_comments": null,
|
||||
"_current_version": 1,
|
||||
"average_daily_downloads": 0,
|
||||
"manifest_url": null,
|
||||
"admin_review_type": 1,
|
||||
"the_future": null,
|
||||
"trusted": false,
|
||||
"total_contributions": null,
|
||||
"locale_disambiguation": null,
|
||||
"target_locale": null,
|
||||
"guid": null,
|
||||
"weekly_downloads": 1709,
|
||||
"support_url": null,
|
||||
"disabled_by_user": true,
|
||||
"paypal_id": "",
|
||||
"average_rating": 0.0,
|
||||
"wants_contributions": false,
|
||||
"average_daily_users": 758,
|
||||
"bayesian_rating": 1.28657399683251,
|
||||
"share_count": 0,
|
||||
"ts_slowness": null,
|
||||
"homepage": null,
|
||||
"support_email": null,
|
||||
"public_stats": false,
|
||||
"status": 4,
|
||||
"app_domain": null,
|
||||
"privacy_policy": null,
|
||||
"is_packaged": false,
|
||||
"description": null,
|
||||
"default_locale": "en-US",
|
||||
"whiteboard": "",
|
||||
"enable_new_regions": false,
|
||||
"suggested_amount": null,
|
||||
"prerelease": false,
|
||||
"thankyou_note": null,
|
||||
"admin_review": false,
|
||||
"auto_repackage": true,
|
||||
"slug": "user-disabled",
|
||||
"external_software": false,
|
||||
"highest_status": 0,
|
||||
"_latest_version": 1,
|
||||
"mozilla_contact": "",
|
||||
"_backup_version": null,
|
||||
"name": 134567801,
|
||||
"created": "2014-12-08T06:39:45",
|
||||
"type": 1,
|
||||
"vip_app": false,
|
||||
"icon_type": "",
|
||||
"annoying": 0,
|
||||
"modified": "2014-12-08T06:39:45",
|
||||
"summary": null,
|
||||
"nomination_message": null,
|
||||
"site_specific": false,
|
||||
"charity": null,
|
||||
"make_public": null,
|
||||
"total_reviews": 0,
|
||||
"the_reason": null,
|
||||
"hotness": 0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"pk": 2,
|
||||
"model": "addons.addon",
|
||||
"fields": {
|
||||
"dev_agreement": false,
|
||||
"eula": null,
|
||||
"last_updated": "2011-04-28T07:38:27",
|
||||
"view_source": true,
|
||||
"enable_thankyou": false,
|
||||
"total_downloads": 0,
|
||||
"premium_type": 0,
|
||||
"developer_comments": null,
|
||||
"_current_version": 2,
|
||||
"average_daily_downloads": 0,
|
||||
"manifest_url": null,
|
||||
"admin_review_type": 1,
|
||||
"the_future": null,
|
||||
"trusted": false,
|
||||
"total_contributions": null,
|
||||
"locale_disambiguation": null,
|
||||
"target_locale": null,
|
||||
"guid": null,
|
||||
"weekly_downloads": 1028,
|
||||
"support_url": null,
|
||||
"disabled_by_user": false,
|
||||
"paypal_id": "",
|
||||
"average_rating": 0.0,
|
||||
"wants_contributions": false,
|
||||
"average_daily_users": 1957,
|
||||
"bayesian_rating": 4.62977323542687,
|
||||
"share_count": 0,
|
||||
"ts_slowness": null,
|
||||
"homepage": null,
|
||||
"support_email": null,
|
||||
"public_stats": false,
|
||||
"status": 5,
|
||||
"app_domain": null,
|
||||
"privacy_policy": null,
|
||||
"is_packaged": false,
|
||||
"description": null,
|
||||
"default_locale": "en-US",
|
||||
"whiteboard": "",
|
||||
"enable_new_regions": false,
|
||||
"suggested_amount": null,
|
||||
"prerelease": false,
|
||||
"thankyou_note": null,
|
||||
"admin_review": false,
|
||||
"auto_repackage": true,
|
||||
"slug": "admin-disabled",
|
||||
"external_software": false,
|
||||
"highest_status": 0,
|
||||
"_latest_version": 2,
|
||||
"mozilla_contact": "",
|
||||
"_backup_version": null,
|
||||
"name": 134567802,
|
||||
"created": "2014-12-08T06:40:07",
|
||||
"type": 1,
|
||||
"vip_app": false,
|
||||
"icon_type": "",
|
||||
"annoying": 0,
|
||||
"modified": "2014-12-08T06:40:07",
|
||||
"summary": null,
|
||||
"nomination_message": null,
|
||||
"site_specific": false,
|
||||
"charity": null,
|
||||
"make_public": null,
|
||||
"total_reviews": 0,
|
||||
"the_reason": null,
|
||||
"hotness": 0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"pk": 3,
|
||||
"model": "addons.addon",
|
||||
"fields": {
|
||||
"dev_agreement": false,
|
||||
"eula": null,
|
||||
"last_updated": "2011-02-15T11:33:40",
|
||||
"view_source": true,
|
||||
"enable_thankyou": false,
|
||||
"total_downloads": 0,
|
||||
"premium_type": 0,
|
||||
"developer_comments": null,
|
||||
"_current_version": 3,
|
||||
"average_daily_downloads": 0,
|
||||
"manifest_url": null,
|
||||
"admin_review_type": 1,
|
||||
"the_future": null,
|
||||
"trusted": false,
|
||||
"total_contributions": null,
|
||||
"locale_disambiguation": null,
|
||||
"target_locale": null,
|
||||
"guid": null,
|
||||
"weekly_downloads": 1046,
|
||||
"support_url": null,
|
||||
"disabled_by_user": false,
|
||||
"paypal_id": "",
|
||||
"average_rating": 0.0,
|
||||
"wants_contributions": false,
|
||||
"average_daily_users": 207,
|
||||
"bayesian_rating": 4.53931552224925,
|
||||
"share_count": 0,
|
||||
"ts_slowness": null,
|
||||
"homepage": null,
|
||||
"support_email": null,
|
||||
"public_stats": false,
|
||||
"status": 1,
|
||||
"app_domain": null,
|
||||
"privacy_policy": null,
|
||||
"is_packaged": false,
|
||||
"description": null,
|
||||
"default_locale": "en-US",
|
||||
"whiteboard": "",
|
||||
"enable_new_regions": false,
|
||||
"suggested_amount": null,
|
||||
"prerelease": false,
|
||||
"thankyou_note": null,
|
||||
"admin_review": false,
|
||||
"auto_repackage": true,
|
||||
"slug": "addon-7f0dc590528d4800a4afca6f",
|
||||
"external_software": false,
|
||||
"highest_status": 0,
|
||||
"_latest_version": 3,
|
||||
"mozilla_contact": "",
|
||||
"_backup_version": null,
|
||||
"name": 134567803,
|
||||
"created": "2014-12-08T06:40:16",
|
||||
"type": 1,
|
||||
"vip_app": false,
|
||||
"icon_type": "",
|
||||
"annoying": 0,
|
||||
"modified": "2014-12-08T06:40:16",
|
||||
"summary": null,
|
||||
"nomination_message": null,
|
||||
"site_specific": false,
|
||||
"charity": null,
|
||||
"make_public": null,
|
||||
"total_reviews": 0,
|
||||
"the_reason": null,
|
||||
"hotness": 0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"pk": 4,
|
||||
"model": "addons.addon",
|
||||
"fields": {
|
||||
"dev_agreement": false,
|
||||
"eula": null,
|
||||
"last_updated": "2011-05-22T11:06:50",
|
||||
"view_source": true,
|
||||
"enable_thankyou": false,
|
||||
"total_downloads": 0,
|
||||
"premium_type": 0,
|
||||
"developer_comments": null,
|
||||
"_current_version": 4,
|
||||
"average_daily_downloads": 0,
|
||||
"manifest_url": null,
|
||||
"admin_review_type": 1,
|
||||
"the_future": null,
|
||||
"trusted": false,
|
||||
"total_contributions": null,
|
||||
"locale_disambiguation": null,
|
||||
"target_locale": null,
|
||||
"guid": null,
|
||||
"weekly_downloads": 1967,
|
||||
"support_url": null,
|
||||
"disabled_by_user": false,
|
||||
"paypal_id": "",
|
||||
"average_rating": 0.0,
|
||||
"wants_contributions": false,
|
||||
"average_daily_users": 1756,
|
||||
"bayesian_rating": 3.48031119110043,
|
||||
"share_count": 0,
|
||||
"ts_slowness": null,
|
||||
"homepage": null,
|
||||
"support_email": null,
|
||||
"public_stats": false,
|
||||
"status": 4,
|
||||
"app_domain": null,
|
||||
"privacy_policy": null,
|
||||
"is_packaged": false,
|
||||
"description": null,
|
||||
"default_locale": "en-US",
|
||||
"whiteboard": "",
|
||||
"enable_new_regions": false,
|
||||
"suggested_amount": null,
|
||||
"prerelease": false,
|
||||
"thankyou_note": null,
|
||||
"admin_review": false,
|
||||
"auto_repackage": true,
|
||||
"slug": "addon-8ca80804df0e40c090bc7633",
|
||||
"external_software": false,
|
||||
"highest_status": 0,
|
||||
"_latest_version": 4,
|
||||
"mozilla_contact": "",
|
||||
"_backup_version": null,
|
||||
"name": 134567804,
|
||||
"created": "2014-12-08T06:40:23",
|
||||
"type": 1,
|
||||
"vip_app": false,
|
||||
"icon_type": "",
|
||||
"annoying": 0,
|
||||
"modified": "2014-12-08T06:40:23",
|
||||
"summary": null,
|
||||
"nomination_message": null,
|
||||
"site_specific": false,
|
||||
"charity": null,
|
||||
"make_public": null,
|
||||
"total_reviews": 0,
|
||||
"the_reason": null,
|
||||
"hotness": 0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"pk": 5,
|
||||
"model": "addons.addon",
|
||||
"fields": {
|
||||
"dev_agreement": false,
|
||||
"eula": null,
|
||||
"last_updated": "2011-11-25T07:59:20",
|
||||
"view_source": true,
|
||||
"enable_thankyou": false,
|
||||
"total_downloads": 0,
|
||||
"premium_type": 0,
|
||||
"developer_comments": null,
|
||||
"_current_version": 5,
|
||||
"average_daily_downloads": 0,
|
||||
"manifest_url": null,
|
||||
"admin_review_type": 1,
|
||||
"the_future": null,
|
||||
"trusted": false,
|
||||
"total_contributions": null,
|
||||
"locale_disambiguation": null,
|
||||
"target_locale": null,
|
||||
"guid": null,
|
||||
"weekly_downloads": 476,
|
||||
"support_url": null,
|
||||
"disabled_by_user": false,
|
||||
"paypal_id": "",
|
||||
"average_rating": 0.0,
|
||||
"wants_contributions": false,
|
||||
"average_daily_users": 1282,
|
||||
"bayesian_rating": 1.0053223682018,
|
||||
"share_count": 0,
|
||||
"ts_slowness": null,
|
||||
"homepage": null,
|
||||
"support_email": null,
|
||||
"public_stats": false,
|
||||
"status": 4,
|
||||
"app_domain": null,
|
||||
"privacy_policy": null,
|
||||
"is_packaged": false,
|
||||
"description": null,
|
||||
"default_locale": "en-US",
|
||||
"whiteboard": "",
|
||||
"enable_new_regions": false,
|
||||
"suggested_amount": null,
|
||||
"prerelease": false,
|
||||
"thankyou_note": null,
|
||||
"admin_review": false,
|
||||
"auto_repackage": true,
|
||||
"slug": "addon-669081224b354292a051bbb2",
|
||||
"external_software": false,
|
||||
"highest_status": 0,
|
||||
"_latest_version": 5,
|
||||
"mozilla_contact": "",
|
||||
"_backup_version": null,
|
||||
"name": 134567805,
|
||||
"created": "2014-12-08T06:40:24",
|
||||
"type": 1,
|
||||
"vip_app": false,
|
||||
"icon_type": "",
|
||||
"annoying": 0,
|
||||
"modified": "2014-12-08T06:40:24",
|
||||
"summary": null,
|
||||
"nomination_message": null,
|
||||
"site_specific": false,
|
||||
"charity": null,
|
||||
"make_public": null,
|
||||
"total_reviews": 0,
|
||||
"the_reason": null,
|
||||
"hotness": 0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"pk": 6,
|
||||
"model": "addons.addon",
|
||||
"fields": {
|
||||
"dev_agreement": false,
|
||||
"eula": null,
|
||||
"last_updated": "2011-10-13T15:26:57",
|
||||
"view_source": true,
|
||||
"enable_thankyou": false,
|
||||
"total_downloads": 0,
|
||||
"premium_type": 0,
|
||||
"developer_comments": null,
|
||||
"_current_version": 6,
|
||||
"average_daily_downloads": 0,
|
||||
"manifest_url": null,
|
||||
"admin_review_type": 1,
|
||||
"the_future": null,
|
||||
"trusted": false,
|
||||
"total_contributions": null,
|
||||
"locale_disambiguation": null,
|
||||
"target_locale": null,
|
||||
"guid": null,
|
||||
"weekly_downloads": 1017,
|
||||
"support_url": null,
|
||||
"disabled_by_user": false,
|
||||
"paypal_id": "",
|
||||
"average_rating": 0.0,
|
||||
"wants_contributions": false,
|
||||
"average_daily_users": 1768,
|
||||
"bayesian_rating": 4.08202535488486,
|
||||
"share_count": 0,
|
||||
"ts_slowness": null,
|
||||
"homepage": null,
|
||||
"support_email": null,
|
||||
"public_stats": false,
|
||||
"status": 4,
|
||||
"app_domain": null,
|
||||
"privacy_policy": null,
|
||||
"is_packaged": false,
|
||||
"description": null,
|
||||
"default_locale": "en-US",
|
||||
"whiteboard": "",
|
||||
"enable_new_regions": false,
|
||||
"suggested_amount": null,
|
||||
"prerelease": false,
|
||||
"thankyou_note": null,
|
||||
"admin_review": false,
|
||||
"auto_repackage": true,
|
||||
"slug": "addon-bda0117f6cca49e0bc9321a0",
|
||||
"external_software": false,
|
||||
"highest_status": 0,
|
||||
"_latest_version": 6,
|
||||
"mozilla_contact": "",
|
||||
"_backup_version": null,
|
||||
"name": 134567806,
|
||||
"created": "2014-12-08T06:40:25",
|
||||
"type": 1,
|
||||
"vip_app": false,
|
||||
"icon_type": "",
|
||||
"annoying": 0,
|
||||
"modified": "2014-12-08T06:40:25",
|
||||
"summary": null,
|
||||
"nomination_message": null,
|
||||
"site_specific": false,
|
||||
"charity": null,
|
||||
"make_public": null,
|
||||
"total_reviews": 0,
|
||||
"the_reason": null,
|
||||
"hotness": 0.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"pk": 1,
|
||||
"model": "versions.version",
|
||||
"fields": {
|
||||
"_developer_name": "",
|
||||
"has_info_request": false,
|
||||
"license": null,
|
||||
"created": "2014-12-08T06:39:45",
|
||||
"has_editor_comment": false,
|
||||
"releasenotes": null,
|
||||
"source": "",
|
||||
"approvalnotes": "",
|
||||
"supported_locales": "",
|
||||
"modified": "2014-12-08T06:39:45",
|
||||
"deleted": false,
|
||||
"version": "0.4",
|
||||
"version_int": 40000200100,
|
||||
"reviewed": null,
|
||||
"nomination": "2014-12-08T06:39:45",
|
||||
"addon": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"pk": 2,
|
||||
"model": "versions.version",
|
||||
"fields": {
|
||||
"_developer_name": "",
|
||||
"has_info_request": false,
|
||||
"license": null,
|
||||
"created": "2014-12-08T06:40:07",
|
||||
"has_editor_comment": false,
|
||||
"releasenotes": null,
|
||||
"source": "",
|
||||
"approvalnotes": "",
|
||||
"supported_locales": "",
|
||||
"modified": "2014-12-08T06:40:07",
|
||||
"deleted": false,
|
||||
"version": "1.2",
|
||||
"version_int": 1020000200100,
|
||||
"reviewed": null,
|
||||
"nomination": null,
|
||||
"addon": 2
|
||||
}
|
||||
},
|
||||
{
|
||||
"pk": 3,
|
||||
"model": "versions.version",
|
||||
"fields": {
|
||||
"_developer_name": "",
|
||||
"has_info_request": false,
|
||||
"license": null,
|
||||
"created": "2014-12-08T06:40:16",
|
||||
"has_editor_comment": false,
|
||||
"releasenotes": null,
|
||||
"source": "",
|
||||
"approvalnotes": "",
|
||||
"supported_locales": "",
|
||||
"modified": "2014-12-08T06:40:16",
|
||||
"deleted": false,
|
||||
"version": "1.9",
|
||||
"version_int": 1090000200100,
|
||||
"reviewed": null,
|
||||
"nomination": "2014-12-08T06:40:16",
|
||||
"addon": 3
|
||||
}
|
||||
},
|
||||
{
|
||||
"pk": 4,
|
||||
"model": "versions.version",
|
||||
"fields": {
|
||||
"_developer_name": "",
|
||||
"has_info_request": false,
|
||||
"license": null,
|
||||
"created": "2014-12-08T06:40:23",
|
||||
"has_editor_comment": false,
|
||||
"releasenotes": null,
|
||||
"source": "",
|
||||
"approvalnotes": "",
|
||||
"supported_locales": "",
|
||||
"modified": "2014-12-08T06:40:23",
|
||||
"deleted": false,
|
||||
"version": "1.8",
|
||||
"version_int": 1080000200100,
|
||||
"reviewed": null,
|
||||
"nomination": "2014-12-08T06:40:23",
|
||||
"addon": 4
|
||||
}
|
||||
},
|
||||
{
|
||||
"pk": 5,
|
||||
"model": "versions.version",
|
||||
"fields": {
|
||||
"_developer_name": "",
|
||||
"has_info_request": false,
|
||||
"license": null,
|
||||
"created": "2014-12-08T06:40:24",
|
||||
"has_editor_comment": false,
|
||||
"releasenotes": null,
|
||||
"source": "",
|
||||
"approvalnotes": "",
|
||||
"supported_locales": "",
|
||||
"modified": "2014-12-08T06:40:24",
|
||||
"deleted": false,
|
||||
"version": "1.1",
|
||||
"version_int": 1010000200100,
|
||||
"reviewed": null,
|
||||
"nomination": "2014-12-08T06:40:25",
|
||||
"addon": 5
|
||||
}
|
||||
},
|
||||
{
|
||||
"pk": 6,
|
||||
"model": "versions.version",
|
||||
"fields": {
|
||||
"_developer_name": "",
|
||||
"has_info_request": false,
|
||||
"license": null,
|
||||
"created": "2014-12-08T06:40:25",
|
||||
"has_editor_comment": false,
|
||||
"releasenotes": null,
|
||||
"source": "",
|
||||
"approvalnotes": "",
|
||||
"supported_locales": "",
|
||||
"modified": "2014-12-08T06:40:25",
|
||||
"deleted": false,
|
||||
"version": "0.3",
|
||||
"version_int": 30000200100,
|
||||
"reviewed": null,
|
||||
"nomination": "2014-12-08T06:40:25",
|
||||
"addon": 6
|
||||
}
|
||||
},
|
||||
{
|
||||
"pk": 1,
|
||||
"model": "versions.applicationsversions",
|
||||
"fields": {
|
||||
"application": 1,
|
||||
"max": 2,
|
||||
"version": 1,
|
||||
"min": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"pk": 2,
|
||||
"model": "versions.applicationsversions",
|
||||
"fields": {
|
||||
"application": 1,
|
||||
"max": 2,
|
||||
"version": 2,
|
||||
"min": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"pk": 3,
|
||||
"model": "versions.applicationsversions",
|
||||
"fields": {
|
||||
"application": 1,
|
||||
"max": 2,
|
||||
"version": 3,
|
||||
"min": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"pk": 4,
|
||||
"model": "versions.applicationsversions",
|
||||
"fields": {
|
||||
"application": 1,
|
||||
"max": 2,
|
||||
"version": 4,
|
||||
"min": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"pk": 5,
|
||||
"model": "versions.applicationsversions",
|
||||
"fields": {
|
||||
"application": 1,
|
||||
"max": 2,
|
||||
"version": 5,
|
||||
"min": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"pk": 6,
|
||||
"model": "versions.applicationsversions",
|
||||
"fields": {
|
||||
"application": 1,
|
||||
"max": 2,
|
||||
"version": 6,
|
||||
"min": 1
|
||||
}
|
||||
},
|
||||
{
|
||||
"pk": 1,
|
||||
"model": "applications.appversion",
|
||||
"fields": {
|
||||
"version_int": 4009900200100,
|
||||
"application": 1,
|
||||
"version": "4.0.99",
|
||||
"modified": "2014-12-08T06:39:45",
|
||||
"created": "2014-12-08T06:39:45"
|
||||
}
|
||||
},
|
||||
{
|
||||
"pk": 2,
|
||||
"model": "applications.appversion",
|
||||
"fields": {
|
||||
"version_int": 5009900200100,
|
||||
"application": 1,
|
||||
"version": "5.0.99",
|
||||
"modified": "2014-12-08T06:39:45",
|
||||
"created": "2014-12-08T06:39:45"
|
||||
}
|
||||
},
|
||||
{
|
||||
"pk": 1,
|
||||
"model": "files.file",
|
||||
"fields": {
|
||||
"status": 4,
|
||||
"codereview": false,
|
||||
"builder_version": null,
|
||||
"hash": "",
|
||||
"binary_components": false,
|
||||
"created": "2014-12-08T06:39:45",
|
||||
"modified": "2014-12-08T06:39:45",
|
||||
"strict_compatibility": false,
|
||||
"filename": "1-1",
|
||||
"binary": false,
|
||||
"platform": 1,
|
||||
"version": 1,
|
||||
"reviewed": null,
|
||||
"jetpack_version": null,
|
||||
"requires_chrome": false,
|
||||
"datestatuschanged": "2014-12-08T06:39:45",
|
||||
"no_restart": false,
|
||||
"size": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"pk": 2,
|
||||
"model": "files.file",
|
||||
"fields": {
|
||||
"status": 4,
|
||||
"codereview": false,
|
||||
"builder_version": null,
|
||||
"hash": "",
|
||||
"binary_components": false,
|
||||
"created": "2014-12-08T06:40:07",
|
||||
"modified": "2014-12-08T06:40:07",
|
||||
"strict_compatibility": false,
|
||||
"filename": "2-2",
|
||||
"binary": false,
|
||||
"platform": 1,
|
||||
"version": 2,
|
||||
"reviewed": null,
|
||||
"jetpack_version": null,
|
||||
"requires_chrome": false,
|
||||
"datestatuschanged": "2014-12-08T06:40:07",
|
||||
"no_restart": false,
|
||||
"size": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"pk": 3,
|
||||
"model": "files.file",
|
||||
"fields": {
|
||||
"status": 4,
|
||||
"codereview": false,
|
||||
"builder_version": null,
|
||||
"hash": "",
|
||||
"binary_components": false,
|
||||
"created": "2014-12-08T06:40:16",
|
||||
"modified": "2014-12-08T06:40:16",
|
||||
"strict_compatibility": false,
|
||||
"filename": "3-3",
|
||||
"binary": false,
|
||||
"platform": 1,
|
||||
"version": 3,
|
||||
"reviewed": null,
|
||||
"jetpack_version": null,
|
||||
"requires_chrome": false,
|
||||
"datestatuschanged": "2014-12-08T06:40:16",
|
||||
"no_restart": false,
|
||||
"size": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"pk": 4,
|
||||
"model": "files.file",
|
||||
"fields": {
|
||||
"status": 4,
|
||||
"codereview": false,
|
||||
"builder_version": null,
|
||||
"hash": "",
|
||||
"binary_components": false,
|
||||
"created": "2014-12-08T06:40:23",
|
||||
"modified": "2014-12-08T06:40:23",
|
||||
"strict_compatibility": false,
|
||||
"filename": "4-4",
|
||||
"binary": false,
|
||||
"platform": 1,
|
||||
"version": 4,
|
||||
"reviewed": null,
|
||||
"jetpack_version": null,
|
||||
"requires_chrome": false,
|
||||
"datestatuschanged": "2014-12-08T06:40:23",
|
||||
"no_restart": false,
|
||||
"size": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"pk": 5,
|
||||
"model": "files.file",
|
||||
"fields": {
|
||||
"status": 4,
|
||||
"codereview": false,
|
||||
"builder_version": null,
|
||||
"hash": "",
|
||||
"binary_components": false,
|
||||
"created": "2014-12-08T06:40:24",
|
||||
"modified": "2014-12-08T06:40:24",
|
||||
"strict_compatibility": false,
|
||||
"filename": "5-5",
|
||||
"binary": false,
|
||||
"platform": 1,
|
||||
"version": 5,
|
||||
"reviewed": null,
|
||||
"jetpack_version": null,
|
||||
"requires_chrome": false,
|
||||
"datestatuschanged": "2014-12-08T06:40:24",
|
||||
"no_restart": false,
|
||||
"size": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"pk": 6,
|
||||
"model": "files.file",
|
||||
"fields": {
|
||||
"status": 4,
|
||||
"codereview": false,
|
||||
"builder_version": null,
|
||||
"hash": "",
|
||||
"binary_components": false,
|
||||
"created": "2014-12-08T06:40:25",
|
||||
"modified": "2014-12-08T06:40:25",
|
||||
"strict_compatibility": false,
|
||||
"filename": "6-6",
|
||||
"binary": false,
|
||||
"platform": 1,
|
||||
"version": 6,
|
||||
"reviewed": null,
|
||||
"jetpack_version": null,
|
||||
"requires_chrome": false,
|
||||
"datestatuschanged": "2014-12-08T06:40:25",
|
||||
"no_restart": false,
|
||||
"size": 0
|
||||
}
|
||||
},
|
||||
{
|
||||
"pk": 1,
|
||||
"model": "translations.translation",
|
||||
"fields": {
|
||||
"localized_string_clean": null,
|
||||
"created": "2014-12-08T06:39:45",
|
||||
"locale": "en-us",
|
||||
"modified": "2014-12-08T06:39:45",
|
||||
"id": 134567801,
|
||||
"localized_string": "user-disabled"
|
||||
}
|
||||
},
|
||||
{
|
||||
"pk": 2,
|
||||
"model": "translations.translation",
|
||||
"fields": {
|
||||
"localized_string_clean": null,
|
||||
"created": "2014-12-08T06:40:07",
|
||||
"locale": "en-us",
|
||||
"modified": "2014-12-08T06:40:07",
|
||||
"id": 134567802,
|
||||
"localized_string": "admin-disabled"
|
||||
}
|
||||
},
|
||||
{
|
||||
"pk": 3,
|
||||
"model": "translations.translation",
|
||||
"fields": {
|
||||
"localized_string_clean": null,
|
||||
"created": "2014-12-08T06:40:16",
|
||||
"locale": "en-us",
|
||||
"modified": "2014-12-08T06:40:16",
|
||||
"id": 134567803,
|
||||
"localized_string": "Addon 7f0dc590528d4800a4afca6fff72cbaa"
|
||||
}
|
||||
},
|
||||
{
|
||||
"pk": 4,
|
||||
"model": "translations.translation",
|
||||
"fields": {
|
||||
"localized_string_clean": null,
|
||||
"created": "2014-12-08T06:40:23",
|
||||
"locale": "en-us",
|
||||
"modified": "2014-12-08T06:40:23",
|
||||
"id": 134567804,
|
||||
"localized_string": "Addon 8ca80804df0e40c090bc763324dd4b5a"
|
||||
}
|
||||
},
|
||||
{
|
||||
"pk": 5,
|
||||
"model": "translations.translation",
|
||||
"fields": {
|
||||
"localized_string_clean": null,
|
||||
"created": "2014-12-08T06:40:24",
|
||||
"locale": "en-us",
|
||||
"modified": "2014-12-08T06:40:24",
|
||||
"id": 134567805,
|
||||
"localized_string": "Addon 669081224b354292a051bbb278642d03"
|
||||
}
|
||||
},
|
||||
{
|
||||
"pk": 6,
|
||||
"model": "translations.translation",
|
||||
"fields": {
|
||||
"localized_string_clean": null,
|
||||
"created": "2014-12-08T06:40:25",
|
||||
"locale": "en-us",
|
||||
"modified": "2014-12-08T06:40:25",
|
||||
"id": 134567806,
|
||||
"localized_string": "Addon bda0117f6cca49e0bc9321a02a612699"
|
||||
}
|
||||
}
|
||||
]
|
|
@ -326,7 +326,8 @@ class TestButton(ButtonTest):
|
|||
eq_(b.fix_link('foo.com'), 'foo.com?collection_id=xxx')
|
||||
|
||||
b = self.get_button(collection=collection, src='src')
|
||||
eq_(b.fix_link('foo.com'), 'foo.com?src=src&collection_id=xxx')
|
||||
self.assertUrlEqual(b.fix_link('foo.com'),
|
||||
'foo.com?src=src&collection_id=xxx')
|
||||
|
||||
def test_links(self):
|
||||
self.version.all_files = self.platform_files
|
||||
|
|
|
@ -2170,7 +2170,6 @@ class TestAddonWatchDisabled(amo.tests.TestCase):
|
|||
|
||||
|
||||
class TestSearchSignals(amo.tests.ESTestCase):
|
||||
test_es = True
|
||||
|
||||
def setUp(self):
|
||||
super(TestSearchSignals, self).setUp()
|
||||
|
|
|
@ -4,7 +4,6 @@ Miscellaneous helpers that make Django compatible with AMO.
|
|||
import threading
|
||||
|
||||
import commonware.log
|
||||
from caching.base import CachingQuerySet
|
||||
|
||||
from product_details import product_details
|
||||
|
||||
|
@ -73,6 +72,7 @@ class CachedProperty(object):
|
|||
value = obj.__dict__.get(self.__name__, _missing)
|
||||
if value is _missing:
|
||||
value = self.func(obj)
|
||||
from caching.base import CachingQuerySet
|
||||
if isinstance(value, CachingQuerySet):
|
||||
# Work around a bug in django-cache-machine that
|
||||
# causes deadlock or infinite recursion if
|
||||
|
|
|
@ -8,11 +8,12 @@ import uuid
|
|||
from contextlib import contextmanager
|
||||
from datetime import datetime, timedelta
|
||||
from functools import partial, wraps
|
||||
from urlparse import urlsplit, urlunsplit
|
||||
from urlparse import parse_qs, urlparse, urlsplit, urlunsplit
|
||||
|
||||
from django import forms, http, test
|
||||
from django.conf import settings
|
||||
from django.core.cache import cache
|
||||
from django.core.management import call_command
|
||||
from django.db.models.signals import post_save
|
||||
from django.forms.fields import Field
|
||||
from django.http import SimpleCookie
|
||||
|
@ -21,10 +22,9 @@ from django.utils import translation
|
|||
|
||||
import caching
|
||||
import mock
|
||||
import pytest
|
||||
import tower
|
||||
from dateutil.parser import parse as dateutil_parser
|
||||
from django_nose import FastFixtureTestCase
|
||||
from nose.exc import SkipTest
|
||||
from nose.tools import eq_, nottest
|
||||
from pyquery import PyQuery as pq
|
||||
from redisutils import mock_redis, reset_redis
|
||||
|
@ -39,14 +39,14 @@ import stats.search
|
|||
from access.models import Group, GroupUser
|
||||
from addons.models import (Addon, Persona,
|
||||
update_search_index as addon_update_search_index)
|
||||
from addons.tasks import unindex_addons
|
||||
from amo.urlresolvers import get_url_prefix, Prefixer, reverse, set_url_prefix
|
||||
from addons.tasks import unindex_addons
|
||||
from applications.models import AppVersion
|
||||
from bandwagon.models import Collection
|
||||
from files.models import File
|
||||
from lib.es.signals import process, reset
|
||||
from translations.hold import clean_translations
|
||||
from translations.models import delete_translation, Translation
|
||||
from translations.models import Translation
|
||||
from versions.models import ApplicationsVersions, Version
|
||||
from users.models import RequestUser, UserProfile
|
||||
|
||||
|
@ -143,6 +143,17 @@ def check_selected(expected, links, selected):
|
|||
check_links(expected, links, verify=True, selected=selected)
|
||||
|
||||
|
||||
def assert_url_equal(url, other, compare_host=False):
|
||||
"""Compare url paths and query strings."""
|
||||
parsed = urlparse(url)
|
||||
parsed_other = urlparse(other)
|
||||
eq_(parsed.path, parsed_other.path) # Paths are equal.
|
||||
eq_(parse_qs(parsed.path),
|
||||
parse_qs(parsed_other.path)) # Params are equal.
|
||||
if compare_host:
|
||||
eq_(parsed.netloc, parsed_other.netloc)
|
||||
|
||||
|
||||
class RedisTest(object):
|
||||
"""Mixin for when you need to mock redis for testing."""
|
||||
|
||||
|
@ -259,7 +270,7 @@ def default_prefixer():
|
|||
amo.urlresolvers.set_url_prefix(prefixer)
|
||||
|
||||
|
||||
class BaseTestCase(FastFixtureTestCase):
|
||||
class BaseTestCase(test.TestCase):
|
||||
"""Base test case that each and every test cases should inherit from."""
|
||||
|
||||
def _pre_setup(self):
|
||||
|
@ -324,6 +335,11 @@ class BaseTestCase(FastFixtureTestCase):
|
|||
locale=locale).localized_string,
|
||||
localized_string)
|
||||
|
||||
def assertUrlEqual(self, url, other, compare_host=False,
|
||||
compare_scheme=False):
|
||||
"""Compare url paths and query strings."""
|
||||
assert_url_equal(url, other, compare_host=compare_host)
|
||||
|
||||
|
||||
class TestCase(MockEsMixin, RedisTest, BaseTestCase):
|
||||
"""Base class for all amo tests."""
|
||||
|
@ -559,6 +575,17 @@ class TestCase(MockEsMixin, RedisTest, BaseTestCase):
|
|||
"""
|
||||
return pq(pq(html)(template_selector).html())
|
||||
|
||||
def assertUrlEqual(self, url, other, compare_host=False,
|
||||
compare_scheme=False):
|
||||
"""Compare url paths and query strings."""
|
||||
parsed = urlparse(url)
|
||||
parsed_other = urlparse(other)
|
||||
eq_(parsed.path, parsed_other.path) # Paths are equal.
|
||||
eq_(parse_qs(parsed.path),
|
||||
parse_qs(parsed_other.path)) # Params are equal.
|
||||
if compare_host:
|
||||
eq_(parsed.netloc, parsed_other.netloc)
|
||||
|
||||
|
||||
class AMOPaths(object):
|
||||
"""Mixin for getting common AMO Paths."""
|
||||
|
@ -760,18 +787,16 @@ def version_factory(file_kw={}, **kw):
|
|||
return v
|
||||
|
||||
|
||||
@pytest.mark.es_tests
|
||||
class ESTestCase(TestCase):
|
||||
"""Base class for tests that require elasticsearch."""
|
||||
# ES is slow to set up so this uses class setup/teardown. That happens
|
||||
# outside Django transactions so be careful to clean up afterwards.
|
||||
test_es = True
|
||||
mock_es = False
|
||||
exempt_from_fixture_bundling = True # ES doesn't support bundling (yet?)
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
if not settings.RUN_ES_TESTS:
|
||||
raise SkipTest('ES disabled')
|
||||
cls.es = amo.search.get_es(timeout=settings.ES_TIMEOUT)
|
||||
|
||||
# The ES setting are set before we call super()
|
||||
|
@ -784,9 +809,10 @@ class ESTestCase(TestCase):
|
|||
try:
|
||||
cls.es.cluster.health()
|
||||
except Exception, e:
|
||||
e.args = tuple([u'%s (it looks like ES is not running, '
|
||||
'try starting it or set RUN_ES_TESTS=False)'
|
||||
% e.args[0]] + list(e.args[1:]))
|
||||
e.args = tuple(
|
||||
[u"%s (it looks like ES is not running, try starting it or "
|
||||
u"don't run ES tests: make test_no_es)" % e.args[0]] +
|
||||
list(e.args[1:]))
|
||||
raise
|
||||
|
||||
cls._SEARCH_ANALYZER_MAP = amo.SEARCH_ANALYZER_MAP
|
||||
|
@ -803,28 +829,8 @@ class ESTestCase(TestCase):
|
|||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
try:
|
||||
if hasattr(cls, '_addons'):
|
||||
addons = Addon.objects.filter(
|
||||
pk__in=[a.id for a in cls._addons])
|
||||
# First delete all the translations.
|
||||
for addon in addons:
|
||||
for field in addon._meta.translated_fields:
|
||||
delete_translation(addon, field.name)
|
||||
# Then delete the addons themselves.
|
||||
addons.delete()
|
||||
unindex_addons([a.id for a in cls._addons])
|
||||
amo.SEARCH_ANALYZER_MAP = cls._SEARCH_ANALYZER_MAP
|
||||
finally:
|
||||
# Make sure we're calling super's tearDownClass even if something
|
||||
# went wrong in the code above, as otherwise we'd run into bug
|
||||
# 960598.
|
||||
super(ESTestCase, cls).tearDownClass()
|
||||
|
||||
@classmethod
|
||||
def setUpIndex(cls):
|
||||
cls.add_addons()
|
||||
cls.refresh()
|
||||
amo.SEARCH_ANALYZER_MAP = cls._SEARCH_ANALYZER_MAP
|
||||
super(ESTestCase, cls).tearDownClass()
|
||||
|
||||
@classmethod
|
||||
def send(cls):
|
||||
|
@ -842,17 +848,6 @@ class ESTestCase(TestCase):
|
|||
[o.save() for o in model.objects.all()]
|
||||
cls.refresh(index)
|
||||
|
||||
@classmethod
|
||||
def add_addons(cls):
|
||||
cls._addons = [
|
||||
addon_factory(name='user-disabled', disabled_by_user=True),
|
||||
addon_factory(name='admin-disabled', status=amo.STATUS_DISABLED),
|
||||
addon_factory(status=amo.STATUS_UNREVIEWED),
|
||||
addon_factory(),
|
||||
addon_factory(),
|
||||
addon_factory(),
|
||||
]
|
||||
|
||||
@classmethod
|
||||
def empty_index(cls, index):
|
||||
cls.es.delete_by_query(
|
||||
|
@ -861,6 +856,31 @@ class ESTestCase(TestCase):
|
|||
)
|
||||
|
||||
|
||||
class ESTestCaseWithAddons(ESTestCase):
|
||||
|
||||
@classmethod
|
||||
def setUp(cls):
|
||||
super(ESTestCaseWithAddons, cls).setUpClass()
|
||||
# Load the fixture here, to not be overloaded by a child class'
|
||||
# fixture attribute.
|
||||
call_command('loaddata', 'addons/base_es')
|
||||
addon_ids = [1, 2, 3, 4, 5, 6] # From the addons/base_es fixture.
|
||||
cls._addons = list(Addon.objects.filter(pk__in=addon_ids)
|
||||
.order_by('id'))
|
||||
from addons.tasks import index_addons
|
||||
index_addons(addon_ids)
|
||||
# Refresh ES.
|
||||
cls.refresh()
|
||||
|
||||
@classmethod
|
||||
def tearDown(cls):
|
||||
try:
|
||||
unindex_addons([a.id for a in cls._addons])
|
||||
cls._addons = []
|
||||
finally:
|
||||
super(ESTestCaseWithAddons, cls).tearDownClass()
|
||||
|
||||
|
||||
class TestXss(TestCase):
|
||||
fixtures = ['base/addon_3615', 'users/test_backends', ]
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ from django.utils import translation
|
|||
|
||||
import jingo
|
||||
import mock
|
||||
import pytest
|
||||
from nose.tools import eq_, assert_raises, raises
|
||||
|
||||
from amo.tests import BaseTestCase
|
||||
|
@ -18,6 +19,9 @@ from amo.utils import (cache_ns_key, escape_all, find_language,
|
|||
to_language)
|
||||
from product_details import product_details
|
||||
|
||||
|
||||
pytestmark = pytest.mark.django_db
|
||||
|
||||
u = u'Ελληνικά'
|
||||
|
||||
|
||||
|
@ -100,6 +104,9 @@ def test_find_language():
|
|||
yield check, a, b
|
||||
|
||||
|
||||
@pytest.mark.skipif(
|
||||
not product_details.last_update,
|
||||
reason="We don't want to download product_details on travis")
|
||||
def test_spotcheck():
|
||||
"""Check a couple product-details files to make sure they're available."""
|
||||
languages = product_details.languages
|
||||
|
|
|
@ -5,6 +5,7 @@ from django.conf import settings
|
|||
from django.core.exceptions import PermissionDenied
|
||||
|
||||
import mock
|
||||
import pytest
|
||||
from nose.tools import eq_
|
||||
|
||||
import amo.tests
|
||||
|
@ -14,6 +15,9 @@ from amo.urlresolvers import reverse
|
|||
from users.models import UserProfile
|
||||
|
||||
|
||||
pytestmark = pytest.mark.django_db
|
||||
|
||||
|
||||
def test_post_required():
|
||||
f = lambda r: mock.sentinel.response
|
||||
g = decorators.post_required(f)
|
||||
|
|
|
@ -3,9 +3,13 @@ import mock
|
|||
|
||||
from django.shortcuts import render
|
||||
|
||||
import pytest
|
||||
from nose.tools import eq_
|
||||
|
||||
|
||||
pytestmark = pytest.mark.django_db
|
||||
|
||||
|
||||
@mock.patch('caching.ext.cache._cache_support')
|
||||
def test_app_in_fragment_cache_key(cache_mock):
|
||||
cache_mock.return_value = ''
|
||||
|
|
|
@ -11,6 +11,7 @@ from django.test.utils import override_settings
|
|||
from django.utils import encoding
|
||||
|
||||
import jingo
|
||||
import pytest
|
||||
from mock import Mock, patch
|
||||
from nose.tools import eq_, ok_
|
||||
from pyquery import PyQuery
|
||||
|
@ -22,6 +23,9 @@ from amo.utils import ImageCheck
|
|||
from versions.models import License
|
||||
|
||||
|
||||
pytestmark = pytest.mark.django_db
|
||||
|
||||
|
||||
def render(s, context={}):
|
||||
t = jingo.env.from_string(s)
|
||||
return t.render(context)
|
||||
|
@ -188,7 +192,7 @@ def test_urlparams():
|
|||
|
||||
# Adding query with existing params.
|
||||
s = render('{{ base_query|urlparams(frag, sort=sort) }}', c)
|
||||
eq_(s, '%s?sort=name&x=y#frag' % url)
|
||||
amo.tests.assert_url_equal(s, '%s?sort=name&x=y#frag' % url)
|
||||
|
||||
# Replacing a query param.
|
||||
s = render('{{ base_query|urlparams(frag, x="z") }}', c)
|
||||
|
@ -422,6 +426,7 @@ class TestAnimatedImages(amo.tests.TestCase):
|
|||
|
||||
|
||||
def test_site_nav():
|
||||
amo.tests.default_prefixer()
|
||||
r = Mock()
|
||||
r.APP = amo.FIREFOX
|
||||
assert 'id="site-nav"' in helpers.site_nav({'request': r})
|
||||
|
@ -453,11 +458,19 @@ def test_f():
|
|||
eq_(render(u'{{ "foo {0}"|f("baré") }}'), u'foo baré')
|
||||
|
||||
|
||||
def test_inline_css():
|
||||
def test_inline_css(monkeypatch):
|
||||
jingo.load_helpers()
|
||||
env = jingo.env
|
||||
t = env.from_string("{{ inline_css('zamboni/mobile', debug=True) }}")
|
||||
|
||||
# Monkeypatch settings.LESS_BIN to not call the less compiler. We don't
|
||||
# need nor want it in tests.
|
||||
monkeypatch.setattr(settings, 'LESS_BIN', 'ls')
|
||||
# Monkeypatch jingo_minify.helpers.is_external to counter-effect the
|
||||
# autouse fixture in conftest.py.
|
||||
monkeypatch.setattr(amo.helpers, 'is_external', lambda css: False)
|
||||
s = t.render()
|
||||
|
||||
ok_('background-image: url(/static/img/icons/stars.png);' in s)
|
||||
|
||||
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
from django.utils.translation import trans_real
|
||||
|
||||
import pytest
|
||||
import tower
|
||||
|
||||
|
||||
pytestmark = pytest.mark.django_db
|
||||
|
||||
|
||||
def test_amo_locale_not_in_django():
|
||||
"""
|
||||
We load gettext catalogs in this order:
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
"""Tests for the activitylog."""
|
||||
import json
|
||||
from datetime import datetime
|
||||
|
||||
from nose.tools import eq_
|
||||
|
@ -26,7 +27,7 @@ class LogTest(amo.tests.TestCase):
|
|||
al = amo.log(amo.LOG.DELETE_REVIEW, 1, a, details=magic)
|
||||
|
||||
eq_(al.details, magic)
|
||||
eq_(al._details, '{"body": "way!", "title": "no"}')
|
||||
eq_(al._details, json.dumps(magic))
|
||||
|
||||
def test_created(self):
|
||||
"""
|
||||
|
|
|
@ -3,6 +3,7 @@ import django.contrib.messages as django_messages
|
|||
from django.contrib.messages.storage import default_storage
|
||||
from django.http import HttpRequest
|
||||
|
||||
import pytest
|
||||
from jingo import env
|
||||
from nose.tools import eq_
|
||||
from tower import ugettext as _
|
||||
|
@ -10,6 +11,9 @@ from tower import ugettext as _
|
|||
from amo.messages import _make_message, info
|
||||
|
||||
|
||||
pytestmark = pytest.mark.django_db
|
||||
|
||||
|
||||
def test_xss():
|
||||
|
||||
title = "<script>alert(1)</script>"
|
||||
|
|
|
@ -3,6 +3,7 @@ from django import http, test
|
|||
from django.conf import settings
|
||||
from django.test.client import RequestFactory
|
||||
|
||||
import pytest
|
||||
from commonware.middleware import ScrubRequestOnException
|
||||
from mock import Mock, patch
|
||||
from nose.tools import eq_
|
||||
|
@ -14,6 +15,9 @@ from amo.urlresolvers import reverse
|
|||
from zadmin.models import Config, _config_cache
|
||||
|
||||
|
||||
pytestmark = pytest.mark.django_db
|
||||
|
||||
|
||||
class TestMiddleware(amo.tests.TestCase):
|
||||
|
||||
def test_no_vary_cookie(self):
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
|
||||
import pytest
|
||||
from mock import Mock
|
||||
from nose.tools import eq_
|
||||
|
||||
|
@ -9,6 +9,9 @@ from amo import models as context
|
|||
from addons.models import Addon
|
||||
|
||||
|
||||
pytestmark = pytest.mark.django_db
|
||||
|
||||
|
||||
class ManualOrderTest(TestCase):
|
||||
fixtures = ('base/addon_3615', 'base/addon_5299_gcal', 'base/addon_40')
|
||||
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
import pytest
|
||||
from mock import Mock
|
||||
from nose.tools import eq_
|
||||
|
||||
from amo.helpers import Paginator
|
||||
|
||||
|
||||
pytestmark = pytest.mark.django_db
|
||||
|
||||
|
||||
def mock_pager(page_number, num_pages, count):
|
||||
m = Mock()
|
||||
m.paginator = Mock()
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
from django.core import paginator
|
||||
|
||||
import mock
|
||||
from nose.tools import eq_
|
||||
from nose.tools import eq_, ok_
|
||||
|
||||
import amo
|
||||
import amo.search
|
||||
|
@ -9,19 +9,13 @@ import amo.tests
|
|||
from addons.models import Addon
|
||||
|
||||
|
||||
class TestESIndexing(amo.tests.ESTestCase):
|
||||
mock_es = False
|
||||
test_es = True
|
||||
|
||||
def setUp(self):
|
||||
super(TestESIndexing, self).setUp()
|
||||
self.setUpIndex()
|
||||
self.addCleanup(lambda: self.empty_index('default'))
|
||||
class TestESIndexing(amo.tests.ESTestCaseWithAddons):
|
||||
|
||||
# This needs to be in its own class for data isolation.
|
||||
def test_indexed_count(self):
|
||||
# Did all the right addons get indexed?
|
||||
count = Addon.search().filter(type=1, is_disabled=False).count()
|
||||
eq_(count, 4) # Created in the setUpClass.
|
||||
eq_(count,
|
||||
Addon.objects.filter(disabled_by_user=False,
|
||||
status__in=amo.VALID_STATUSES).count())
|
||||
|
@ -32,7 +26,6 @@ class TestESIndexing(amo.tests.ESTestCase):
|
|||
|
||||
|
||||
class TestNoESIndexing(amo.tests.TestCase):
|
||||
|
||||
mock_es = True
|
||||
|
||||
def test_no_es(self):
|
||||
|
@ -51,13 +44,7 @@ class TestNoESIndexing(amo.tests.TestCase):
|
|||
assert issubclass(es.__class__, mock.Mock)
|
||||
|
||||
|
||||
class TestES(amo.tests.ESTestCase):
|
||||
test_es = True
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(TestES, cls).setUpClass()
|
||||
cls.setUpIndex()
|
||||
class TestES(amo.tests.ESTestCaseWithAddons):
|
||||
|
||||
def test_clone(self):
|
||||
# Doing a filter creates a new ES object.
|
||||
|
@ -78,8 +65,12 @@ class TestES(amo.tests.ESTestCase):
|
|||
|
||||
def test_and(self):
|
||||
qs = Addon.search().filter(type=1, category__in=[1, 2])
|
||||
eq_(qs._build_query()['query']['filtered']['filter'],
|
||||
{'and': [{'term': {'type': 1}}, {'in': {'category': [1, 2]}}]})
|
||||
filters = qs._build_query()['query']['filtered']['filter']
|
||||
# Filters:
|
||||
# {'and': [{'term': {'type': 1}}, {'in': {'category': [1, 2]}}]}
|
||||
eq_(filters.keys(), ['and'])
|
||||
ok_({'term': {'type': 1}} in filters['and'])
|
||||
ok_({'in': {'category': [1, 2]}} in filters['and'])
|
||||
|
||||
def test_query(self):
|
||||
qs = Addon.search().query(type=1)
|
||||
|
@ -93,30 +84,54 @@ class TestES(amo.tests.ESTestCase):
|
|||
|
||||
def test_query_multiple_and_range(self):
|
||||
qs = Addon.search().query(type=1, status__gte=1)
|
||||
eq_(qs._build_query()['query']['function_score']['query'],
|
||||
{'bool': {'must': [{'term': {'type': 1}},
|
||||
{'range': {'status': {'gte': 1}}}, ]}})
|
||||
query = qs._build_query()['query']['function_score']['query']
|
||||
# Query:
|
||||
# {'bool': {'must': [{'term': {'type': 1}},
|
||||
# {'range': {'status': {'gte': 1}}}, ]}}
|
||||
eq_(query.keys(), ['bool'])
|
||||
eq_(query['bool'].keys(), ['must'])
|
||||
ok_({'term': {'type': 1}} in query['bool']['must'])
|
||||
ok_({'range': {'status': {'gte': 1}}} in query['bool']['must'])
|
||||
|
||||
def test_query_or(self):
|
||||
qs = Addon.search().query(or_=dict(type=1, status__gte=2))
|
||||
eq_(qs._build_query()['query']['function_score']['query'],
|
||||
{'bool': {'should': [{'term': {'type': 1}},
|
||||
{'range': {'status': {'gte': 2}}}, ]}})
|
||||
query = qs._build_query()['query']['function_score']['query']
|
||||
# Query:
|
||||
# {'bool': {'should': [{'term': {'type': 1}},
|
||||
# {'range': {'status': {'gte': 2}}}, ]}}
|
||||
eq_(query.keys(), ['bool'])
|
||||
eq_(query['bool'].keys(), ['should'])
|
||||
ok_({'term': {'type': 1}} in query['bool']['should'])
|
||||
ok_({'range': {'status': {'gte': 2}}} in query['bool']['should'])
|
||||
|
||||
def test_query_or_and(self):
|
||||
qs = Addon.search().query(or_=dict(type=1, status__gte=2), category=2)
|
||||
eq_(qs._build_query()['query']['function_score']['query'],
|
||||
{'bool': {'must': [{'term': {'category': 2}},
|
||||
{'bool': {'should': [
|
||||
{'term': {'type': 1}},
|
||||
{'range': {'status': {'gte': 2}}}, ]}}]}})
|
||||
query = qs._build_query()['query']['function_score']['query']
|
||||
# Query:
|
||||
# {'bool': {'must': [{'term': {'category': 2}},
|
||||
# {'bool': {'should': [
|
||||
# {'term': {'type': 1}},
|
||||
# {'range': {'status': {'gte': 2}}}, ]}}]}})
|
||||
eq_(query.keys(), ['bool'])
|
||||
eq_(query['bool'].keys(), ['must'])
|
||||
ok_({'term': {'category': 2}} in query['bool']['must'])
|
||||
sub_clause = sorted(query['bool']['must'])[0]
|
||||
eq_(sub_clause.keys(), ['bool'])
|
||||
eq_(sub_clause['bool'].keys(), ['should'])
|
||||
ok_({'range': {'status': {'gte': 2}}} in sub_clause['bool']['should'])
|
||||
ok_({'term': {'type': 1}} in sub_clause['bool']['should'])
|
||||
|
||||
def test_query_fuzzy(self):
|
||||
fuzz = {'boost': 2, 'value': 'woo'}
|
||||
qs = Addon.search().query(or_=dict(type=1, status__fuzzy=fuzz))
|
||||
eq_(qs._build_query()['query']['function_score']['query'],
|
||||
{'bool': {'should': [{'fuzzy': {'status': fuzz}},
|
||||
{'term': {'type': 1}}, ]}})
|
||||
query = qs._build_query()['query']['function_score']['query']
|
||||
# Query:
|
||||
# {'bool': {'should': [{'fuzzy': {'status': fuzz}},
|
||||
# {'term': {'type': 1}}, ]}})
|
||||
eq_(query.keys(), ['bool'])
|
||||
eq_(query['bool'].keys(), ['should'])
|
||||
ok_({'term': {'type': 1}} in query['bool']['should'])
|
||||
ok_({'fuzzy': {'status': fuzz}} in query['bool']['should'])
|
||||
|
||||
def test_order_by_desc(self):
|
||||
qs = Addon.search().order_by('-rating')
|
||||
|
@ -137,18 +152,32 @@ class TestES(amo.tests.ESTestCase):
|
|||
|
||||
def test_filter_or(self):
|
||||
qs = Addon.search().filter(type=1).filter(or_=dict(status=1, app=2))
|
||||
eq_(qs._build_query()['query']['filtered']['filter'],
|
||||
{'and': [
|
||||
{'term': {'type': 1}},
|
||||
{'or': [{'term': {'status': 1}}, {'term': {'app': 2}}]},
|
||||
]})
|
||||
filters = qs._build_query()['query']['filtered']['filter']
|
||||
# Filters:
|
||||
# {'and': [
|
||||
# {'term': {'type': 1}},
|
||||
# {'or': [{'term': {'status': 1}}, {'term': {'app': 2}}]},
|
||||
# ]}
|
||||
eq_(filters.keys(), ['and'])
|
||||
ok_({'term': {'type': 1}} in filters['and'])
|
||||
or_clause = sorted(filters['and'])[0]
|
||||
eq_(or_clause.keys(), ['or'])
|
||||
ok_({'term': {'status': 1}} in or_clause['or'])
|
||||
ok_({'term': {'app': 2}} in or_clause['or'])
|
||||
|
||||
qs = Addon.search().filter(type=1, or_=dict(status=1, app=2))
|
||||
eq_(qs._build_query()['query']['filtered']['filter'],
|
||||
{'and': [
|
||||
{'term': {'type': 1}},
|
||||
{'or': [{'term': {'status': 1}}, {'term': {'app': 2}}]},
|
||||
]})
|
||||
filters = qs._build_query()['query']['filtered']['filter']
|
||||
# Filters:
|
||||
# {'and': [
|
||||
# {'term': {'type': 1}},
|
||||
# {'or': [{'term': {'status': 1}}, {'term': {'app': 2}}]},
|
||||
# ]}
|
||||
eq_(filters.keys(), ['and'])
|
||||
ok_({'term': {'type': 1}} in filters['and'])
|
||||
or_clause = sorted(filters['and'])[0]
|
||||
eq_(or_clause.keys(), ['or'])
|
||||
ok_({'term': {'status': 1}} in or_clause['or'])
|
||||
ok_({'term': {'app': 2}} in or_clause['or'])
|
||||
|
||||
def test_slice_stop(self):
|
||||
qs = Addon.search()[:6]
|
||||
|
@ -182,35 +211,51 @@ class TestES(amo.tests.ESTestCase):
|
|||
|
||||
def test_gte(self):
|
||||
qs = Addon.search().filter(type__in=[1, 2], status__gte=4)
|
||||
eq_(qs._build_query()['query']['filtered']['filter'],
|
||||
{'and': [
|
||||
{'in': {'type': [1, 2]}},
|
||||
{'range': {'status': {'gte': 4}}},
|
||||
]})
|
||||
filters = qs._build_query()['query']['filtered']['filter']
|
||||
# Filters:
|
||||
# {'and': [
|
||||
# {'in': {'type': [1, 2]}},
|
||||
# {'range': {'status': {'gte': 4}}},
|
||||
# ]}
|
||||
eq_(filters.keys(), ['and'])
|
||||
ok_({'in': {'type': [1, 2]}} in filters['and'])
|
||||
ok_({'range': {'status': {'gte': 4}}} in filters['and'])
|
||||
|
||||
def test_lte(self):
|
||||
qs = Addon.search().filter(type__in=[1, 2], status__lte=4)
|
||||
eq_(qs._build_query()['query']['filtered']['filter'],
|
||||
{'and': [
|
||||
{'in': {'type': [1, 2]}},
|
||||
{'range': {'status': {'lte': 4}}},
|
||||
]})
|
||||
filters = qs._build_query()['query']['filtered']['filter']
|
||||
# Filters:
|
||||
# {'and': [
|
||||
# {'in': {'type': [1, 2]}},
|
||||
# {'range': {'status': {'lte': 4}}},
|
||||
# ]}
|
||||
eq_(filters.keys(), ['and'])
|
||||
ok_({'in': {'type': [1, 2]}} in filters['and'])
|
||||
ok_({'range': {'status': {'lte': 4}}} in filters['and'])
|
||||
|
||||
def test_gt(self):
|
||||
qs = Addon.search().filter(type__in=[1, 2], status__gt=4)
|
||||
eq_(qs._build_query()['query']['filtered']['filter'],
|
||||
{'and': [
|
||||
{'in': {'type': [1, 2]}},
|
||||
{'range': {'status': {'gt': 4}}},
|
||||
]})
|
||||
filters = qs._build_query()['query']['filtered']['filter']
|
||||
# Filters:
|
||||
# {'and': [
|
||||
# {'in': {'type': [1, 2]}},
|
||||
# {'range': {'status': {'gt': 4}}},
|
||||
# ]}
|
||||
eq_(filters.keys(), ['and'])
|
||||
ok_({'in': {'type': [1, 2]}} in filters['and'])
|
||||
ok_({'range': {'status': {'gt': 4}}} in filters['and'])
|
||||
|
||||
def test_lt(self):
|
||||
qs = Addon.search().filter(type__in=[1, 2], status__lt=4)
|
||||
eq_(qs._build_query()['query']['filtered']['filter'],
|
||||
{'and': [
|
||||
{'range': {'status': {'lt': 4}}},
|
||||
{'in': {'type': [1, 2]}},
|
||||
]})
|
||||
filters = qs._build_query()['query']['filtered']['filter']
|
||||
# Filters:
|
||||
# {'and': [
|
||||
# {'range': {'status': {'lt': 4}}},
|
||||
# {'in': {'type': [1, 2]}},
|
||||
# ]}
|
||||
eq_(filters.keys(), ['and'])
|
||||
ok_({'range': {'status': {'lt': 4}}} in filters['and'])
|
||||
ok_({'in': {'type': [1, 2]}} in filters['and'])
|
||||
|
||||
def test_lt2(self):
|
||||
qs = Addon.search().filter(status__lt=4)
|
||||
|
@ -307,19 +352,35 @@ class TestES(amo.tests.ESTestCase):
|
|||
|
||||
qs = (Addon.search().filter(type=1)
|
||||
.extra(filter={'category__in': [1, 2]}))
|
||||
eq_(qs._build_query()['query']['filtered']['filter'],
|
||||
{'and': [{'term': {'type': 1}}, {'in': {'category': [1, 2]}}, ]})
|
||||
filters = qs._build_query()['query']['filtered']['filter']
|
||||
# Filters:
|
||||
# {'and': [{'term': {'type': 1}}, {'in': {'category': [1, 2]}}, ]}
|
||||
eq_(filters.keys(), ['and'])
|
||||
ok_({'term': {'type': 1}} in filters['and'])
|
||||
ok_({'in': {'category': [1, 2]}} in filters['and'])
|
||||
|
||||
def test_extra_filter_or(self):
|
||||
qs = Addon.search().extra(filter={'or_': {'status': 1, 'app': 2}})
|
||||
eq_(qs._build_query()['query']['filtered']['filter'],
|
||||
[{'or': [{'term': {'status': 1}}, {'term': {'app': 2}}]}])
|
||||
filters = qs._build_query()['query']['filtered']['filter']
|
||||
# Filters:
|
||||
# [{'or': [{'term': {'status': 1}}, {'term': {'app': 2}}]}])
|
||||
eq_(len(filters), 1)
|
||||
eq_(filters[0].keys(), ['or'])
|
||||
ok_({'term': {'status': 1}} in filters[0]['or'])
|
||||
ok_({'term': {'app': 2}} in filters[0]['or'])
|
||||
|
||||
qs = (Addon.search().filter(type=1)
|
||||
.extra(filter={'or_': {'status': 1, 'app': 2}}))
|
||||
eq_(qs._build_query()['query']['filtered']['filter'],
|
||||
{'and': [{'term': {'type': 1}},
|
||||
{'or': [{'term': {'status': 1}}, {'term': {'app': 2}}]}]})
|
||||
filters = qs._build_query()['query']['filtered']['filter']
|
||||
# Filters:
|
||||
# {'and': [{'term': {'type': 1}},
|
||||
# {'or': [{'term': {'status': 1}}, {'term': {'app': 2}}]}]})
|
||||
eq_(filters.keys(), ['and'])
|
||||
ok_({'term': {'type': 1}} in filters['and'])
|
||||
or_clause = sorted(filters['and'])[0]
|
||||
eq_(or_clause.keys(), ['or'])
|
||||
ok_({'term': {'status': 1}} in or_clause['or'])
|
||||
ok_({'term': {'app': 2}} in or_clause['or'])
|
||||
|
||||
def test_facet_range(self):
|
||||
facet = {'range': {'status': [{'lte': 3}, {'gte': 5}]}}
|
||||
|
@ -334,13 +395,7 @@ class TestES(amo.tests.ESTestCase):
|
|||
eq_(qs._build_query()['_source'], ['versions'])
|
||||
|
||||
|
||||
class TestPaginator(amo.tests.ESTestCase):
|
||||
test_es = True
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(TestPaginator, cls).setUpClass()
|
||||
cls.setUpIndex()
|
||||
class TestPaginator(amo.tests.ESTestCaseWithAddons):
|
||||
|
||||
def setUp(self):
|
||||
super(TestPaginator, self).setUp()
|
||||
|
|
|
@ -5,6 +5,7 @@ import tempfile
|
|||
from django.core.files.base import ContentFile
|
||||
from django.core.files.storage import default_storage as storage
|
||||
|
||||
import pytest
|
||||
from nose.tools import eq_
|
||||
|
||||
from amo.storage_utils import (walk_storage, copy_stored_file,
|
||||
|
@ -13,6 +14,9 @@ from amo.tests import BaseTestCase
|
|||
from amo.utils import rm_local_tmp_dir
|
||||
|
||||
|
||||
pytestmark = pytest.mark.django_db
|
||||
|
||||
|
||||
def test_storage_walk():
|
||||
tmp = tempfile.mkdtemp()
|
||||
jn = partial(os.path.join, tmp)
|
||||
|
|
|
@ -3,6 +3,7 @@ from django.conf import settings
|
|||
from django.core.urlresolvers import set_script_prefix
|
||||
from django.test.client import Client, RequestFactory
|
||||
|
||||
import pytest
|
||||
from nose.tools import eq_, assert_not_equal
|
||||
|
||||
import amo.tests
|
||||
|
@ -11,6 +12,9 @@ from amo.middleware import LocaleAndAppURLMiddleware
|
|||
from amo.tests import BaseTestCase
|
||||
|
||||
|
||||
pytestmark = pytest.mark.django_db
|
||||
|
||||
|
||||
class MiddlewareTest(BaseTestCase):
|
||||
"""Tests that the locale and app redirection work properly."""
|
||||
|
||||
|
@ -108,7 +112,7 @@ class MiddlewareTest(BaseTestCase):
|
|||
def test_get_lang(self):
|
||||
def check(url, expected):
|
||||
response = self.process(url)
|
||||
eq_(response['Location'], expected)
|
||||
self.assertUrlEqual(response['Location'], expected)
|
||||
|
||||
check('/services?lang=fr', '/services')
|
||||
check('/en-US/firefox?lang=fr', '/fr/firefox/')
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import collections
|
||||
import tempfile
|
||||
|
||||
import pytest
|
||||
from nose.tools import eq_, ok_
|
||||
|
||||
|
||||
|
@ -10,6 +11,9 @@ from addons.models import Addon
|
|||
from versions.models import Version
|
||||
|
||||
|
||||
pytestmark = pytest.mark.django_db
|
||||
|
||||
|
||||
class TestAttachTransDict(amo.tests.TestCase):
|
||||
"""
|
||||
Tests for attach_trans_dict. For convenience, we re-use Addon model instead
|
||||
|
|
|
@ -7,6 +7,7 @@ from django.test.client import Client
|
|||
from django.utils import translation
|
||||
|
||||
import jingo
|
||||
import pytest
|
||||
from mock import patch
|
||||
from nose.tools import eq_
|
||||
from pyquery import PyQuery as pq
|
||||
|
@ -29,6 +30,9 @@ from files.tests.test_models import UploadTest
|
|||
from tags.models import AddonTag, Tag
|
||||
|
||||
|
||||
pytestmark = pytest.mark.django_db
|
||||
|
||||
|
||||
def api_url(x, app='firefox', lang='en-US', version=1.2):
|
||||
return '/%s/%s/api/%s/%s' % (lang, app, version, x)
|
||||
|
||||
|
@ -434,11 +438,7 @@ class APITest(TestCase):
|
|||
'preview position="0">',
|
||||
'<caption>TwitterBar places an icon in the address bar.</caption>',
|
||||
'full type="image/png">',
|
||||
urlparams('full/%s/%d.%s' %
|
||||
('20', 20397, 'png'), src='api', modified=1209834208),
|
||||
'<thumbnail type="image/png">',
|
||||
urlparams('thumbs/%s/%d.png' %
|
||||
('20', 20397), src='api', modified=1209834208),
|
||||
('<developer_comments>Embrace hug love hug meow meow'
|
||||
'</developer_comments>'),
|
||||
'size="100352"',
|
||||
|
@ -446,6 +446,19 @@ class APITest(TestCase):
|
|||
'</homepage>'),
|
||||
'<support>http://www.chrisfinke.com/addons/twitterbar/</support>')
|
||||
|
||||
# For urls with several parameters, we need to use self.assertUrlEqual,
|
||||
# as the parameters could be in random order. Dicts aren't ordered!
|
||||
url_needles = {
|
||||
"full": urlparams(
|
||||
'{previews}full/20/20397.png'.format(
|
||||
previews=helpers.user_media_url('previews')),
|
||||
src='api', modified=1209834208),
|
||||
"thumbnail": urlparams(
|
||||
'{previews}thumbs/20/20397.png'.format(
|
||||
previews=helpers.user_media_url('previews')),
|
||||
src='api', modified=1209834208),
|
||||
}
|
||||
|
||||
response = make_call('addon/4664', version=1.5)
|
||||
doc = pq(response.content)
|
||||
|
||||
|
@ -466,6 +479,10 @@ class APITest(TestCase):
|
|||
for needle in needles:
|
||||
self.assertContains(response, needle)
|
||||
|
||||
for tag, needle in url_needles.iteritems():
|
||||
url = doc(tag).text()
|
||||
self.assertUrlEqual(url, needle)
|
||||
|
||||
def test_no_contribs_until_approved(self):
|
||||
Addon.objects.filter(id=4664).update(status=amo.STATUS_LITE)
|
||||
response = make_call('addon/4664', version=1.5)
|
||||
|
@ -588,7 +605,11 @@ class DRFAPITest(DRFMixin, APITest):
|
|||
"""
|
||||
Run all APITest tests with DRF.
|
||||
"""
|
||||
test_module_url = reverse('api.addon_detail', args=['1.5', 999999])
|
||||
|
||||
def setUp(self):
|
||||
super(DRFAPITest, self).setUp()
|
||||
self.test_module_url = reverse('api.addon_detail',
|
||||
args=['1.5', 999999])
|
||||
|
||||
|
||||
class ListTest(TestCase):
|
||||
|
@ -688,7 +709,10 @@ class DRFListTest(DRFMixin, ListTest):
|
|||
"""
|
||||
Run all ListTest tests with DRF.
|
||||
"""
|
||||
test_module_url = reverse('api.list', args=['1.5', 'featured'])
|
||||
|
||||
def setUp(self):
|
||||
super(DRFListTest, self).setUp()
|
||||
self.test_module_url = reverse('api.list', args=['1.5', 'featured'])
|
||||
|
||||
|
||||
class AddonFilterTest(TestCase):
|
||||
|
@ -1268,14 +1292,17 @@ class DRFSearchTest(DRFMixin, SearchTest):
|
|||
"""
|
||||
Run all SearchTest tests with DRF.
|
||||
"""
|
||||
test_module_url = reverse('api.search', args=['1.5', 'delicious'])
|
||||
|
||||
def setUp(self):
|
||||
super(DRFSearchTest, self).setUp()
|
||||
self.test_module_url = reverse('api.search', args=['1.5', 'delicious'])
|
||||
|
||||
|
||||
class LanguagePacks(UploadTest):
|
||||
class LanguagePacksTest(UploadTest):
|
||||
fixtures = ['addons/listed']
|
||||
|
||||
def setUp(self):
|
||||
super(LanguagePacks, self).setUp()
|
||||
super(LanguagePacksTest, self).setUp()
|
||||
self.url = reverse('api.language', args=['1.5'])
|
||||
self.tb_url = self.url.replace('firefox', 'thunderbird')
|
||||
self.addon = Addon.objects.get(pk=3723)
|
||||
|
@ -1332,8 +1359,11 @@ class LanguagePacks(UploadTest):
|
|||
]]></strings>"""))
|
||||
|
||||
|
||||
class DRFLanguagePacks(DRFMixin, LanguagePacks):
|
||||
class DRFLanguagePacksTest(DRFMixin, LanguagePacksTest):
|
||||
"""
|
||||
Run all LanguagePack tests with DRF.
|
||||
"""
|
||||
test_module_url = reverse('api.language', args=['1.5'])
|
||||
|
||||
def setUp(self):
|
||||
super(DRFLanguagePacksTest, self).setUp()
|
||||
self.test_module_url = reverse('api.language', args=['1.5'])
|
||||
|
|
|
@ -4,6 +4,7 @@ import tempfile
|
|||
|
||||
from django.conf import settings
|
||||
|
||||
import pytest
|
||||
from nose.tools import eq_
|
||||
from PIL import Image
|
||||
|
||||
|
@ -11,6 +12,9 @@ from amo.tests.test_helpers import get_image_path
|
|||
from bandwagon.tasks import resize_icon
|
||||
|
||||
|
||||
pytestmark = pytest.mark.django_db
|
||||
|
||||
|
||||
def test_resize_icon():
|
||||
somepic = get_image_path('mozilla.png')
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ import django.test
|
|||
from django.utils.datastructures import MultiValueDict
|
||||
from django.utils import encoding
|
||||
|
||||
import pytest
|
||||
from mock import patch, Mock
|
||||
from nose.tools import eq_
|
||||
from pyquery import PyQuery as pq
|
||||
|
@ -29,6 +30,9 @@ from devhub.models import ActivityLog
|
|||
from users.models import UserProfile
|
||||
|
||||
|
||||
pytestmark = pytest.mark.django_db
|
||||
|
||||
|
||||
def test_addons_form():
|
||||
f = forms.AddonsForm(MultiValueDict({'addon': [''],
|
||||
'addon_comment': ['comment']}))
|
||||
|
|
|
@ -6,7 +6,7 @@ from xml.dom import minidom
|
|||
from django.conf import settings
|
||||
from django.core.cache import cache
|
||||
|
||||
from nose.tools import eq_
|
||||
from nose.tools import eq_, ok_
|
||||
|
||||
import amo
|
||||
import amo.tests
|
||||
|
@ -229,7 +229,10 @@ class BlocklistItemTest(XMLAssertsMixin, BlocklistViewTest):
|
|||
eq_(self.vr()[0].getAttribute('minVersion'), '0.1')
|
||||
|
||||
self.item.update(max='0.2')
|
||||
eq_(self.vr()[0].attributes.keys(), ['minVersion', 'maxVersion'])
|
||||
keys = self.vr()[0].attributes.keys()
|
||||
eq_(len(keys), 2)
|
||||
ok_('minVersion' in keys)
|
||||
ok_('maxVersion' in keys)
|
||||
eq_(self.vr()[0].getAttribute('minVersion'), '0.1')
|
||||
eq_(self.vr()[0].getAttribute('maxVersion'), '0.2')
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ from django.core.cache import cache
|
|||
from django.test.utils import override_settings
|
||||
from django.utils import http as urllib
|
||||
|
||||
import pytest
|
||||
from jingo.helpers import datetime as datetime_filter
|
||||
import mock
|
||||
from nose.tools import eq_, assert_raises, nottest
|
||||
|
@ -33,6 +34,9 @@ from users.models import UserProfile
|
|||
from versions.models import Version
|
||||
|
||||
|
||||
pytestmark = pytest.mark.django_db
|
||||
|
||||
|
||||
@nottest
|
||||
def test_listing_sort(self, sort, key=None, reverse=True, sel_class='opt'):
|
||||
r = self.client.get(self.url, dict(sort=sort))
|
||||
|
@ -58,13 +62,7 @@ def test_default_sort(self, sort, key=None, reverse=True, sel_class='opt'):
|
|||
test_listing_sort(self, sort, key, reverse, sel_class)
|
||||
|
||||
|
||||
class ExtensionTestCase(amo.tests.ESTestCase):
|
||||
test_es = True
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(ExtensionTestCase, cls).setUpClass()
|
||||
cls.setUpIndex()
|
||||
class ExtensionTestCase(amo.tests.ESTestCaseWithAddons):
|
||||
|
||||
def setUp(self):
|
||||
super(ExtensionTestCase, self).setUp()
|
||||
|
@ -83,7 +81,6 @@ class TestUpdatedSort(ExtensionTestCase):
|
|||
|
||||
|
||||
class TestESExtensions(ExtensionTestCase):
|
||||
test_es = True
|
||||
|
||||
def test_landing(self):
|
||||
r = self.client.get(self.url)
|
||||
|
@ -847,9 +844,9 @@ class TestSearchToolsPages(BaseSearchToolsTest):
|
|||
|
||||
links = doc('#search-tools-sidebar a')
|
||||
|
||||
eq_([a.text.strip() for a in links],
|
||||
['Most Popular', 'Recently Added', # Search Extensions.
|
||||
'Bookmarks']) # Search Providers.
|
||||
eq_(sorted([a.text.strip() for a in links]),
|
||||
sorted(['Most Popular', 'Recently Added', # Search Extensions.
|
||||
'Bookmarks'])) # Search Providers.
|
||||
|
||||
search_ext_url = urlparse(reverse('browse.extensions',
|
||||
kwargs=dict(category='search-tools')))
|
||||
|
|
|
@ -56,8 +56,8 @@ class TestIndex(amo.tests.TestCase):
|
|||
r = self.client.get(self.url)
|
||||
eq_(r.status_code, 200)
|
||||
doc = pq(r.content)
|
||||
eq_(doc('h2.c a').attr('href'),
|
||||
'{url}?page=1&previous=1'.format(url=self.url))
|
||||
self.assertUrlEqual(doc('h2.c a').attr('href'),
|
||||
'{url}?page=1&previous=1'.format(url=self.url))
|
||||
|
||||
def test_previous_version_link_with_active_pagination(self):
|
||||
# The current pagination is not kept when we switch to previous
|
||||
|
@ -65,7 +65,8 @@ class TestIndex(amo.tests.TestCase):
|
|||
r = self.client.get(self.url, {'page': 2, 'type': 'all'})
|
||||
eq_(r.status_code, 200)
|
||||
doc = pq(r.content)
|
||||
eq_(doc('h2.c a').attr('href'),
|
||||
self.assertUrlEqual(
|
||||
doc('h2.c a').attr('href'),
|
||||
'{url}?type=all&page=1&previous=1'.format(url=self.url))
|
||||
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ import urllib
|
|||
|
||||
from django.utils import translation
|
||||
|
||||
import pytest
|
||||
from mock import Mock
|
||||
from nose.tools import eq_
|
||||
from pyquery import PyQuery as pq
|
||||
|
@ -17,6 +18,9 @@ from files.models import File
|
|||
from versions.models import Version
|
||||
|
||||
|
||||
pytestmark = pytest.mark.django_db
|
||||
|
||||
|
||||
def test_dev_page_title():
|
||||
translation.activate('en-US')
|
||||
request = Mock()
|
||||
|
|
|
@ -5,6 +5,7 @@ import tempfile
|
|||
from django.conf import settings
|
||||
|
||||
import mock
|
||||
import pytest
|
||||
from nose.tools import eq_
|
||||
from PIL import Image
|
||||
|
||||
|
@ -17,6 +18,9 @@ from devhub import tasks
|
|||
from files.models import FileUpload
|
||||
|
||||
|
||||
pytestmark = pytest.mark.django_db
|
||||
|
||||
|
||||
def test_resize_icon_shrink():
|
||||
""" Image should be shrunk so that the longest side is 32px. """
|
||||
|
||||
|
|
|
@ -1361,7 +1361,7 @@ class TestSubmitStep4(TestSubmitBase):
|
|||
eq_(Image.open(storage.open(dest)).size, (32, 12))
|
||||
|
||||
def test_edit_media_uploadedicon_noresize(self):
|
||||
img = "%s/img/notifications/error.png" % settings.STATIC_ROOT
|
||||
img = "static/img/notifications/error.png"
|
||||
src_image = open(img, 'rb')
|
||||
|
||||
data = dict(upload_image=src_image)
|
||||
|
|
|
@ -9,7 +9,7 @@ from django.db.models import Q
|
|||
from django.test.utils import override_settings
|
||||
|
||||
import mock
|
||||
from nose.tools import eq_
|
||||
from nose.tools import eq_, ok_
|
||||
from PIL import Image
|
||||
from pyquery import PyQuery as pq
|
||||
|
||||
|
@ -594,7 +594,7 @@ class TestEditMedia(TestEdit):
|
|||
eq_(log[0].action, amo.LOG.CHANGE_ICON.id)
|
||||
|
||||
def test_edit_media_uploadedicon_noresize(self):
|
||||
img = "%s/img/notifications/error.png" % settings.STATIC_ROOT
|
||||
img = "static/img/notifications/error.png"
|
||||
src_image = open(img, 'rb')
|
||||
|
||||
data = dict(upload_image=src_image)
|
||||
|
@ -629,7 +629,7 @@ class TestEditMedia(TestEdit):
|
|||
eq_(Image.open(storage.open(dest)).size, (48, 48))
|
||||
|
||||
def check_image_type(self, url, msg):
|
||||
img = '%s/js/zamboni/devhub.js' % settings.STATIC_ROOT
|
||||
img = 'static/js/zamboni/devhub.js'
|
||||
src_image = open(img, 'rb')
|
||||
|
||||
res = self.client.post(url, {'upload_image': src_image})
|
||||
|
@ -869,30 +869,37 @@ class TestEditDetails(TestEdit):
|
|||
description, homepage = map(unicode, [self.addon.description,
|
||||
self.addon.homepage])
|
||||
# TODO: description should get fixed up with the form.
|
||||
fields = ['description', 'name', 'summary']
|
||||
error = ('Before changing your default locale you must have a name, '
|
||||
'summary, and description in that locale. '
|
||||
'You are missing %s.')
|
||||
missing = lambda f: error % ', '.join(map(repr, f))
|
||||
'You are missing ')
|
||||
|
||||
d = dict(description=description, homepage=homepage,
|
||||
default_locale='fr')
|
||||
r = self.client.post(self.details_edit_url, d)
|
||||
self.assertFormError(r, 'form', None, missing(fields))
|
||||
# We can't use assertFormError here, because the missing fields are
|
||||
# stored in a dict, which isn't ordered.
|
||||
form_error = r.context['form'].non_field_errors()[0]
|
||||
ok_(form_error.startswith(error))
|
||||
ok_("'description'" in form_error)
|
||||
ok_("'name'" in form_error)
|
||||
ok_("'summary'" in form_error)
|
||||
|
||||
# Now we have a name.
|
||||
self.addon.name = {'fr': 'fr name'}
|
||||
self.addon.save()
|
||||
fields.remove('name')
|
||||
r = self.client.post(self.details_edit_url, d)
|
||||
self.assertFormError(r, 'form', None, missing(fields))
|
||||
form_error = r.context['form'].non_field_errors()[0]
|
||||
ok_(form_error.startswith(error))
|
||||
ok_("'description'" in form_error)
|
||||
ok_("'summary'" in form_error)
|
||||
|
||||
# Now we have a summary.
|
||||
self.addon.summary = {'fr': 'fr summary'}
|
||||
self.addon.save()
|
||||
fields.remove('summary')
|
||||
r = self.client.post(self.details_edit_url, d)
|
||||
self.assertFormError(r, 'form', None, missing(fields))
|
||||
form_error = r.context['form'].non_field_errors()[0]
|
||||
ok_(form_error.startswith(error))
|
||||
ok_("'description'" in form_error)
|
||||
|
||||
# Now we're sending an fr description with the form.
|
||||
d['description_fr'] = 'fr description'
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
import json
|
||||
|
||||
from django.conf import settings
|
||||
|
||||
from nose.tools import eq_
|
||||
from pyquery import PyQuery as pq
|
||||
|
||||
|
@ -44,7 +42,7 @@ class TestSubmitPersona(amo.tests.TestCase):
|
|||
'and %s pixels tall.' % (w, h)])
|
||||
|
||||
def test_img_wrongtype(self):
|
||||
img = open('%s/js/impala/global.js' % settings.STATIC_ROOT, 'rb')
|
||||
img = open('static/js/impala/global.js', 'rb')
|
||||
for url in self.get_img_urls():
|
||||
r_ajax = self.client.post(url, {'upload_image': img})
|
||||
r_json = json.loads(r_ajax.content)
|
||||
|
|
|
@ -211,7 +211,8 @@ class TestModuleAdmin(amo.tests.TestCase):
|
|||
d = dict(app=amo.FIREFOX.id, module='xx', locales='en-US he he fa fa')
|
||||
form = DiscoveryModuleForm(d)
|
||||
assert form.is_valid()
|
||||
eq_(form.cleaned_data['locales'], 'fa en-US he')
|
||||
cleaned_locales = form.cleaned_data['locales'].split()
|
||||
eq_(sorted(cleaned_locales), ['en-US', 'fa', 'he'])
|
||||
|
||||
|
||||
class TestUrls(amo.tests.TestCase):
|
||||
|
|
|
@ -4,6 +4,7 @@ from datetime import datetime, timedelta
|
|||
from django.core import mail
|
||||
from django.core.files.storage import default_storage as storage
|
||||
|
||||
import pytest
|
||||
from mock import Mock, patch
|
||||
from nose.tools import eq_
|
||||
from pyquery import PyQuery as pq
|
||||
|
@ -23,6 +24,9 @@ from versions.models import Version
|
|||
from . test_models import create_addon_file
|
||||
|
||||
|
||||
pytestmark = pytest.mark.django_db
|
||||
|
||||
|
||||
REVIEW_ADDON_STATUSES = (amo.STATUS_NOMINATED, amo.STATUS_LITE_AND_NOMINATED,
|
||||
amo.STATUS_UNREVIEWED)
|
||||
REVIEW_FILES_STATUSES = (amo.STATUS_BETA, amo.STATUS_NULL, amo.STATUS_PUBLIC,
|
||||
|
|
|
@ -7,57 +7,14 @@ from datetime import datetime
|
|||
|
||||
from django.db import connection, models
|
||||
from django.db.models import Q
|
||||
|
||||
import pytest
|
||||
from nose.tools import eq_, raises
|
||||
|
||||
from amo.tests import BaseTestCase
|
||||
from editors.sql_model import RawSQLModel
|
||||
|
||||
|
||||
def setup():
|
||||
sql = """
|
||||
create table sql_model_test_product (
|
||||
id int(11) not null auto_increment primary key,
|
||||
name varchar(255) not null,
|
||||
created datetime not null
|
||||
);
|
||||
create table sql_model_test_cat (
|
||||
id int(11) not null auto_increment primary key,
|
||||
name varchar(255) not null
|
||||
);
|
||||
create table sql_model_test_product_cat (
|
||||
id int(11) not null auto_increment primary key,
|
||||
cat_id int(11) not null references sql_model_test_cat (id),
|
||||
product_id int(11) not null references sql_model_test_product (id)
|
||||
);
|
||||
insert into sql_model_test_product (id, name, created)
|
||||
values (1, 'defilbrilator', UTC_TIMESTAMP());
|
||||
insert into sql_model_test_cat (id, name)
|
||||
values (1, 'safety');
|
||||
insert into sql_model_test_product_cat (product_id, cat_id)
|
||||
values (1, 1);
|
||||
insert into sql_model_test_product (id, name, created)
|
||||
values (2, 'life jacket', UTC_TIMESTAMP());
|
||||
insert into sql_model_test_product_cat (product_id, cat_id)
|
||||
values (2, 1);
|
||||
insert into sql_model_test_product (id, name, created)
|
||||
values (3, 'snake skin jacket', UTC_TIMESTAMP());
|
||||
insert into sql_model_test_cat (id, name)
|
||||
values (2, 'apparel');
|
||||
insert into sql_model_test_product_cat (product_id, cat_id)
|
||||
values (3, 2);
|
||||
""".split(';')
|
||||
execute_all(sql)
|
||||
|
||||
|
||||
def teardown():
|
||||
sql = """
|
||||
drop table sql_model_test_product_cat;
|
||||
drop table sql_model_test_cat;
|
||||
drop table sql_model_test_product;
|
||||
""".split(';')
|
||||
execute_all(sql)
|
||||
|
||||
|
||||
def execute_all(statements):
|
||||
cursor = connection.cursor()
|
||||
for sql in statements:
|
||||
|
@ -107,6 +64,58 @@ class ProductDetail(RawSQLModel):
|
|||
|
||||
class TestSQLModel(BaseTestCase):
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def setup(self, request):
|
||||
sql = """
|
||||
create table if not exists sql_model_test_product (
|
||||
id int(11) not null auto_increment primary key,
|
||||
name varchar(255) not null,
|
||||
created datetime not null
|
||||
);
|
||||
create table if not exists sql_model_test_cat (
|
||||
id int(11) not null auto_increment primary key,
|
||||
name varchar(255) not null
|
||||
);
|
||||
create table if not exists sql_model_test_product_cat (
|
||||
id int(11) not null auto_increment primary key,
|
||||
cat_id int(11) not null references sql_model_test_cat (id),
|
||||
product_id int(11) not null references sql_model_test_product (id)
|
||||
);
|
||||
insert into sql_model_test_product (id, name, created)
|
||||
values (1, 'defilbrilator', UTC_TIMESTAMP());
|
||||
insert into sql_model_test_cat (id, name)
|
||||
values (1, 'safety');
|
||||
insert into sql_model_test_product_cat (product_id, cat_id)
|
||||
values (1, 1);
|
||||
insert into sql_model_test_product (id, name, created)
|
||||
values (2, 'life jacket', UTC_TIMESTAMP());
|
||||
insert into sql_model_test_product_cat (product_id, cat_id)
|
||||
values (2, 1);
|
||||
insert into sql_model_test_product (id, name, created)
|
||||
values (3, 'snake skin jacket',UTC_TIMESTAMP());
|
||||
insert into sql_model_test_cat (id, name)
|
||||
values (2, 'apparel');
|
||||
insert into sql_model_test_product_cat (product_id, cat_id)
|
||||
values (3, 2);
|
||||
""".split(';')
|
||||
|
||||
def teardown():
|
||||
try:
|
||||
sql = """
|
||||
drop table if exists sql_model_test_product_cat;
|
||||
drop table if exists sql_model_test_cat;
|
||||
drop table if exists sql_model_test_product;
|
||||
""".split(';')
|
||||
execute_all(sql)
|
||||
except:
|
||||
pass # No failing here.
|
||||
|
||||
teardown()
|
||||
|
||||
execute_all(sql)
|
||||
|
||||
request.addfinalizer(teardown)
|
||||
|
||||
def test_all(self):
|
||||
eq_(sorted([s.category for s in Summary.objects.all()]),
|
||||
['apparel', 'safety'])
|
||||
|
|
|
@ -341,15 +341,15 @@ class TestHome(EditorTest):
|
|||
doc = pq(self.client.get(url).content)
|
||||
|
||||
dts, dds = doc('dt'), doc('dd')
|
||||
expected = [
|
||||
('is_flagged', 'True'),
|
||||
('addon_id', str(review.addon.pk)),
|
||||
('addon_name', 'test'),
|
||||
]
|
||||
for idx, pair in enumerate(expected):
|
||||
dt, dd = pair
|
||||
eq_(dts.eq(idx).text(), dt)
|
||||
eq_(dds.eq(idx).text(), dd)
|
||||
expected = {
|
||||
'is_flagged': 'True',
|
||||
'addon_id': str(review.addon.pk),
|
||||
'addon_name': 'test',
|
||||
}
|
||||
eq_(len(dts), 3)
|
||||
eq_(len(dds), 3)
|
||||
for dt, dd in zip(dts, dds):
|
||||
eq_(dd.text, expected[dt.text])
|
||||
|
||||
def test_stats_total(self):
|
||||
self.approve_reviews()
|
||||
|
|
|
@ -17,6 +17,7 @@ from django.db import models
|
|||
from django.dispatch import receiver
|
||||
from django.template.defaultfilters import slugify
|
||||
from django.utils.encoding import smart_str
|
||||
from django.utils.translation import force_text
|
||||
|
||||
import commonware
|
||||
from cache_nuggets.lib import memoize
|
||||
|
@ -85,7 +86,7 @@ class File(amo.models.OnChangeMixin, amo.models.ModelBase):
|
|||
return unicode(self.id)
|
||||
|
||||
def get_platform_display(self):
|
||||
return unicode(amo.PLATFORMS[self.platform].name)
|
||||
return force_text(amo.PLATFORMS[self.platform].name)
|
||||
|
||||
@property
|
||||
def has_been_validated(self):
|
||||
|
|
|
@ -13,6 +13,7 @@ from django.conf import settings
|
|||
from django.test.utils import override_settings
|
||||
|
||||
import mock
|
||||
import pytest
|
||||
from nose.tools import eq_
|
||||
|
||||
import amo
|
||||
|
@ -29,6 +30,9 @@ from files.utils import check_xpi_info, JetpackUpgrader, parse_addon, parse_xpi
|
|||
from versions.models import Version
|
||||
|
||||
|
||||
pytestmark = pytest.mark.django_db
|
||||
|
||||
|
||||
class UploadTest(amo.tests.TestCase, amo.tests.AMOPaths):
|
||||
"""
|
||||
Base for tests that mess with file uploads, safely using temp directories.
|
||||
|
@ -597,18 +601,19 @@ class TestFileUpload(UploadTest):
|
|||
assert not upload.validation
|
||||
assert not upload._escaped_validation
|
||||
validation = '{"the": "validation"}'
|
||||
escaped_validation = '{"the": "validation", "ending_tier": 0}'
|
||||
escaped_validation = {"the": "validation", "ending_tier": 0}
|
||||
upload.validation = validation
|
||||
upload.save()
|
||||
eq_(upload.validation, validation)
|
||||
eq_(upload._escaped_validation, escaped_validation)
|
||||
eq_(json.loads(upload._escaped_validation), escaped_validation)
|
||||
|
||||
def test_escaped_validation_is_escaped(self):
|
||||
validation = '''{"the": "valid<script>alert('owned')</script>ation"}'''
|
||||
escaped_validation = ('''{"the": "valid<script>alert('owned')'''
|
||||
'''</script>ation", "ending_tier": 0}''')
|
||||
escaped_validation = {
|
||||
"the": "valid<script>alert('owned')</script>ation",
|
||||
"ending_tier": 0}
|
||||
upload = FileUpload.objects.create(validation=validation)
|
||||
eq_(upload._escaped_validation, escaped_validation)
|
||||
eq_(json.loads(upload._escaped_validation), escaped_validation)
|
||||
|
||||
def test_escaped_validation_ignores_bad_json(self):
|
||||
upload = FileUpload(validation='wtf')
|
||||
|
@ -622,8 +627,8 @@ class TestFileUpload(UploadTest):
|
|||
upload = FileUpload(validation='{"messages": [{"the": "validation"}]}')
|
||||
assert not upload._escaped_validation
|
||||
upload.escaped_validation()
|
||||
eq_(upload._escaped_validation,
|
||||
'{"ending_tier": 0, "messages": [{"the": "validation"}]}')
|
||||
eq_(json.loads(upload._escaped_validation),
|
||||
{"ending_tier": 0, "messages": [{"the": "validation"}]})
|
||||
|
||||
@override_settings(VALIDATOR_MESSAGE_LIMIT=10)
|
||||
def test_limit_validator_warnings(self):
|
||||
|
|
|
@ -2,6 +2,7 @@ import json
|
|||
from contextlib import contextmanager
|
||||
from tempfile import NamedTemporaryFile
|
||||
|
||||
import pytest
|
||||
from nose.tools import eq_
|
||||
|
||||
import amo
|
||||
|
@ -13,6 +14,9 @@ from files.utils import find_jetpacks, is_beta, PackageJSONExtractor
|
|||
from versions.models import Version
|
||||
|
||||
|
||||
pytestmark = pytest.mark.django_db
|
||||
|
||||
|
||||
def test_is_beta():
|
||||
assert not is_beta('1.2')
|
||||
assert is_beta('1.2a')
|
||||
|
|
|
@ -289,14 +289,15 @@ class FilesBase(object):
|
|||
res = self.client.get(self.file_url())
|
||||
doc = pq(res.content)
|
||||
|
||||
files = doc('#id_left > optgroup > option')
|
||||
eq_([f.text for f in files],
|
||||
[str(self.files[0].get_platform_display()),
|
||||
'%s, %s' % (self.files[1].get_platform_display(),
|
||||
self.files[2].get_platform_display())])
|
||||
unreviewed_file = doc('#id_left > optgroup > option.status-unreviewed')
|
||||
public_file = doc('#id_left > optgroup > option.status-public')
|
||||
eq_(public_file.text(), str(self.files[0].get_platform_display()))
|
||||
eq_(unreviewed_file.text(),
|
||||
'%s, %s' % (self.files[1].get_platform_display(),
|
||||
self.files[2].get_platform_display()))
|
||||
|
||||
eq_(files.eq(0).attr('value'), str(self.files[0].id))
|
||||
eq_(files.eq(1).attr('value'), str(self.files[1].id))
|
||||
eq_(public_file.attr('value'), str(self.files[0].id))
|
||||
eq_(unreviewed_file.attr('value'), str(self.files[1].id))
|
||||
|
||||
def test_file_chooser_disabled_coalescing(self):
|
||||
self.files[1].update(status=amo.STATUS_DISABLED)
|
||||
|
@ -304,8 +305,8 @@ class FilesBase(object):
|
|||
res = self.client.get(self.file_url())
|
||||
doc = pq(res.content)
|
||||
|
||||
files = doc('#id_left > optgroup > option')
|
||||
eq_(files.eq(1).attr('value'), str(self.files[2].id))
|
||||
disabled_file = doc('#id_left > optgroup > option.status-disabled')
|
||||
eq_(disabled_file.attr('value'), str(self.files[2].id))
|
||||
|
||||
|
||||
class TestFileViewer(FilesBase, amo.tests.TestCase):
|
||||
|
@ -447,11 +448,11 @@ class TestFileViewer(FilesBase, amo.tests.TestCase):
|
|||
str(self.files[0].id))
|
||||
eq_(len(doc('#id_right option[value][selected]')), 0)
|
||||
|
||||
@patch.object(amo.PLATFORM_LINUX, 'name', u'所有移动平台')
|
||||
def test_file_chooser_non_ascii_platform(self):
|
||||
with self.activate(locale='zh-CN'):
|
||||
PLATFORM_NAME = u'所有移动平台'
|
||||
f = self.files[0]
|
||||
PLATFORM_NAME = u'所有移动平台'
|
||||
f = self.files[0]
|
||||
with patch.object(File, 'get_platform_display',
|
||||
lambda self: PLATFORM_NAME):
|
||||
eq_(f.get_platform_display(), PLATFORM_NAME)
|
||||
|
||||
res = self.client.get(self.file_url())
|
||||
|
|
|
@ -16,8 +16,8 @@ class CategoriesTests(amo.tests.TestCase):
|
|||
eq_(len(data), 15)
|
||||
|
||||
def test_categories_themes_translations(self):
|
||||
data = generate_categories()
|
||||
with self.activate(locale='es'):
|
||||
data = generate_categories()
|
||||
ok_(unicode(data[0].name).startswith(u'(español) '))
|
||||
|
||||
def test_categories_addons_generation(self):
|
||||
|
@ -26,6 +26,6 @@ class CategoriesTests(amo.tests.TestCase):
|
|||
eq_(len(data), 10)
|
||||
|
||||
def test_categories_addons_translations(self):
|
||||
data = generate_categories(APPS['android'])
|
||||
with self.activate(locale='es'):
|
||||
data = generate_categories(APPS['android'])
|
||||
ok_(unicode(data[0].name).startswith(u'(español) '))
|
||||
|
|
|
@ -11,7 +11,7 @@ from landfill.generators import _yield_name_and_cat, create_addon, create_theme
|
|||
from versions.models import Version
|
||||
|
||||
|
||||
class _BaseAddonGeneratorTests(amo.tests.TestCase):
|
||||
class _BaseAddonGeneratorMixin(object):
|
||||
|
||||
def test_tinyset(self):
|
||||
size = 4
|
||||
|
@ -51,23 +51,25 @@ class _BaseAddonGeneratorTests(amo.tests.TestCase):
|
|||
eq_(len(set(addonname for addonname, cat in data)), size)
|
||||
|
||||
|
||||
class FirefoxAddonGeneratorTests(_BaseAddonGeneratorTests):
|
||||
class FirefoxAddonGeneratorTests(_BaseAddonGeneratorMixin, amo.tests.TestCase):
|
||||
app = APPS['firefox']
|
||||
|
||||
|
||||
class ThunderbirdAddonGeneratorTests(_BaseAddonGeneratorTests):
|
||||
class ThunderbirdAddonGeneratorTests(_BaseAddonGeneratorMixin,
|
||||
amo.tests.TestCase):
|
||||
app = APPS['thunderbird']
|
||||
|
||||
|
||||
class AndroidAddonGeneratorTests(_BaseAddonGeneratorTests):
|
||||
class AndroidAddonGeneratorTests(_BaseAddonGeneratorMixin, amo.tests.TestCase):
|
||||
app = APPS['android']
|
||||
|
||||
|
||||
class SeamonkeyAddonGeneratorTests(_BaseAddonGeneratorTests):
|
||||
class SeamonkeyAddonGeneratorTests(_BaseAddonGeneratorMixin,
|
||||
amo.tests.TestCase):
|
||||
app = APPS['seamonkey']
|
||||
|
||||
|
||||
class ThemeGeneratorTests(_BaseAddonGeneratorTests):
|
||||
class ThemeGeneratorTests(_BaseAddonGeneratorMixin, amo.tests.TestCase):
|
||||
app = None
|
||||
|
||||
|
||||
|
|
|
@ -6,12 +6,16 @@ import urlparse
|
|||
from django.conf import settings
|
||||
|
||||
import mock
|
||||
import pytest
|
||||
from mock import Mock
|
||||
from nose.tools import eq_
|
||||
|
||||
import amo.tests
|
||||
import paypal
|
||||
|
||||
|
||||
pytestmark = pytest.mark.django_db
|
||||
|
||||
good_response = (
|
||||
'responseEnvelope.timestamp='
|
||||
'2011-01-28T06%3A16%3A33.259-08%3A00&responseEnvelope.ack=Success'
|
||||
|
|
|
@ -44,8 +44,8 @@ def addon_review_aggregates(*addons, **kw):
|
|||
stats = dict((x[0], x[1:]) for x in
|
||||
Review.objects.valid().no_cache().using(using)
|
||||
.filter(addon__in=addons, is_latest=True)
|
||||
.values_list('addon')
|
||||
.annotate(Avg('rating'), Count('addon')))
|
||||
.annotate(Avg('rating'), Count('addon'))
|
||||
.values_list('addon', 'rating__avg', 'addon__count'))
|
||||
for addon in addon_objs:
|
||||
rating, reviews = stats.get(addon.id, [0, 0])
|
||||
addon.update(total_reviews=reviews, average_rating=rating)
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import json
|
||||
from nose.tools import eq_
|
||||
from pyquery import PyQuery as pq
|
||||
|
||||
|
@ -445,7 +446,7 @@ class TestTranslate(ReviewTest):
|
|||
review.id, 'fr')
|
||||
r = self.client.get(url, HTTP_X_REQUESTED_WITH='XMLHttpRequest')
|
||||
eq_(r.status_code, 200)
|
||||
eq_(r.content, '{"body": "oui", "title": "oui"}')
|
||||
eq_(json.loads(r.content), {"body": "oui", "title": "oui"})
|
||||
|
||||
@mock.patch('waffle.switch_is_active', lambda x: True)
|
||||
@mock.patch('reviews.views.requests')
|
||||
|
|
|
@ -1,12 +1,16 @@
|
|||
from django.utils import translation
|
||||
|
||||
import jingo
|
||||
import pytest
|
||||
from mock import Mock
|
||||
from nose.tools import eq_
|
||||
|
||||
from amo.tests.test_helpers import render
|
||||
|
||||
|
||||
pytestmark = pytest.mark.django_db
|
||||
|
||||
|
||||
def test_showing_helper():
|
||||
translation.activate('en-US')
|
||||
tpl = "{{ showing(query, tag, pager) }}"
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
import pytest
|
||||
from nose.tools import eq_
|
||||
|
||||
from search.utils import floor_version
|
||||
|
||||
|
||||
pytestmark = pytest.mark.django_db
|
||||
|
||||
|
||||
def test_floor_version():
|
||||
|
||||
def c(x, y):
|
||||
|
|
|
@ -6,6 +6,7 @@ from django.http import QueryDict
|
|||
from django.test.client import RequestFactory
|
||||
|
||||
import mock
|
||||
import pytest
|
||||
from jingo.helpers import datetime as datetime_filter
|
||||
from nose.tools import eq_
|
||||
from pyquery import PyQuery as pq
|
||||
|
@ -25,12 +26,10 @@ from users.models import UserProfile
|
|||
from versions.compare import num as vnum, version_int as vint, MAXVERSION
|
||||
|
||||
|
||||
class TestSearchboxTarget(amo.tests.ESTestCase):
|
||||
pytestmark = pytest.mark.django_db
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(TestSearchboxTarget, cls).setUpClass()
|
||||
cls.setUpIndex()
|
||||
|
||||
class TestSearchboxTarget(amo.tests.ESTestCaseWithAddons):
|
||||
|
||||
def check(self, url, placeholder, cat=None, action=None, q=None):
|
||||
# Checks that we search within addons, personas, collections, etc.
|
||||
|
@ -66,7 +65,7 @@ class TestSearchboxTarget(amo.tests.ESTestCase):
|
|||
'search for add-ons', q='ballin')
|
||||
|
||||
|
||||
class SearchBase(amo.tests.ESTestCase):
|
||||
class SearchBase(amo.tests.ESTestCaseWithAddons):
|
||||
|
||||
def get_results(self, r, sort=True):
|
||||
"""Return pks of add-ons shown on search results page."""
|
||||
|
@ -128,11 +127,6 @@ class SearchBase(amo.tests.ESTestCase):
|
|||
class TestESSearch(SearchBase):
|
||||
fixtures = ['base/category']
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(TestESSearch, cls).setUpClass()
|
||||
cls.setUpIndex()
|
||||
|
||||
def setUp(self):
|
||||
super(TestESSearch, self).setUp()
|
||||
self.url = reverse('search.search')
|
||||
|
@ -234,7 +228,12 @@ class TestESSearch(SearchBase):
|
|||
to = ('?sort=updated&advancedsearch=1&appver=1.0'
|
||||
'&tag=dearbhair&cat=4%2C84')
|
||||
r = self.client.get(url + from_)
|
||||
self.assertRedirects(r, url + to, status_code=301)
|
||||
eq_(r.status_code, 301)
|
||||
redirected = r.url
|
||||
parsed = urlparse.urlparse(redirected)
|
||||
params = parsed.query
|
||||
eq_(parsed.path, url)
|
||||
eq_(urlparse.parse_qs(params), urlparse.parse_qs(to[1:]))
|
||||
|
||||
def check_platform_filters(self, platform, expected=None):
|
||||
r = self.client.get('%s?platform=%s' % (self.url, platform),
|
||||
|
@ -617,11 +616,6 @@ class TestESSearch(SearchBase):
|
|||
|
||||
class TestPersonaSearch(SearchBase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(TestPersonaSearch, cls).setUpClass()
|
||||
cls.setUpIndex()
|
||||
|
||||
def setUp(self):
|
||||
super(TestPersonaSearch, self).setUp()
|
||||
self.url = urlparams(reverse('search.search'), atype=amo.ADDON_PERSONA)
|
||||
|
@ -644,7 +638,7 @@ class TestPersonaSearch(SearchBase):
|
|||
self._addons.append(amo.tests.addon_factory(type=amo.ADDON_PERSONA,
|
||||
disabled_by_user=True))
|
||||
|
||||
# NOTE: There are also some add-ons in `setUpIndex` for good measure.
|
||||
# NOTE: There are also some add-ons in the setUpClass for good measure.
|
||||
|
||||
self.refresh()
|
||||
|
||||
|
@ -796,6 +790,7 @@ class TestCollectionSearch(SearchBase):
|
|||
self.refresh()
|
||||
|
||||
def test_legacy_redirect(self):
|
||||
self._generate()
|
||||
# Ensure `sort=newest` redirects to `sort=created`.
|
||||
r = self.client.get(urlparams(self.url, sort='newest'))
|
||||
self.assertRedirects(r, urlparams(self.url, sort='created'), 301)
|
||||
|
@ -1067,12 +1062,7 @@ def test_search_redirects():
|
|||
yield same, qs
|
||||
|
||||
|
||||
class TestAjaxSearch(amo.tests.ESTestCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(TestAjaxSearch, cls).setUpClass()
|
||||
cls.setUpIndex()
|
||||
class TestAjaxSearch(amo.tests.ESTestCaseWithAddons):
|
||||
|
||||
def search_addons(self, url, params, addons=[], types=amo.ADDON_TYPES,
|
||||
src=None):
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
from django.conf import settings
|
||||
from django.utils import translation, encoding
|
||||
|
||||
import pytest
|
||||
import tower
|
||||
from mock import Mock, patch
|
||||
from nose.tools import eq_
|
||||
from pyquery import PyQuery as pq
|
||||
import tower
|
||||
|
||||
from addons.models import Addon
|
||||
import amo
|
||||
|
@ -18,6 +19,9 @@ from sharing import DIGG, FACEBOOK
|
|||
from users.models import UserProfile
|
||||
|
||||
|
||||
pytestmark = pytest.mark.django_db
|
||||
|
||||
|
||||
class SharingHelpersTestCase(BaseTestCase):
|
||||
fixtures = ['base/addon_3615']
|
||||
|
||||
|
|
|
@ -157,7 +157,6 @@ class TestIndexStats(amo.tests.TestCase):
|
|||
|
||||
|
||||
class TestIndexLatest(amo.tests.ESTestCase):
|
||||
test_es = True
|
||||
|
||||
def test_index_latest(self):
|
||||
latest = datetime.date.today() - datetime.timedelta(days=5)
|
||||
|
|
|
@ -88,6 +88,15 @@ class ESStatsTest(StatsTest, amo.tests.ESTestCase):
|
|||
tasks.index_theme_user_counts(list(user_counts))
|
||||
self.refresh('stats')
|
||||
|
||||
def csv_eq(self, response, expected):
|
||||
content = csv.DictReader(
|
||||
# Drop lines that are comments.
|
||||
filter(lambda row: row[0] != '#', response.content.splitlines()))
|
||||
expected = csv.DictReader(
|
||||
# Strip any extra spaces from the expected content.
|
||||
line.strip() for line in expected.splitlines())
|
||||
self.assertEqual(tuple(content), tuple(expected))
|
||||
|
||||
|
||||
class TestSeriesSecurity(StatsTest):
|
||||
"""Tests to make sure all restricted data remains restricted."""
|
||||
|
@ -169,21 +178,23 @@ class TestSeriesSecurity(StatsTest):
|
|||
self._check_it(self.private_views_gen(addon_id=5, format='json'), 403)
|
||||
|
||||
|
||||
class _TestCSVs(StatsTest):
|
||||
class TestCSVs(ESStatsTest):
|
||||
"""Tests for CSV output of all known series views."""
|
||||
first_row = 5
|
||||
|
||||
def test_downloads_series(self):
|
||||
response = self.get_view_response('stats.downloads_series',
|
||||
group='month', format='csv')
|
||||
|
||||
eq_(response.status_code, 200, 'unexpected http status')
|
||||
rows = list(csv.reader(response.content.split('\n')))
|
||||
row = rows[self.first_row] # the first row of data after the header
|
||||
eq_(len(row), 2, 'unexpected row length')
|
||||
date, count = row
|
||||
eq_(date, '2009-06-01', 'unexpected date string: %s' % date)
|
||||
eq_(count, '50', 'unexpected count value: %s' % count)
|
||||
self.csv_eq(response, """date,count
|
||||
2009-09-03,10
|
||||
2009-08-03,10
|
||||
2009-07-03,10
|
||||
2009-06-28,10
|
||||
2009-06-20,10
|
||||
2009-06-12,10
|
||||
2009-06-07,10
|
||||
2009-06-01,10""")
|
||||
|
||||
def test_usage_series(self):
|
||||
for url_args in [self.url_args, self.url_args_theme]:
|
||||
|
@ -193,111 +204,82 @@ class _TestCSVs(StatsTest):
|
|||
group='month', format='csv')
|
||||
|
||||
eq_(response.status_code, 200, 'unexpected http status')
|
||||
rows = list(csv.reader(response.content.split('\n')))
|
||||
# The first row of data after the header.
|
||||
row = rows[self.first_row]
|
||||
eq_(len(row), 2, 'unexpected row length')
|
||||
date, ave = row
|
||||
eq_(date, '2009-06-01', 'unexpected date string: %s' % date)
|
||||
eq_(ave, '83', 'unexpected ADU average: %s' % ave)
|
||||
self.csv_eq(response, """date,count
|
||||
2009-06-02,1500
|
||||
2009-06-01,1000""")
|
||||
|
||||
def test_contributions_series(self):
|
||||
response = self.get_view_response('stats.contributions_series',
|
||||
group='day', format='csv')
|
||||
|
||||
eq_(response.status_code, 200, 'unexpected http status')
|
||||
rows = list(csv.reader(response.content.split('\n')))
|
||||
row = rows[self.first_row] # the first row of data after the header
|
||||
eq_(len(row), 4, 'unexpected row length')
|
||||
date, total, count, ave = row
|
||||
eq_(date, '2009-06-02', 'unexpected date string: %s' % date)
|
||||
eq_(total, '4.98', 'unexpected contribution total: %s' % total)
|
||||
eq_(count, '2', 'unexpected contribution count: %s' % count)
|
||||
eq_(ave, '2.49', 'unexpected contribution average: %s' % ave)
|
||||
self.csv_eq(response, """date,total,count,average
|
||||
2009-06-02,4.98,2,2.49
|
||||
2009-06-01,5.0,1,5.0""")
|
||||
|
||||
def test_sources_series(self):
|
||||
response = self.get_view_response('stats.sources_series',
|
||||
group='month', format='csv')
|
||||
|
||||
eq_(response.status_code, 200, 'unexpected http status')
|
||||
rows = list(csv.reader(response.content.split('\n')))
|
||||
row = rows[self.first_row] # the first row of data after the header
|
||||
eq_(len(row), 5, 'unexpected row length')
|
||||
date, count, source1, source2, source3 = row
|
||||
eq_(date, '2009-06-01', 'unexpected date string: %s' % date)
|
||||
eq_(count, '50', 'unexpected count: %s' % count)
|
||||
eq_(source1, '25', 'unexpected source1 count: %s' % source1)
|
||||
eq_(source2, '15', 'unexpected source2 count: %s' % source2)
|
||||
eq_(source3, '10', 'unexpected source3 count: %s' % source3)
|
||||
self.csv_eq(response, """date,count,search,api
|
||||
2009-09-03,10,3,2
|
||||
2009-08-03,10,3,2
|
||||
2009-07-03,10,3,2
|
||||
2009-06-28,10,3,2
|
||||
2009-06-20,10,3,2
|
||||
2009-06-12,10,3,2
|
||||
2009-06-07,10,3,2
|
||||
2009-06-01,10,3,2""")
|
||||
|
||||
def test_os_series(self):
|
||||
response = self.get_view_response('stats.os_series',
|
||||
group='month', format='csv')
|
||||
|
||||
eq_(response.status_code, 200, 'unexpected http status')
|
||||
rows = list(csv.reader(response.content.split('\n')))
|
||||
row = rows[self.first_row] # the first row of data after the header
|
||||
eq_(len(row), 5, 'unexpected row length')
|
||||
date, count, os1, os2, os3 = row
|
||||
eq_(date, '2009-06-01', 'unexpected date string: %s' % date)
|
||||
eq_(count, '83', 'unexpected count: %s' % count)
|
||||
eq_(os1, '30', 'unexpected os1 count: %s' % os1)
|
||||
eq_(os2, '30', 'unexpected os2 count: %s' % os2)
|
||||
eq_(os3, '23', 'unexpected os3 count: %s' % os3)
|
||||
self.csv_eq(response, """date,count,Windows,Linux
|
||||
2009-06-02,1500,500,400
|
||||
2009-06-01,1000,400,300""")
|
||||
|
||||
def test_locales_series(self):
|
||||
response = self.get_view_response('stats.locales_series',
|
||||
group='month', format='csv')
|
||||
|
||||
eq_(response.status_code, 200, 'unexpected http status')
|
||||
rows = list(csv.reader(response.content.split('\n')))
|
||||
row = rows[self.first_row] # the first row of data after the header
|
||||
eq_(len(row), 3, 'unexpected row length')
|
||||
date, count, locale1 = row
|
||||
eq_(date, '2009-06-01', 'unexpected date string: %s' % date)
|
||||
eq_(count, '83', 'unexpected count: %s' % count)
|
||||
eq_(locale1, '83', 'unexpected locale1 count: %s' % locale1)
|
||||
self.csv_eq(
|
||||
response,
|
||||
"""date,count,English (US) (en-us),"""
|
||||
"""\xce\x95\xce\xbb\xce\xbb\xce\xb7\xce\xbd\xce\xb9\xce\xba"""
|
||||
"""\xce\xac (el)
|
||||
2009-06-02,1500,300,400
|
||||
2009-06-01,1000,300,400""")
|
||||
|
||||
def test_statuses_series(self):
|
||||
response = self.get_view_response('stats.statuses_series',
|
||||
group='month', format='csv')
|
||||
|
||||
eq_(response.status_code, 200, 'unexpected http status')
|
||||
rows = list(csv.reader(response.content.split('\n')))
|
||||
row = rows[self.first_row] # the first row of data after the header
|
||||
eq_(len(row), 4, 'unexpected row length')
|
||||
date, count, status1, status2 = row
|
||||
eq_(date, '2009-06-01', 'unexpected date string: %s' % date)
|
||||
eq_(count, '83', 'unexpected count: %s' % count)
|
||||
eq_(status1, '77', 'unexpected status1 count: %s' % status1)
|
||||
eq_(status2, '6', 'unexpected status2 count: %s' % status2)
|
||||
self.csv_eq(response, """date,count,userEnabled,userDisabled
|
||||
2009-06-02,1500,1370,130
|
||||
2009-06-01,1000,950,50""")
|
||||
|
||||
def test_versions_series(self):
|
||||
response = self.get_view_response('stats.versions_series',
|
||||
group='month', format='csv')
|
||||
|
||||
eq_(response.status_code, 200, 'unexpected http status')
|
||||
rows = list(csv.reader(response.content.split('\n')))
|
||||
row = rows[self.first_row] # the first row of data after the header
|
||||
eq_(len(row), 4, 'unexpected row length')
|
||||
date, count, version1, version2 = row
|
||||
eq_(date, '2009-06-01', 'unexpected date string: %s' % date)
|
||||
eq_(count, '83', 'unexpected count: %s' % count)
|
||||
eq_(version1, '58', 'unexpected version1 count: %s' % version1)
|
||||
eq_(version2, '25', 'unexpected version2 count: %s' % version2)
|
||||
self.csv_eq(response, """date,count,2.0,1.0
|
||||
2009-06-02,1500,950,550
|
||||
2009-06-01,1000,800,200""")
|
||||
|
||||
def test_apps_series(self):
|
||||
response = self.get_view_response('stats.apps_series',
|
||||
group='month', format='csv')
|
||||
|
||||
eq_(response.status_code, 200, 'unexpected http status')
|
||||
rows = list(csv.reader(response.content.split('\n')))
|
||||
row = rows[self.first_row] # the first row of data after the header
|
||||
eq_(len(row), 3, 'unexpected row length')
|
||||
date, count, app1 = row
|
||||
eq_(date, '2009-06-01', 'unexpected date string: %s' % date)
|
||||
eq_(count, '83', 'unexpected count: %s' % count)
|
||||
eq_(app1, '83', 'unexpected app1 count: %s' % app1)
|
||||
self.csv_eq(response, """date,count,Firefox 4.0
|
||||
2009-06-02,1500,1500
|
||||
2009-06-01,1000,1000""")
|
||||
|
||||
def test_no_cache(self):
|
||||
"""Test that the csv or json is not caching, due to lack of data."""
|
||||
|
@ -323,10 +305,7 @@ class _TestCSVs(StatsTest):
|
|||
group='day', format='csv')
|
||||
|
||||
eq_(response.status_code, 200)
|
||||
rows = list(csv.reader(response.content.split('\n')))
|
||||
eq_(len(rows), 6)
|
||||
eq_(rows[4], []) # No fields
|
||||
eq_(rows[self.first_row], []) # There is no data
|
||||
self.csv_eq(response, """date,count""")
|
||||
|
||||
|
||||
class TestCacheControl(StatsTest):
|
||||
|
@ -359,14 +338,6 @@ class TestLayout(StatsTest):
|
|||
|
||||
|
||||
class TestResponses(ESStatsTest):
|
||||
test_es = True
|
||||
|
||||
def csv_eq(self, response, expected):
|
||||
# Drop the first 4 lines, which contain the header comment.
|
||||
content = response.content.splitlines()[4:]
|
||||
# Strip any extra spaces from the expected content.
|
||||
expected = [line.strip() for line in expected.splitlines()]
|
||||
self.assertListEqual(content, expected)
|
||||
|
||||
def test_usage_json(self):
|
||||
for url_args in [self.url_args, self.url_args_theme]:
|
||||
|
|
|
@ -697,7 +697,7 @@ def render_csv(request, addon, stats, fields,
|
|||
writer.writeheader()
|
||||
writer.writerows(stats)
|
||||
|
||||
fudge_headers(response, list)
|
||||
fudge_headers(response, stats)
|
||||
response['Content-Type'] = 'text/csv; charset=utf-8'
|
||||
return response
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ from django.conf import settings
|
|||
from django.utils import translation
|
||||
|
||||
import jingo
|
||||
import pytest
|
||||
from mock import Mock, patch
|
||||
from nose.tools import eq_
|
||||
|
||||
|
@ -14,6 +15,9 @@ from translations.models import PurifiedTranslation
|
|||
from translations.tests.testapp.models import TranslatedModel
|
||||
|
||||
|
||||
pytestmark = pytest.mark.django_db
|
||||
|
||||
|
||||
def super():
|
||||
jingo.load_helpers()
|
||||
|
||||
|
|
|
@ -4,12 +4,14 @@ from contextlib import nested
|
|||
import django
|
||||
from django.conf import settings
|
||||
from django.db import connections, reset_queries
|
||||
from django.test import TransactionTestCase
|
||||
from django.test.utils import override_settings
|
||||
from django.utils import translation
|
||||
from django.utils.functional import lazy
|
||||
|
||||
import jinja2
|
||||
import multidb
|
||||
import pytest
|
||||
from mock import patch
|
||||
from nose import SkipTest
|
||||
from nose.tools import eq_
|
||||
|
@ -25,6 +27,9 @@ from translations.models import (LinkifiedTranslation, NoLinksTranslation,
|
|||
TranslationSequence)
|
||||
|
||||
|
||||
pytestmark = pytest.mark.django_db
|
||||
|
||||
|
||||
def ids(qs):
|
||||
return [o.id for o in qs]
|
||||
|
||||
|
@ -431,7 +436,7 @@ class TranslationTestCase(BaseTestCase):
|
|||
eq_(obj.name.locale, 'de')
|
||||
|
||||
|
||||
class TranslationMultiDbTests(BaseTestCase):
|
||||
class TranslationMultiDbTests(TransactionTestCase):
|
||||
fixtures = ['testapp/test_models.json']
|
||||
|
||||
def setUp(self):
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
import pytest
|
||||
from nose.tools import eq_
|
||||
|
||||
from translations.models import Translation
|
||||
from translations.utils import transfield_changed, truncate, truncate_text
|
||||
|
||||
|
||||
pytestmark = pytest.mark.django_db
|
||||
|
||||
|
||||
def test_truncate_text():
|
||||
eq_(truncate_text('foobar', 5), ('...', 0))
|
||||
eq_(truncate_text('foobar', 5, True), ('fooba...', 0))
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import re
|
||||
|
||||
import pytest
|
||||
from nose.tools import eq_
|
||||
from pyquery import PyQuery as pq
|
||||
|
||||
|
@ -13,6 +14,9 @@ from users.helpers import (addon_users_list, emaillink, user_data, user_link,
|
|||
from users.models import UserProfile, RequestUser
|
||||
|
||||
|
||||
pytestmark = pytest.mark.django_db
|
||||
|
||||
|
||||
def test_emaillink():
|
||||
email = 'me@example.com'
|
||||
obfuscated = unicode(emaillink(email))
|
||||
|
|
|
@ -6,6 +6,7 @@ import tempfile
|
|||
from django.conf import settings
|
||||
from django.core.files.storage import default_storage as storage
|
||||
|
||||
import pytest
|
||||
from nose.tools import eq_
|
||||
from PIL import Image
|
||||
|
||||
|
@ -13,6 +14,9 @@ from amo.tests.test_helpers import get_image_path
|
|||
from users.tasks import delete_photo, resize_photo
|
||||
|
||||
|
||||
pytestmark = pytest.mark.django_db
|
||||
|
||||
|
||||
def test_delete_photo():
|
||||
dst_path = tempfile.mktemp(suffix='.png',
|
||||
dir=settings.TMP_PATH)
|
||||
|
|
|
@ -11,6 +11,7 @@ from django.core.files.base import File as DjangoFile
|
|||
from django.test.utils import override_settings
|
||||
|
||||
import mock
|
||||
import pytest
|
||||
from nose.tools import eq_
|
||||
from pyquery import PyQuery
|
||||
|
||||
|
@ -33,6 +34,9 @@ from versions.compare import (MAXVERSION, version_int, dict_from_int,
|
|||
version_dict)
|
||||
|
||||
|
||||
pytestmark = pytest.mark.django_db
|
||||
|
||||
|
||||
def test_version_int():
|
||||
"""Tests that version_int. Corrects our versions."""
|
||||
eq_(version_int('3.5.0a1pre2'), 3050000001002)
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
# The following line is needed for all the hackery done to the python path.
|
||||
import manage # noqa
|
||||
|
||||
from django.conf import settings
|
||||
from django.db.models import loading
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True, scope='session')
|
||||
def _load_testapp():
|
||||
extra_apps = getattr(settings, 'TEST_INSTALLED_APPS')
|
||||
if extra_apps:
|
||||
installed_apps = getattr(settings, 'INSTALLED_APPS')
|
||||
setattr(settings, 'INSTALLED_APPS', installed_apps + extra_apps)
|
||||
loading.cache.loaded = False
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def mock_inline_css(monkeypatch):
|
||||
"""Mock jingo_minify.helpers.is_external: don't break on missing files.
|
||||
|
||||
When testing, we don't want nor need the bundled/minified css files, so
|
||||
pretend that all the css files are external.
|
||||
|
||||
Mocking this will prevent amo.helpers.inline_css to believe it should
|
||||
bundle the css.
|
||||
|
||||
"""
|
||||
import amo.helpers
|
||||
monkeypatch.setattr(amo.helpers, 'is_external', lambda css: True)
|
|
@ -9,6 +9,3 @@ DEBUG_TOOLBAR_PATCH_SETTINGS = False # Prevent DDT from patching the settings.
|
|||
|
||||
INTERNAL_IPS = ('127.0.0.1',)
|
||||
MIDDLEWARE_CLASSES += ('debug_toolbar.middleware.DebugToolbarMiddleware',)
|
||||
|
||||
# Uncomment to run ES tests (Elasticsearch need to be installed).
|
||||
#RUN_ES_TESTS = True
|
||||
|
|
|
@ -4,11 +4,11 @@
|
|||
Testing
|
||||
=======
|
||||
|
||||
We're using a mix of `Django's Unit Testing`_ and `nose`_
|
||||
`Selenium`_ for our automated testing. This gives us a lot of power and
|
||||
flexibility to test all aspects of the site.
|
||||
We're using a mix of `Django's Unit Testing`_ and `pytest`_ with
|
||||
`pytest-django`_, and `Selenium`_ for our automated testing. This gives us a
|
||||
lot of power and flexibility to test all aspects of the site.
|
||||
|
||||
Selenium tests are maintained in a seperate `Selenium repository`_.
|
||||
Selenium tests are maintained in a separate `Selenium repository`_.
|
||||
|
||||
Configuration
|
||||
-------------
|
||||
|
@ -19,9 +19,18 @@ has full permissions to modify a database with ``test_`` prepended to it. By
|
|||
default the database name is ``olympia``, so the test database is
|
||||
``test_olympia``.
|
||||
Optionally, in particular if the code you are working on is related to search,
|
||||
you'll want to run Elasticsearch tests. For this, you need to set the setting
|
||||
``RUN_ES_TESTS=True``. Obviously, you need Elasticsearch to be installed. See
|
||||
:ref:`elasticsearch` page for details.
|
||||
you'll want to run Elasticsearch tests. Obviously, you need Elasticsearch to be
|
||||
installed. See :ref:`elasticsearch` page for details.
|
||||
|
||||
If you don't want to run the Elasticsearch tests, you can use the
|
||||
``test_no_es`` target in the Makefile::
|
||||
|
||||
make test_no_es
|
||||
|
||||
On the contrary, if you only want to run Elasticsearch tests, use the
|
||||
``test_es`` target::
|
||||
|
||||
make test_es
|
||||
|
||||
|
||||
Running Tests
|
||||
|
@ -29,22 +38,19 @@ Running Tests
|
|||
|
||||
To run the whole shebang use::
|
||||
|
||||
python manage.py test
|
||||
py.test
|
||||
|
||||
There are a lot of options you can pass to adjust the output. Read `the docs`_
|
||||
for the full set, but some common ones are:
|
||||
There are a lot of options you can pass to adjust the output. Read `pytest`_
|
||||
and `pytest-django`_ docs for the full set, but some common ones are:
|
||||
|
||||
* ``--noinput`` tells Django not to ask about creating or destroying test
|
||||
databases.
|
||||
* ``--logging-clear-handlers`` tells nose that you don't want to see any
|
||||
logging output. Without this, our debug logging will spew all over your
|
||||
console during test runs. This can be useful for debugging, but it's not that
|
||||
great most of the time. See the docs for more stuff you can do with
|
||||
:mod:`nose and logging <nose.plugins.logcapture>`.
|
||||
|
||||
Our continuous integration server adds some additional flags for other features
|
||||
(for example, coverage statistics). To see what those commands are check out
|
||||
the build script at :src:`scripts/build.sh`.
|
||||
* ``-v`` to provide more verbose information about the test run
|
||||
* ``-s`` tells pytest to not capture the logging output
|
||||
* ``--create-db`` tells pytest-django to recreate the database instead of
|
||||
reusing the one from the previous run
|
||||
* ``-x --pdb`` to stop on the first failure, and drop into a python debugger
|
||||
* ``--lf`` to re-run the last test failed
|
||||
* ``-m test_es`` will only run tests that are marked with the ``test_es`` mark
|
||||
* ``-k foobar`` will only run tests that contain ``foobar`` in their name
|
||||
|
||||
There are a few useful makefile targets that you can use:
|
||||
|
||||
|
@ -63,10 +69,9 @@ To fail and stop running tests on the first failure::
|
|||
If you wish to add arguments, or run a specific test, overload the variables
|
||||
(check the Makefile for more information)::
|
||||
|
||||
make ARGS='--verbosity 2 olympia.apps.amo.tests.test_url_prefix:MiddlewareTest.test_get_app' test
|
||||
make test ARGS='-v apps/amo/tests/test_url_prefix.py::MiddlewareTest::test_get_app'
|
||||
|
||||
Those targets include some useful options, like the ``--with-id`` which allows
|
||||
you to re-run only the tests failed from the previous run::
|
||||
If you wish to re-run only the tests failed from the previous run::
|
||||
|
||||
make test_failed
|
||||
|
||||
|
@ -74,11 +79,17 @@ you to re-run only the tests failed from the previous run::
|
|||
Database Setup
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
Our test runner will try as hard as it can to skip creating a fresh database
|
||||
every time. If you really want to make a new database (e.g. when models have
|
||||
changed), set the environment variable ``FORCE_DB``. ::
|
||||
Our test runner is configured by default to reuse the database between each
|
||||
test run. If you really want to make a new database (e.g. when models have
|
||||
changed), use the ``--create-db`` parameter::
|
||||
|
||||
FORCE_DB=true python manage.py test
|
||||
py.test --create-db
|
||||
|
||||
or
|
||||
|
||||
::
|
||||
|
||||
make test_force_db
|
||||
|
||||
|
||||
Writing Tests
|
||||
|
@ -86,6 +97,11 @@ Writing Tests
|
|||
We support two types of automated tests right now and there are some details
|
||||
below but remember, if you're confused look at existing tests for examples.
|
||||
|
||||
Also, take some time to get familiar with `pytest`_ way of dealing with
|
||||
dependency injection, which they call `fixtures`_ (which should not be confused
|
||||
with Django's fixtures). They are very powerful, and can make your tests much
|
||||
more independent, cleaner, shorter, and more readable.
|
||||
|
||||
|
||||
Unit/Functional Tests
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
@ -98,15 +114,12 @@ External calls
|
|||
Connecting to remote services in tests is not recommended, developers should
|
||||
mock_ out those calls instead.
|
||||
|
||||
To enforce this we run Jenkins with the `nose-blockage`_ plugin, that
|
||||
will raise errors if you have an HTTP calls in your tests apart from calls to
|
||||
the whitelisted domains of `127.0.0.1` and `localhost`.
|
||||
|
||||
Why Tests Fail
|
||||
--------------
|
||||
Tests usually fail for one of two reasons: The code has changed or the data has
|
||||
changed. An third reason is **time**. Some tests have time-dependent data
|
||||
usually in the fixtues. For example, some featured items have expiration dates.
|
||||
usually in the fixtures. For example, some featured items have expiration
|
||||
dates.
|
||||
|
||||
We can usually save our future-selves time by setting these expirations far in
|
||||
the future.
|
||||
|
@ -124,9 +137,9 @@ need to recompile the .mo files manually, for example::
|
|||
|
||||
|
||||
.. _`Django's Unit Testing`: http://docs.djangoproject.com/en/dev/topics/testing
|
||||
.. _`nose`: https://nose.readthedocs.org/en/latest/
|
||||
.. _`pytest`: http://pytest.org/latest/
|
||||
.. _`pytest-django`: https://nose.readthedocs.org/en/latest/
|
||||
.. _`Selenium`: http://www.seleniumhq.org/
|
||||
.. _`Selenium repository`: https://github.com/mozilla/Addon-Tests/
|
||||
.. _`the docs`: http://docs.djangoproject.com/en/dev/topics/testing#id1
|
||||
.. _mock: http://pypi.python.org/pypi/mock
|
||||
.. _`nose-blockage`: https://github.com/andymckay/nose-blockage
|
||||
.. _fixtures: http://pytest.org/latest/fixture.html
|
||||
|
|
|
@ -91,12 +91,19 @@ Testing with Elasticsearch
|
|||
--------------------------
|
||||
|
||||
All test cases using Elasticsearch should inherit from ``amo.tests.ESTestCase``.
|
||||
All such tests will be skipped by the test runner unless::
|
||||
All such tests are marked with the ``es_tests`` pytest_ marker. To run only
|
||||
those tests::
|
||||
|
||||
RUN_ES_TESTS = True
|
||||
py.test -m es_tests
|
||||
|
||||
or
|
||||
|
||||
::
|
||||
|
||||
make test_es
|
||||
|
||||
.. _pytest: http://pytest.org/latest/
|
||||
|
||||
This is done as a performance optimization to keep the run time of the test
|
||||
suite down, unless necessary.
|
||||
|
||||
Troubleshooting
|
||||
---------------
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
import pytest
|
||||
from array import array
|
||||
from nose.tools import eq_
|
||||
|
||||
import recommend
|
||||
from lib import recommend
|
||||
|
||||
|
||||
pytestmark = pytest.mark.django_db
|
||||
|
||||
|
||||
def test_symmetric_diff_count():
|
||||
|
|
|
@ -1349,11 +1349,6 @@ SIGNING_OMIT_PER_FILE_SIGS = True
|
|||
# True when the Django app is running from the test suite.
|
||||
IN_TEST_SUITE = False
|
||||
|
||||
# Until bug 753421 gets fixed, we're skipping ES tests. Sad times. I know.
|
||||
# Flip this on in your local settings or set an environment variable to
|
||||
# experience the joy of ES tests.
|
||||
RUN_ES_TESTS = False
|
||||
|
||||
# The configuration for the client that speaks to solitude.
|
||||
# A tuple of the solitude hosts.
|
||||
SOLITUDE_HOSTS = ('',)
|
||||
|
|
|
@ -2,6 +2,7 @@ import os
|
|||
import stat
|
||||
import tempfile
|
||||
|
||||
import pytest
|
||||
from mock import Mock, patch
|
||||
from nose import SkipTest
|
||||
from nose.tools import eq_
|
||||
|
@ -18,6 +19,9 @@ from lib.video import ffmpeg, totem
|
|||
from lib.video.tasks import resize_video
|
||||
from users.models import UserProfile
|
||||
|
||||
|
||||
pytestmark = pytest.mark.django_db
|
||||
|
||||
files = {
|
||||
'good': os.path.join(os.path.dirname(__file__),
|
||||
'fixtures/disco-truncated.webm'),
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
[pytest]
|
||||
addopts = --reuse-db --tb=native
|
||||
python_files=test*.py
|
||||
markers =
|
||||
es_tests: mark a test as an elasticsearch test.
|
|
@ -2,5 +2,11 @@
|
|||
# it is not needed for local testing.
|
||||
-r prod.txt
|
||||
|
||||
psutil==0.2.0
|
||||
execnet==1.2
|
||||
nose-blockage==0.1.2
|
||||
psutil==0.2.0
|
||||
py==1.4.26
|
||||
pytest==2.6.4
|
||||
pytest-cache==1.0
|
||||
pytest-django==2.7.0
|
||||
pytest-xdist==1.11
|
||||
|
|
|
@ -37,26 +37,6 @@ pip install -U --exists-action=w --no-deps -q \
|
|||
-f https://pyrepo.addons.mozilla.org/ \
|
||||
-r requirements/compiled.txt -r requirements/test.txt
|
||||
|
||||
# Create paths we want for addons
|
||||
if [ ! -d "/tmp/warez" ]; then
|
||||
mkdir /tmp/warez
|
||||
fi
|
||||
|
||||
if [ ! -d "$LOCALE" ]; then
|
||||
echo "No locale dir? Cloning..."
|
||||
svn co http://svn.mozilla.org/addons/trunk/site/app/locale/ $LOCALE
|
||||
fi
|
||||
|
||||
# Install node deps locally.
|
||||
npm install
|
||||
export PATH="./node_modules/.bin/:${PATH}"
|
||||
|
||||
if [ -z $SET_ES_TESTS ]; then
|
||||
RUN_ES_TESTS=False
|
||||
else
|
||||
RUN_ES_TESTS=True
|
||||
fi
|
||||
|
||||
cat > local_settings.py <<SETTINGS
|
||||
from settings_ci import *
|
||||
|
||||
|
@ -76,30 +56,10 @@ RUNNING_IN_JENKINS = True
|
|||
|
||||
SETTINGS
|
||||
|
||||
# Update product details to pull in any changes (namely, 'dbg' locale)
|
||||
echo "Updating product details..."
|
||||
python manage.py update_product_details
|
||||
|
||||
|
||||
# Manage statics (collect and compress).
|
||||
echo "collecting statics..." `date`
|
||||
|
||||
python manage.py collectstatic --noinput
|
||||
|
||||
echo "building assets..." `date`
|
||||
|
||||
python manage.py compress_assets
|
||||
|
||||
|
||||
echo "Starting tests..." `date`
|
||||
export FORCE_DB='yes sir'
|
||||
|
||||
if [[ $3 = 'with-coverage' ]]; then
|
||||
coverage run manage.py test -v 2 --noinput --logging-clear-handlers --with-xunit
|
||||
coverage xml $(find apps lib -name '*.py')
|
||||
else
|
||||
python manage.py test -v 2 --noinput --logging-clear-handlers --with-xunit --with-blockage --http-whitelist=127.0.0.1,localhost,${ES_HOST}
|
||||
fi
|
||||
py.test -v
|
||||
|
||||
|
||||
echo "Building documentation..." `date`
|
||||
|
|
|
@ -63,8 +63,6 @@ UGLIFY_BIN = path('node_modules/uglify-js/bin/uglifyjs')
|
|||
# Locally we typically don't run more than 1 elasticsearch node. So we set
|
||||
# replicas to zero.
|
||||
ES_DEFAULT_NUM_REPLICAS = 0
|
||||
# Overload in local_settings.py to run elasticsearch related tests.
|
||||
RUN_ES_TESTS = False
|
||||
|
||||
SITE_URL = 'http://localhost:8000/'
|
||||
SERVICES_DOMAIN = 'localhost:8000'
|
||||
|
|
|
@ -1,4 +1,56 @@
|
|||
import product_details
|
||||
|
||||
from settings import * # noqa
|
||||
|
||||
|
||||
LOG_LEVEL = logging.ERROR
|
||||
RUN_ES_TESTS = True
|
||||
|
||||
|
||||
class MockProductDetails:
|
||||
"""Main information we need in tests.
|
||||
|
||||
We don't want to rely on the product_details that are automatically
|
||||
downloaded in manage.py for the tests. Also, downloading all the
|
||||
information is very long, and we don't want that for each test build on
|
||||
travis for example.
|
||||
|
||||
So here's a Mock that can be used instead of the real product_details.
|
||||
|
||||
"""
|
||||
last_update = False
|
||||
languages = dict((lang, {'native': lang}) for lang in AMO_LANGUAGES)
|
||||
firefox_versions = {"LATEST_FIREFOX_VERSION": "33.1.1"}
|
||||
thunderbird_versions = {"LATEST_THUNDERBIRD_VERSION": "31.2.0"}
|
||||
firefox_history_major_releases = {'1.0': '2004-11-09'}
|
||||
|
||||
def __init__(self):
|
||||
"""Some tests need specifics languages.
|
||||
|
||||
This is an excerpt of lib/product_json/languages.json.
|
||||
|
||||
"""
|
||||
self.languages.update({
|
||||
u'el': {
|
||||
u'native': u'\u0395\u03bb\u03bb\u03b7\u03bd\u03b9\u03ba\u03ac',
|
||||
u'English': u'Greek'},
|
||||
u'hr': {
|
||||
u'native': u'Hrvatski',
|
||||
u'English': u'Croatian'},
|
||||
u'sr': {
|
||||
u'native': u'\u0421\u0440\u043f\u0441\u043a\u0438',
|
||||
u'English': u'Serbian'},
|
||||
u'en-US': {
|
||||
u'native': u'English (US)',
|
||||
u'English': u'English (US)'},
|
||||
u'tr': {
|
||||
u'native': u'T\xfcrk\xe7e',
|
||||
u'English': u'Turkish'},
|
||||
u'cy': {
|
||||
u'native': u'Cymraeg',
|
||||
u'English': u'Welsh'},
|
||||
u'sr-Latn': {
|
||||
u'native': u'Srpski',
|
||||
u'English': u'Serbian'}})
|
||||
|
||||
|
||||
product_details.product_details = MockProductDetails()
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
from distutils.core import setup
|
||||
|
||||
setup(name='Olympia',
|
||||
version='0.1dev',
|
||||
description='This is https://addons.mozilla.org (AMO)',
|
||||
author='The Mozilla Team',
|
||||
author_email='amo-developers@mozilla.org',
|
||||
url='https://addons.mozilla.org/',
|
||||
packages=['apps', 'lib'],
|
||||
classifiers=[
|
||||
'Development Status :: 5 - Production/Stable',
|
||||
'Environment :: Web Environment',
|
||||
'Intended Audience :: End Users/Desktop',
|
||||
'License :: OSI Approved :: Mozilla Public License',
|
||||
'Operating System :: POSIX',
|
||||
'Programming Language :: Python',
|
||||
'Topic :: Internet :: WWW/HTTP :: Browsers',
|
||||
])
|
|
@ -0,0 +1,46 @@
|
|||
[tox]
|
||||
envlist = es, addons-devhub-editors, main, flake8, docs
|
||||
|
||||
[testenv]
|
||||
basepython = python2.6
|
||||
install_command = pip install --no-deps --exists-action=w --download-cache=/tmp/pip-cache --find-links https://pyrepo.addons.mozilla.org/ {opts} {packages}
|
||||
setenv =
|
||||
DJANGO_SETTINGS_MODULE=settings_ci
|
||||
PYTHONPATH=apps
|
||||
DEB_HOST_MULTIARCH=x86_64-linux-gnu # For M2Crypto on linux.
|
||||
whitelist_externals =
|
||||
make
|
||||
|
||||
[base]
|
||||
deps =
|
||||
-rrequirements/dev.txt
|
||||
git+git://anonscm.debian.org/collab-maint/m2crypto.git@debian/0.21.1-3#egg=M2Crypto
|
||||
|
||||
[testenv:es]
|
||||
deps = {[base]deps}
|
||||
commands =
|
||||
py.test -m es_tests -v {posargs}
|
||||
|
||||
[testenv:addons-devhub-editors]
|
||||
deps = {[base]deps}
|
||||
commands =
|
||||
py.test --create-db -m 'not es_tests' -v apps/addons/ apps/devhub/ apps/editors/ {posargs}
|
||||
|
||||
[testenv:main]
|
||||
deps = {[base]deps}
|
||||
commands =
|
||||
py.test --create-db -m 'not es_tests' -v --ignore apps/addons/ --ignore apps/devhub/ --ignore apps/editors/ {posargs}
|
||||
|
||||
[testenv:flake8]
|
||||
deps =
|
||||
flake8
|
||||
mccabe
|
||||
pep8
|
||||
pyflakes
|
||||
commands = make flake8
|
||||
|
||||
[testenv:docs]
|
||||
deps =
|
||||
-rrequirements/compiled.txt
|
||||
-rrequirements/docs.txt
|
||||
commands = make docs SPHINXOPTS='-nW'
|
|
@ -1 +0,0 @@
|
|||
mkt.wsgi
|
Загрузка…
Ссылка в новой задаче