Move routing configuration to main.py. (#1552)

* Move routing configuration to main.py.

* inline_file works so we dont need this directive

* rebased

* Removed __future__s
This commit is contained in:
Jason Robbins 2021-09-23 13:01:43 -07:00 коммит произвёл GitHub
Родитель 84e42f798a
Коммит 527c49abed
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
38 изменённых файлов: 366 добавлений и 500 удалений

Просмотреть файл

@ -23,9 +23,10 @@ import mock
import werkzeug.exceptions # Flask HTTP stuff.
from api import accounts_api
from api import register
from internals import models
test_app = flask.Flask(__name__)
class AccountsAPITest(testing_config.CustomTestCase):
@ -49,7 +50,7 @@ class AccountsAPITest(testing_config.CustomTestCase):
testing_config.sign_in('admin@example.com', 123567890)
json_data = {'email': 'new@example.com', 'isAdmin': False}
with register.app.test_request_context(self.request_path, json=json_data):
with test_app.test_request_context(self.request_path, json=json_data):
actual_json = self.handler.do_post()
self.assertEqual('new@example.com', actual_json['email'])
self.assertFalse(actual_json['is_admin'])
@ -64,7 +65,7 @@ class AccountsAPITest(testing_config.CustomTestCase):
testing_config.sign_in('admin@example.com', 123567890)
json_data = {'email': 'new_admin@example.com', 'isAdmin': True}
with register.app.test_request_context(self.request_path, json=json_data):
with test_app.test_request_context(self.request_path, json=json_data):
actual_json = self.handler.do_post()
self.assertEqual('new_admin@example.com', actual_json['email'])
self.assertTrue(actual_json['is_admin'])
@ -78,7 +79,7 @@ class AccountsAPITest(testing_config.CustomTestCase):
"""Regular user cannot create an account."""
testing_config.sign_in('one@example.com', 123567890)
with register.app.test_request_context(self.request_path):
with test_app.test_request_context(self.request_path):
with self.assertRaises(werkzeug.exceptions.Forbidden):
self.handler.do_post(self.appuser_id)
@ -91,7 +92,7 @@ class AccountsAPITest(testing_config.CustomTestCase):
testing_config.sign_in('admin@example.com', 123567890)
json_data = {'isAdmin': False} # No email
with register.app.test_request_context(self.request_path, json=json_data):
with test_app.test_request_context(self.request_path, json=json_data):
with self.assertRaises(werkzeug.exceptions.BadRequest):
self.handler.do_post()
@ -104,7 +105,7 @@ class AccountsAPITest(testing_config.CustomTestCase):
testing_config.sign_in('admin@example.com', 123567890)
json_data = {'email': 'user@example.com'}
with register.app.test_request_context(self.request_path, json=json_data):
with test_app.test_request_context(self.request_path, json=json_data):
with self.assertRaises(werkzeug.exceptions.BadRequest):
self.handler.do_post()
@ -115,7 +116,7 @@ class AccountsAPITest(testing_config.CustomTestCase):
"""Admin wants to delete an account."""
testing_config.sign_in('admin@example.com', 123567890)
with register.app.test_request_context(self.request_path):
with test_app.test_request_context(self.request_path):
actual_json = self.handler.do_delete(self.appuser_id)
self.assertEqual({'message': 'Done'}, actual_json)
@ -126,7 +127,7 @@ class AccountsAPITest(testing_config.CustomTestCase):
"""Regular user cannot delete an account."""
testing_config.sign_in('one@example.com', 123567890)
with register.app.test_request_context(self.request_path):
with test_app.test_request_context(self.request_path):
with self.assertRaises(werkzeug.exceptions.Forbidden):
self.handler.do_delete(self.appuser_id)
@ -137,7 +138,7 @@ class AccountsAPITest(testing_config.CustomTestCase):
"""We cannot delete an account without an account_id."""
testing_config.sign_in('admin@example.com', 123567890)
with register.app.test_request_context(self.request_path):
with test_app.test_request_context(self.request_path):
with self.assertRaises(werkzeug.exceptions.BadRequest):
self.handler.do_delete(None)
@ -149,7 +150,7 @@ class AccountsAPITest(testing_config.CustomTestCase):
"""We cannot delete an account with the wrong account_id."""
testing_config.sign_in('admin@example.com', 123567890)
with register.app.test_request_context(self.request_path):
with test_app.test_request_context(self.request_path):
with self.assertRaises(werkzeug.exceptions.NotFound):
self.handler.do_delete(self.appuser_id + 1)

Просмотреть файл

@ -22,10 +22,10 @@ import flask
import mock
import werkzeug.exceptions # Flask HTTP stuff.
from api import register
from api import approvals_api
from internals import models
test_app = flask.Flask(__name__)
NOW = datetime.datetime.now()
@ -74,7 +74,7 @@ class ApprovalsAPITest(testing_config.CustomTestCase):
def test_get__all_empty(self):
"""We can get all approvals for a given feature, even if there none."""
testing_config.sign_out()
with register.app.test_request_context(self.request_path):
with test_app.test_request_context(self.request_path):
actual_response = self.handler.do_get(self.feature_id)
self.assertEqual({"approvals": []}, actual_response)
@ -84,7 +84,7 @@ class ApprovalsAPITest(testing_config.CustomTestCase):
self.appr_1_1.put()
self.appr_1_2.put()
with register.app.test_request_context(self.request_path):
with test_app.test_request_context(self.request_path):
actual_response = self.handler.do_get(self.feature_id)
self.assertEqual(
@ -94,7 +94,7 @@ class ApprovalsAPITest(testing_config.CustomTestCase):
def test_get__field_empty(self):
"""We can get approvals for given feature and field, even if there none."""
testing_config.sign_out()
with register.app.test_request_context(self.request_path + '/1'):
with test_app.test_request_context(self.request_path + '/1'):
actual_response = self.handler.do_get(self.feature_id, field_id=1)
self.assertEqual({"approvals": []}, actual_response)
@ -104,7 +104,7 @@ class ApprovalsAPITest(testing_config.CustomTestCase):
self.appr_1_1.put()
self.appr_1_2.put()
with register.app.test_request_context(self.request_path + '/1'):
with test_app.test_request_context(self.request_path + '/1'):
actual_response = self.handler.do_get(self.feature_id, field_id=1)
self.assertEqual(
@ -114,48 +114,48 @@ class ApprovalsAPITest(testing_config.CustomTestCase):
def test_post__bad_feature_id(self):
"""Handler rejects requests that don't specify a feature ID correctly."""
params = {}
with register.app.test_request_context(self.request_path, json=params):
with test_app.test_request_context(self.request_path, json=params):
with self.assertRaises(werkzeug.exceptions.BadRequest):
self.handler.do_post()
params = {'featureId': 'not an int'}
with register.app.test_request_context(self.request_path, json=params):
with test_app.test_request_context(self.request_path, json=params):
with self.assertRaises(werkzeug.exceptions.BadRequest):
self.handler.do_post()
def test_post__bad_field_id(self):
"""Handler rejects requests that don't specify a field ID correctly."""
params = {'featureId': self.feature_id}
with register.app.test_request_context(self.request_path, json=params):
with test_app.test_request_context(self.request_path, json=params):
with self.assertRaises(werkzeug.exceptions.BadRequest):
self.handler.do_post()
params = {'featureId': self.feature_id, 'fieldId': 'not an int'}
with register.app.test_request_context(self.request_path, json=params):
with test_app.test_request_context(self.request_path, json=params):
with self.assertRaises(werkzeug.exceptions.BadRequest):
self.handler.do_post()
params = {'featureId': self.feature_id, 'fieldId': 999}
with register.app.test_request_context(self.request_path, json=params):
with test_app.test_request_context(self.request_path, json=params):
with self.assertRaises(werkzeug.exceptions.BadRequest):
self.handler.do_post()
def test_post__bad_state(self):
"""Handler rejects requests that don't specify a state correctly."""
params = {'featureId': self.feature_id, 'fieldId': 1}
with register.app.test_request_context(self.request_path, json=params):
with test_app.test_request_context(self.request_path, json=params):
with self.assertRaises(werkzeug.exceptions.BadRequest):
self.handler.do_post()
params = {'featureId': self.feature_id, 'fieldId': 1,
'state': 'not an int'}
with register.app.test_request_context(self.request_path, json=params):
with test_app.test_request_context(self.request_path, json=params):
with self.assertRaises(werkzeug.exceptions.BadRequest):
self.handler.do_post()
params = {'featureId': self.feature_id, 'fieldId': 1,
'state': 999}
with register.app.test_request_context(self.request_path, json=params):
with test_app.test_request_context(self.request_path, json=params):
with self.assertRaises(werkzeug.exceptions.BadRequest):
self.handler.do_post()
@ -163,7 +163,7 @@ class ApprovalsAPITest(testing_config.CustomTestCase):
"""Handler rejects requests that don't match an existing feature."""
params = {'featureId': 12345, 'fieldId': 1,
'state': models.Approval.NEED_INFO }
with register.app.test_request_context(self.request_path, json=params):
with test_app.test_request_context(self.request_path, json=params):
with self.assertRaises(werkzeug.exceptions.NotFound):
self.handler.do_post()
@ -175,17 +175,17 @@ class ApprovalsAPITest(testing_config.CustomTestCase):
'state': models.Approval.NEED_INFO}
testing_config.sign_out()
with register.app.test_request_context(self.request_path, json=params):
with test_app.test_request_context(self.request_path, json=params):
with self.assertRaises(werkzeug.exceptions.Forbidden):
self.handler.do_post()
testing_config.sign_in('user7@example.com', 123567890)
with register.app.test_request_context(self.request_path, json=params):
with test_app.test_request_context(self.request_path, json=params):
with self.assertRaises(werkzeug.exceptions.Forbidden):
self.handler.do_post()
testing_config.sign_in('user@google.com', 123567890)
with register.app.test_request_context(self.request_path, json=params):
with test_app.test_request_context(self.request_path, json=params):
with self.assertRaises(werkzeug.exceptions.Forbidden):
self.handler.do_post()
@ -196,7 +196,7 @@ class ApprovalsAPITest(testing_config.CustomTestCase):
testing_config.sign_in('owner1@example.com', 123567890)
params = {'featureId': self.feature_id, 'fieldId': 1,
'state': models.Approval.NEED_INFO}
with register.app.test_request_context(self.request_path, json=params):
with test_app.test_request_context(self.request_path, json=params):
actual = self.handler.do_post()
self.assertEqual(actual, {'message': 'Done'})
@ -206,4 +206,4 @@ class ApprovalsAPITest(testing_config.CustomTestCase):
self.assertEqual(appr.feature_id, self.feature_id)
self.assertEqual(appr.field_id, 1)
self.assertEqual(appr.set_by, 'owner1@example.com')
self.assertEqual(appr.state, models.Approval.NEED_INFO)
self.assertEqual(appr.state, models.Approval.NEED_INFO)

Просмотреть файл

@ -23,10 +23,10 @@ import flask
import mock
import werkzeug.exceptions # Flask HTTP stuff.
from api import register
from api import comments_api
from internals import models
test_app = flask.Flask(__name__)
NOW = datetime.datetime.now()
@ -77,7 +77,7 @@ class CommentsAPITest(testing_config.CustomTestCase):
def test_get__empty(self):
"""We can get comments for a given approval, even if there none."""
testing_config.sign_out()
with register.app.test_request_context(self.request_path):
with test_app.test_request_context(self.request_path):
actual_response = self.handler.do_get(self.feature_id, self.field_id)
self.assertEqual({'comments': []}, actual_response)
@ -86,7 +86,7 @@ class CommentsAPITest(testing_config.CustomTestCase):
testing_config.sign_out()
self.cmnt_1_1.put()
with register.app.test_request_context(self.request_path):
with test_app.test_request_context(self.request_path):
actual_response = self.handler.do_get(self.feature_id, self.field_id)
actual_comment = actual_response['comments'][0]
@ -98,12 +98,12 @@ class CommentsAPITest(testing_config.CustomTestCase):
def test_post__bad_state(self):
"""Handler rejects requests that don't specify a state correctly."""
params = {'state': 'not an int'}
with register.app.test_request_context(self.request_path, json=params):
with test_app.test_request_context(self.request_path, json=params):
with self.assertRaises(werkzeug.exceptions.BadRequest):
self.handler.do_post(self.feature_id, self.field_id)
params = {'state': 999}
with register.app.test_request_context(self.request_path, json=params):
with test_app.test_request_context(self.request_path, json=params):
with self.assertRaises(werkzeug.exceptions.BadRequest):
self.handler.do_post(self.feature_id, self.field_id)
@ -111,7 +111,7 @@ class CommentsAPITest(testing_config.CustomTestCase):
"""Handler rejects requests that don't match an existing feature."""
bad_path = '/api/v0/features/12345/approvals/1/comments'
params = {'state': models.Approval.NEED_INFO }
with register.app.test_request_context(bad_path, json=params):
with test_app.test_request_context(bad_path, json=params):
with self.assertRaises(werkzeug.exceptions.NotFound):
self.handler.do_post(12345, self.field_id)
@ -122,17 +122,17 @@ class CommentsAPITest(testing_config.CustomTestCase):
params = {'state': models.Approval.NEED_INFO}
testing_config.sign_out()
with register.app.test_request_context(self.request_path, json=params):
with test_app.test_request_context(self.request_path, json=params):
with self.assertRaises(werkzeug.exceptions.Forbidden):
self.handler.do_post(self.feature_id, self.field_id)
testing_config.sign_in('user7@example.com', 123567890)
with register.app.test_request_context(self.request_path, json=params):
with test_app.test_request_context(self.request_path, json=params):
with self.assertRaises(werkzeug.exceptions.Forbidden):
self.handler.do_post(self.feature_id, self.field_id)
testing_config.sign_in('user@google.com', 123567890)
with register.app.test_request_context(self.request_path, json=params):
with test_app.test_request_context(self.request_path, json=params):
with self.assertRaises(werkzeug.exceptions.Forbidden):
self.handler.do_post(self.feature_id, self.field_id)
@ -142,7 +142,7 @@ class CommentsAPITest(testing_config.CustomTestCase):
mock_get_approvers.return_value = ['owner1@example.com']
testing_config.sign_in('owner1@example.com', 123567890)
params = {'state': models.Approval.NEED_INFO}
with register.app.test_request_context(self.request_path, json=params):
with test_app.test_request_context(self.request_path, json=params):
actual = self.handler.do_post(self.feature_id, self.field_id)
self.assertEqual(actual, {'message': 'Done'})
@ -166,7 +166,7 @@ class CommentsAPITest(testing_config.CustomTestCase):
mock_get_approvers.return_value = []
testing_config.sign_in('owner2@example.com', 123567890)
params = {'comment': 'Congratulations'}
with register.app.test_request_context(self.request_path, json=params):
with test_app.test_request_context(self.request_path, json=params):
actual = self.handler.do_post(self.feature_id, self.field_id)
self.assertEqual(actual, {'message': 'Done'})
@ -182,4 +182,4 @@ class CommentsAPITest(testing_config.CustomTestCase):
cmnt = updated_comments[0]
self.assertEqual('Congratulations', cmnt.content)
self.assertIsNone(cmnt.old_approval_state)
self.assertIsNone(cmnt.new_approval_state)
self.assertIsNone(cmnt.new_approval_state)

Просмотреть файл

@ -22,9 +22,10 @@ import mock
import werkzeug.exceptions # Flask HTTP stuff.
from api import cues_api
from api import register
from internals import models
test_app = flask.Flask(__name__)
class CuesAPITest(testing_config.CustomTestCase):
@ -42,7 +43,7 @@ class CuesAPITest(testing_config.CustomTestCase):
"""User wants to dismiss a valid cue card ID."""
testing_config.sign_in('one@example.com', 123567890)
with register.app.test_request_context(
with test_app.test_request_context(
'/cues/dismiss', json={"cue": "progress-checkmarks"}):
actual_json = self.handler.do_post()
self.assertEqual({'message': 'Done'}, actual_json)
@ -54,11 +55,11 @@ class CuesAPITest(testing_config.CustomTestCase):
"""User wants to dismiss an invalid cue card ID."""
testing_config.sign_in('one@example.com', 123567890)
with register.app.test_request_context(
with test_app.test_request_context(
'/cues/dismiss', json={"cue": "xyz"}):
with self.assertRaises(werkzeug.exceptions.BadRequest):
self.handler.do_post()
# The invalid string should not be added.
revised_user_pref = models.UserPref.get_signed_in_user_pref()
self.assertEqual([], revised_user_pref.dismissed_cues)
self.assertEqual([], revised_user_pref.dismissed_cues)

Просмотреть файл

@ -22,10 +22,11 @@ import mock
import werkzeug.exceptions # Flask HTTP stuff.
from api import features_api
from api import register
from internals import models
from framework import ramcache
test_app = flask.Flask(__name__)
class FeaturesAPITestDelete(testing_config.CustomTestCase):
@ -55,7 +56,7 @@ class FeaturesAPITestDelete(testing_config.CustomTestCase):
"""Admin wants to soft-delete a feature."""
testing_config.sign_in('admin@example.com', 123567890)
with register.app.test_request_context(self.request_path):
with test_app.test_request_context(self.request_path):
actual_json = self.handler.do_delete(self.feature_id)
self.assertEqual({'message': 'Done'}, actual_json)
@ -66,7 +67,7 @@ class FeaturesAPITestDelete(testing_config.CustomTestCase):
"""Regular user cannot soft-delete a feature."""
testing_config.sign_in('one@example.com', 123567890)
with register.app.test_request_context(self.request_path):
with test_app.test_request_context(self.request_path):
with self.assertRaises(werkzeug.exceptions.Forbidden):
self.handler.do_delete(self.feature_id)
@ -77,7 +78,7 @@ class FeaturesAPITestDelete(testing_config.CustomTestCase):
"""We cannot soft-delete a feature without a feature_id."""
testing_config.sign_in('admin@example.com', 123567890)
with register.app.test_request_context(self.request_path):
with test_app.test_request_context(self.request_path):
with self.assertRaises(werkzeug.exceptions.BadRequest):
self.handler.do_delete(None)
@ -88,7 +89,7 @@ class FeaturesAPITestDelete(testing_config.CustomTestCase):
"""We cannot soft-delete a feature with the wrong feature_id."""
testing_config.sign_in('admin@example.com', 123567890)
with register.app.test_request_context(self.request_path):
with test_app.test_request_context(self.request_path):
with self.assertRaises(werkzeug.exceptions.NotFound):
self.handler.do_delete(self.feature_id + 1)
@ -122,7 +123,7 @@ class FeaturesAPITestGet(testing_config.CustomTestCase):
def test_get__all_listed(self):
"""Get all features that are listed."""
with register.app.test_request_context(self.request_path):
with test_app.test_request_context(self.request_path):
actual_response = self.handler.do_get()
# Comparing only the total number of features and name of the feature
@ -136,13 +137,13 @@ class FeaturesAPITestGet(testing_config.CustomTestCase):
self.feature_1.put()
# No signed-in user
with register.app.test_request_context(self.request_path):
with test_app.test_request_context(self.request_path):
actual_response = self.handler.do_get()
self.assertEqual(0, len(actual_response))
# Signed-in user with no permissions
testing_config.sign_in('one@example.com', 123567890)
with register.app.test_request_context(self.request_path):
with test_app.test_request_context(self.request_path):
actual_response = self.handler.do_get()
self.assertEqual(0, len(actual_response))
@ -153,7 +154,7 @@ class FeaturesAPITestGet(testing_config.CustomTestCase):
# Signed-in user with permissions
testing_config.sign_in('admin@example.com', 123567890)
with register.app.test_request_context(self.request_path):
with test_app.test_request_context(self.request_path):
actual_response = self.handler.do_get()
self.assertEqual(1, len(actual_response))
self.assertEqual('feature one', actual_response[0]['name'])
@ -161,13 +162,13 @@ class FeaturesAPITestGet(testing_config.CustomTestCase):
def test_get__in_milestone_listed(self):
"""Get all features in a specific milestone that are listed."""
# Atleast one feature is present in milestone
with register.app.test_request_context(self.request_path+'?milestone=1'):
with test_app.test_request_context(self.request_path+'?milestone=1'):
actual_response = self.handler.do_get()
self.assertEqual(6, len(actual_response))
self.assertEqual(1, len(actual_response['Enabled by default']))
# No Feature is present in milestone
with register.app.test_request_context(self.request_path+'?milestone=2'):
with test_app.test_request_context(self.request_path+'?milestone=2'):
actual_response = self.handler.do_get()
self.assertEqual(6, len(actual_response))
self.assertEqual(0, len(actual_response['Enabled by default']))
@ -178,14 +179,14 @@ class FeaturesAPITestGet(testing_config.CustomTestCase):
self.feature_1.put()
# No signed-in user
with register.app.test_request_context(self.request_path+'?milestone=1'):
with test_app.test_request_context(self.request_path+'?milestone=1'):
actual_response = self.handler.do_get()
self.assertEqual(6, len(actual_response))
self.assertEqual(0, len(actual_response['Enabled by default']))
# Signed-in user with no permissions
testing_config.sign_in('one@example.com', 123567890)
with register.app.test_request_context(self.request_path+'?milestone=1'):
with test_app.test_request_context(self.request_path+'?milestone=1'):
actual_response = self.handler.do_get()
self.assertEqual(6, len(actual_response))
self.assertEqual(0, len(actual_response['Enabled by default']))
@ -199,13 +200,13 @@ class FeaturesAPITestGet(testing_config.CustomTestCase):
testing_config.sign_in('admin@example.com', 123567890)
# Feature is present in milestone
with register.app.test_request_context(self.request_path+'?milestone=1'):
with test_app.test_request_context(self.request_path+'?milestone=1'):
actual_response = self.handler.do_get()
self.assertEqual(6, len(actual_response))
self.assertEqual(1, len(actual_response['Enabled by default']))
# Feature is not present in milestone
with register.app.test_request_context(self.request_path+'?milestone=2'):
with test_app.test_request_context(self.request_path+'?milestone=2'):
actual_response = self.handler.do_get()
self.assertEqual(6, len(actual_response))
self.assertEqual(0, len(actual_response['Enabled by default']))
@ -215,7 +216,7 @@ class FeaturesAPITestGet(testing_config.CustomTestCase):
"""Invalid value of milestone should not be processed."""
# Feature is present in milestone
with register.app.test_request_context(
self.request_path + '?milestone=chromium'):
with test_app.test_request_context(
self.request_path+'?milestone=chromium'):
actual_response = self.handler.do_get()
mock_abort.assert_called_once_with(400, description='Invalid Milestone')

Просмотреть файл

@ -28,12 +28,10 @@ from framework import users
from framework import basehandlers
from internals import models
from framework import ramcache
import settings
CACHE_AGE = 86400 # 24hrs
def _truncate_day_percentage(datapoint):
# Need 8 decimals b/c num will by multiplied by 100 to get a percentage and
# we want 6 decimals.
@ -247,14 +245,3 @@ class FeatureBucketsHandler(basehandlers.FlaskHandler):
models.FeatureObserverHistogram.get_all().items(), key=lambda x:x[1])
return properties
app = basehandlers.FlaskApplication([
('/data/timeline/cssanimated', AnimatedTimelineHandler),
('/data/timeline/csspopularity', PopularityTimelineHandler),
('/data/timeline/featurepopularity', FeatureObserverTimelineHandler),
('/data/csspopularity', CSSPopularityHandler),
('/data/cssanimated', CSSAnimatedHandler),
('/data/featurepopularity', FeatureObserverPopularityHandler),
('/data/blink/<string:prop_type>', FeatureBucketsHandler),
], debug=settings.DEBUG)

Просмотреть файл

@ -27,6 +27,8 @@ from framework import users
from api import metricsdata
from internals import models
test_app = flask.Flask(__name__)
class MetricsFunctionTests(testing_config.CustomTestCase):
@ -85,14 +87,14 @@ class PopularityTimelineHandlerTests(testing_config.CustomTestCase):
def test_get_template_data__bad_bucket(self):
url = '/data/timeline/csspopularity?bucket_id=not-a-number'
with metricsdata.app.test_request_context(url):
with test_app.test_request_context(url):
actual = self.handler.get_template_data()
self.assertEqual([], actual)
def test_get_template_data__normal(self):
testing_config.sign_out()
url = '/data/timeline/csspopularity?bucket_id=1'
with metricsdata.app.test_request_context(url):
with test_app.test_request_context(url):
actual_datapoints = self.handler.get_template_data()
self.assertEqual(1, len(actual_datapoints))
self.assertEqual(0.01234568, actual_datapoints[0]['day_percentage'])
@ -125,15 +127,15 @@ class FeatureBucketsHandlerTest(testing_config.CustomTestCase):
self.prop_4.key.delete()
def test_get_template_data__css(self):
with metricsdata.app.test_request_context('/data/blink/cssprops'):
with test_app.test_request_context('/data/blink/cssprops'):
actual_buckets = self.handler.get_template_data('cssprops')
self.assertEqual(
[(2, 'a prop'), (1, 'b prop')],
actual_buckets)
def test_get_template_data__js(self):
with metricsdata.app.test_request_context('/data/blink/features'):
with test_app.test_request_context('/data/blink/features'):
actual_buckets = self.handler.get_template_data('features')
self.assertEqual(
[(4, 'a feat'), (3, 'b feat')],
actual_buckets)
actual_buckets)

Просмотреть файл

@ -1,64 +0,0 @@
# -*- coding: utf-8 -*-
# Copyright 2021 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License")
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import settings
from api import accounts_api
from api import approvals_api
from api import comments_api
from api import cues_api
from api import features_api
from api import stars_api
from api import token_refresh_api
from api import channels_api
from framework import basehandlers
from api import login_api
from api import logout_api
# TODO(jrobbins): Advance this to v1 once we have it fleshed out
API_BASE = '/api/v0'
app = basehandlers.FlaskApplication([
('/features', features_api.FeaturesAPI),
('/features/<int:feature_id>', features_api.FeaturesAPI),
('/features/<int:feature_id>/approvals/<int:field_id>',
approvals_api.ApprovalsAPI),
('/features/<int:feature_id>/approvals/<int:field_id>/comments',
comments_api.CommentsAPI),
('/login', login_api.LoginAPI),
('/logout', logout_api.LogoutAPI),
('/currentuser/stars', stars_api.StarsAPI),
('/currentuser/cues', cues_api.CuesAPI),
('/currentuser/token', token_refresh_api.TokenRefreshAPI),
# ('/currentuser/autosaves', TODO),
# ('/currentuser/settings', TODO),
# Admin operations for user accounts
('/accounts', accounts_api.AccountsAPI),
('/accounts/<int:account_id>', accounts_api.AccountsAPI),
('/channels', channels_api.ChannelsAPI), # omaha data
# ('/schedule', TODO), # chromiumdash data
# ('/metrics/<str:kind>', TODO), # uma-export data
# ('/metrics/<str:kind>/<int:bucket_id>', TODO),
],
pattern_base=API_BASE,
debug=settings.DEBUG)

Просмотреть файл

@ -21,11 +21,11 @@ import flask
import mock
import werkzeug.exceptions # Flask HTTP stuff.
from api import register
from api import stars_api
from internals import models
from internals import notifier
test_app = flask.Flask(__name__)
class StarsAPITest(testing_config.CustomTestCase):
@ -46,14 +46,14 @@ class StarsAPITest(testing_config.CustomTestCase):
def test_get__anon(self):
"""Anon should always have an empty list of stars."""
testing_config.sign_out()
with register.app.test_request_context(self.request_path):
with test_app.test_request_context(self.request_path):
actual_response = self.handler.do_get()
self.assertEqual({"featureIds": []}, actual_response)
def test_get__no_stars(self):
"""User has not starred any features."""
testing_config.sign_in('user7@example.com', 123567890)
with register.app.test_request_context(self.request_path):
with test_app.test_request_context(self.request_path):
actual_response = self.handler.do_get()
self.assertEqual({"featureIds": []}, actual_response)
@ -63,7 +63,7 @@ class StarsAPITest(testing_config.CustomTestCase):
feature_1_id = self.feature_1.key.integer_id()
testing_config.sign_in(email, 123567890)
notifier.FeatureStar.set_star(email, feature_1_id)
with register.app.test_request_context(self.request_path):
with test_app.test_request_context(self.request_path):
actual_response = self.handler.do_get()
self.assertEqual(
{"featureIds": [feature_1_id]},
@ -72,19 +72,19 @@ class StarsAPITest(testing_config.CustomTestCase):
def test_post__invalid_feature_id(self):
"""We reject star requests that don't have an int featureId."""
params = {}
with register.app.test_request_context(self.request_path, json=params):
with test_app.test_request_context(self.request_path, json=params):
with self.assertRaises(werkzeug.exceptions.BadRequest):
self.handler.do_post()
params = {"featureId": "not an int"}
with register.app.test_request_context(self.request_path, json=params):
with test_app.test_request_context(self.request_path, json=params):
with self.assertRaises(werkzeug.exceptions.BadRequest):
self.handler.do_post()
def test_post__feature_id_not_found(self):
"""We reject star requests for features that don't exist."""
params = {"featureId": 999}
with register.app.test_request_context(self.request_path, json=params):
with test_app.test_request_context(self.request_path, json=params):
with self.assertRaises(werkzeug.exceptions.NotFound):
self.handler.do_post()
@ -93,7 +93,7 @@ class StarsAPITest(testing_config.CustomTestCase):
feature_id = self.feature_1.key.integer_id()
params = {"featureId": feature_id}
testing_config.sign_out()
with register.app.test_request_context(self.request_path, json=params):
with test_app.test_request_context(self.request_path, json=params):
with self.assertRaises(werkzeug.exceptions.Forbidden):
self.handler.do_post()
@ -103,24 +103,24 @@ class StarsAPITest(testing_config.CustomTestCase):
feature_id = self.feature_1.key.integer_id()
params = {"featureId": feature_id}
with register.app.test_request_context(self.request_path, json=params):
with test_app.test_request_context(self.request_path, json=params):
self.handler.do_post() # Original request
updated_feature = models.Feature.get_by_id(feature_id)
self.assertEqual(1, updated_feature.star_count)
with register.app.test_request_context(self.request_path, json=params):
with test_app.test_request_context(self.request_path, json=params):
self.handler.do_post() # Duplicate request
updated_feature = models.Feature.get_by_id(feature_id)
self.assertEqual(1, updated_feature.star_count) # Still 1, not 2.
params = {"featureId": feature_id, "starred": False}
with register.app.test_request_context(self.request_path, json=params):
with test_app.test_request_context(self.request_path, json=params):
self.handler.do_post() # Original request
updated_feature = models.Feature.get_by_id(feature_id)
self.assertEqual(0, updated_feature.star_count)
with register.app.test_request_context(self.request_path, json=params):
with test_app.test_request_context(self.request_path, json=params):
self.handler.do_post() # Duplicate request
updated_feature = models.Feature.get_by_id(feature_id)
self.assertEqual(0, updated_feature.star_count) # Still 0, not negative.
@ -133,7 +133,7 @@ class StarsAPITest(testing_config.CustomTestCase):
# User never stars the feature in the first place.
params = {"featureId": feature_id, "starred": False}
with register.app.test_request_context(self.request_path, json=params):
with test_app.test_request_context(self.request_path, json=params):
self.handler.do_post() # Out-of-step request
updated_feature = models.Feature.get_by_id(feature_id)
self.assertEqual(0, updated_feature.star_count) # Still 0, not negative.
@ -144,13 +144,13 @@ class StarsAPITest(testing_config.CustomTestCase):
feature_id = self.feature_1.key.integer_id()
params = {"featureId": feature_id}
with register.app.test_request_context(self.request_path, json=params):
with test_app.test_request_context(self.request_path, json=params):
self.handler.do_post()
updated_feature = models.Feature.get_by_id(feature_id)
self.assertEqual(1, updated_feature.star_count)
params = {"featureId": feature_id, "starred": False}
with register.app.test_request_context(self.request_path, json=params):
with test_app.test_request_context(self.request_path, json=params):
self.handler.do_post()
updated_feature = models.Feature.get_by_id(feature_id)
self.assertEqual(0, updated_feature.star_count)
self.assertEqual(0, updated_feature.star_count)

Просмотреть файл

@ -21,10 +21,10 @@ import flask
import mock
import werkzeug.exceptions # Flask HTTP stuff.
from api import register
from api import token_refresh_api
from framework import xsrf
test_app = flask.Flask(__name__)
class TokenRefreshAPITest(testing_config.CustomTestCase):
@ -43,7 +43,7 @@ class TokenRefreshAPITest(testing_config.CustomTestCase):
def test_do_get(self):
"""This handler does not respond to GET requests."""
with register.app.test_request_context(self.request_path):
with test_app.test_request_context(self.request_path):
with self.assertRaises(NotImplementedError):
self.handler.do_get()
@ -51,7 +51,7 @@ class TokenRefreshAPITest(testing_config.CustomTestCase):
"""We reject token requests from signed out users."""
testing_config.sign_out()
params = {}
with register.app.test_request_context(self.request_path, json=params):
with test_app.test_request_context(self.request_path, json=params):
with self.assertRaises(werkzeug.exceptions.Forbidden):
self.handler.post()
@ -59,7 +59,7 @@ class TokenRefreshAPITest(testing_config.CustomTestCase):
"""We reject token requests that do not include a previous token."""
testing_config.sign_in('user@example.com', 111)
params = {}
with register.app.test_request_context(self.request_path, json=params):
with test_app.test_request_context(self.request_path, json=params):
with self.assertRaises(werkzeug.exceptions.BadRequest):
self.handler.post()
@ -69,7 +69,7 @@ class TokenRefreshAPITest(testing_config.CustomTestCase):
testing_config.sign_in('user@example.com', 111)
mock_validate_token.side_effect = xsrf.TokenIncorrect()
params = {'token': 'bad'}
with register.app.test_request_context(self.request_path, json=params):
with test_app.test_request_context(self.request_path, json=params):
with self.assertRaises(werkzeug.exceptions.BadRequest):
self.handler.post()
mock_validate_token.assert_called_once()
@ -78,7 +78,7 @@ class TokenRefreshAPITest(testing_config.CustomTestCase):
"""If the request is accepted, we return a new token."""
testing_config.sign_in('user@example.com', 111)
params = {'token': 'checked in base class'}
with register.app.test_request_context(self.request_path, json=params):
with test_app.test_request_context(self.request_path, json=params):
actual = self.handler.do_post()
self.assertIn('token', actual)
self.assertIn('token_expires_sec', actual)
self.assertIn('token_expires_sec', actual)

Просмотреть файл

@ -1,5 +1,5 @@
# TODO(jrobbins): This GAE service will eventually be almost emptied
# out as most handlers are moved over to app-p3.yaml.
# This GAE service only contains email related handlers because those
# require py2. Everything else is routed through app-py3.yaml.
runtime: python27
threadsafe: false
@ -17,35 +17,6 @@ builtins:
handlers:
# Static handlers ---------------------------------------------------------------
- url: /favicon\.ico
static_files: static/img/chromium-128.png
upload: static/img/chromium-128\.png
secure: always
- url: /robots\.txt
static_files: static/robots.txt
upload: static/robots\.txt
secure: always
- url: /static
static_dir: static
#expiration: 30s
application_readable: true # So static assets can be read by inline_file django tag.
http_headers:
Access-Control-Allow-Origin: "*"
secure: always
# Metrics data handlers --------------------------------------------------------
- url: /data/.*
script: api.metricsdata.app
secure: always
# Admin ------------------------------------------------------------------------
- url: /cron/.*
script: internals.fetchmetrics.app
# Any cron job must be harmless if it is called too often or with bad args
# Note: This handler must remain in this file because it requires GAE py2.
- url: /tasks/outbound-email
script: internals.sendemail.app
@ -57,79 +28,6 @@ handlers:
script: internals.sendemail.app
login: admin # Prevents raw access to this handler.
- url: /admin/blink.*
script: pages.blink_handler.app
secure: always
- url: /admin/subscribers
script: pages.blink_handler.app
secure: always
- url: /admin/features/.*
script: pages.intentpreview.app
secure: always
- url: /guide/.*
script: pages.guide.app
secure: always
- url: /admin/users/.*
script: pages.users.app
secure: always
- url: /settings
script: pages.users.app
secure: always
# Main server handlers ---------------------------------------------------------
- url: /
script: pages.featurelist.app
secure: always
- url: /roadmap
script: pages.roadmap.app
secure: always
- url: /features/schedule
script: pages.schedule.app
secure: always
- url: /features.*
script: pages.featurelist.app
secure: always
- url: /feature/.*
script: pages.featuredetail.app
secure: always
- url: /myfeatures
script: pages.myfeatures.app
secure: always
- url: /samples.*
script: pages.samples.app
secure: always
- url: /metrics.*
script: pages.metrics.app
secure: always
- url: /omaha_data
script: pages.metrics.app
secure: always
- url: /api/.*
script: api.register.app
secure: always
- url: /csp
script: framework.csp.app
secure: always
includes:
- env_vars.yaml
inbound_services:
- mail
- mail_bounce
@ -139,6 +37,3 @@ libraries:
version: 1.0.0
- name: ssl
version: latest
env_variables:
GAE_USE_SOCKETS_HTTPLIB : ''

Просмотреть файл

@ -1,9 +1,32 @@
# TODO(jrobbins): This file is not used yet.
# It will contain lines to configure a GAE service running in py3.
# This GAE service contains most of the app, including all UI pages.
runtime: python39
service: app-py3
handlers:
- url: /hello
# Static handlers ---------------------------------------------------------------
- url: /favicon\.ico
static_files: static/img/chromium-128.png
upload: static/img/chromium-128\.png
secure: always
- url: /robots\.txt
static_files: static/robots.txt
upload: static/robots\.txt
secure: always
- url: /static
static_dir: static
http_headers:
Access-Control-Allow-Origin: "*"
secure: always
- url: /.*
script: auto
secure: always
includes:
- env_vars.yaml
env_variables:
GAE_USE_SOCKETS_HTTPLIB : ''

Просмотреть файл

@ -11,7 +11,8 @@ dispatch:
- url: "*/tasks/email-subscribers"
service: notifier
- url: "*/hello"
service: app-py3
- url: "*/tasks/outbound-email"
service: default
# TODO(jrobbins): Gradually route most requests to service app-py3.
- url: "*/*"
service: app-py3

Просмотреть файл

@ -116,9 +116,6 @@ def get_headers(nonce):
return {csp_header_key: csp_directives}
app = flask.Flask(__name__)
@app.route('/csp', methods=['POST'])
def report_handler():
"""Log any CSP violations that are reported to our app."""
logging.error('CSP Violation: %r' % flask.request.data)

Просмотреть файл

@ -18,11 +18,14 @@
import unittest
import testing_config # Must be imported before the module under test.
import flask
import mock
import werkzeug.exceptions # Flask HTTP stuff.
from framework import csp
test_app = flask.Flask(__name__)
class CspTest(unittest.TestCase):
@ -99,7 +102,7 @@ class CspReporttest(unittest.TestCase):
@mock.patch('logging.error')
def test_report_handler(self, mock_error):
"""The report handler logs something for each request."""
with csp.app.test_request_context('/csp', data='12345', method='POST'):
with test_app.test_request_context('/csp', data='12345', method='POST'):
actual = csp.report_handler()
self.assertEqual('', actual)

Просмотреть файл

@ -268,10 +268,3 @@ class BlinkComponentHandler(basehandlers.FlaskHandler):
def get_template_data(self):
models.BlinkComponent.update_db()
return 'Blink components updated'
app = basehandlers.FlaskApplication([
('/cron/metrics', YesterdayHandler),
('/cron/histograms', HistogramsHandler),
('/cron/update_blink_components', BlinkComponentHandler),
], debug=settings.DEBUG)

Просмотреть файл

@ -27,6 +27,8 @@ import werkzeug
from internals import fetchmetrics
from internals import models
test_app = flask.Flask(__name__)
class FetchMetricsTest(testing_config.CustomTestCase):
@ -101,7 +103,7 @@ class YesterdayHandlerTest(testing_config.CustomTestCase):
mock_FetchAndSaveData.return_value = 200
today = datetime.date(2021, 1, 20)
with fetchmetrics.app.test_request_context(self.request_path):
with test_app.test_request_context(self.request_path):
actual_response = self.handler.get_template_data(today=today)
self.assertEqual('Success', actual_response)
@ -117,7 +119,7 @@ class YesterdayHandlerTest(testing_config.CustomTestCase):
mock_FetchAndSaveData.return_value = 200
today = datetime.date(2021, 1, 20)
with fetchmetrics.app.test_request_context(
with test_app.test_request_context(
self.request_path, query_string={'date': '20210120'}):
actual_response = self.handler.get_template_data(today=today)
@ -174,7 +176,7 @@ class HistogramsHandlerTest(testing_config.CustomTestCase):
mock_requests_get.return_value = testing_config.Blank(
status_code=200,
content=base64.b64encode(self.ENUMS_TEXT.encode()))
with fetchmetrics.app.test_request_context(self.request_path):
with test_app.test_request_context(self.request_path):
actual_response = self.handler.get_template_data()
self.assertEqual('Success', actual_response)

Просмотреть файл

@ -591,6 +591,7 @@ class Feature(DictModel):
# TODO(jrobbins): Eliminate format version 1.
def format_for_template(self, version=2):
self.migrate_views()
logging.info('In format_for_template for %r', self)
d = self.to_dict()
is_released = self.impl_status_chrome in RELEASE_IMPL_STATES
d['is_released'] = is_released

174
main.py
Просмотреть файл

@ -1,18 +1,176 @@
# -*- coding: utf-8 -*-
# Copyright 2021 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License")
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from flask import Flask
import logging
from api import accounts_api
from api import approvals_api
from api import channels_api
from api import comments_api
from api import cues_api
from api import features_api
from api import login_api
from api import logout_api
from api import metricsdata
from api import stars_api
from api import token_refresh_api
from framework import basehandlers
from framework import csp
from internals import fetchmetrics
from pages import blink_handler
from pages import featuredetail
from pages import featurelist
from pages import guide
from pages import intentpreview
from pages import metrics
from pages import myfeatures
from pages import roadmap
from pages import samples
from pages import schedule
from pages import users
import settings
logging.basicConfig(level=logging.INFO)
# If `entrypoint` is not defined in app.yaml, App Engine will look for an app
# called `app` in `main.py`.
app = Flask(__name__)
metrics_chart_routes = [
('/data/timeline/cssanimated', metricsdata.AnimatedTimelineHandler),
('/data/timeline/csspopularity', metricsdata.PopularityTimelineHandler),
('/data/timeline/featurepopularity',
metricsdata.FeatureObserverTimelineHandler),
('/data/csspopularity', metricsdata.CSSPopularityHandler),
('/data/cssanimated', metricsdata.CSSAnimatedHandler),
('/data/featurepopularity', metricsdata.FeatureObserverPopularityHandler),
('/data/blink/<string:prop_type>', metricsdata.FeatureBucketsHandler),
]
# TODO(jrobbins): Advance this to v1 once we have it fleshed out
API_BASE = '/api/v0'
api_routes = [
(API_BASE + '/features', features_api.FeaturesAPI),
(API_BASE + '/features/<int:feature_id>', features_api.FeaturesAPI),
(API_BASE + '/features/<int:feature_id>/approvals/<int:field_id>',
approvals_api.ApprovalsAPI),
(API_BASE + '/features/<int:feature_id>/approvals/<int:field_id>/comments',
comments_api.CommentsAPI),
(API_BASE + '/login', login_api.LoginAPI),
(API_BASE + '/logout', logout_api.LogoutAPI),
(API_BASE + '/currentuser/stars', stars_api.StarsAPI),
(API_BASE + '/currentuser/cues', cues_api.CuesAPI),
(API_BASE + '/currentuser/token', token_refresh_api.TokenRefreshAPI),
# (API_BASE + '/currentuser/autosaves', TODO),
# (API_BASE + '/currentuser/settings', TODO),
# Admin operations for user accounts
(API_BASE + '/accounts', accounts_api.AccountsAPI),
(API_BASE + '/accounts/<int:account_id>', accounts_api.AccountsAPI),
(API_BASE + '/channels', channels_api.ChannelsAPI), # omaha data
# (API_BASE + '/schedule', TODO), # chromiumdash data
# (API_BASE + '/metrics/<str:kind>', TODO), # uma-export data
# (API_BASE + '/metrics/<str:kind>/<int:bucket_id>', TODO),
]
@app.route('/hello')
def hello():
"""Return a friendly HTTP greeting."""
logging.info('In hello() !')
return 'Hello python 3!'
page_routes = [
('/admin/subscribers', blink_handler.SubscribersHandler),
('/admin/blink', blink_handler.BlinkHandler),
('/feature/<int:feature_id>', featuredetail.FeatureDetailHandler),
# Note: The only requests being made now hit /features.json and
# /features_v2.json, but both of those cause version == 2.
# There was logic to accept another version value, but it it was not used.
(r'/features.json', featurelist.FeaturesJsonHandler),
(r'/features_v2.json', featurelist.FeaturesJsonHandler),
('/', basehandlers.Redirector,
{'location': '/features'}),
('/features', featurelist.FeatureListHandler),
('/features/<int:feature_id>', featurelist.FeatureListHandler),
('/features.xml', featurelist.FeatureListXMLHandler),
('/guide/new', guide.FeatureNew),
('/guide/edit/<int:feature_id>', guide.ProcessOverview),
('/guide/stage/<int:feature_id>/<int:stage_id>', guide.FeatureEditStage),
('/guide/editall/<int:feature_id>', guide.FeatureEditAllFields),
('/admin/features/launch/<int:feature_id>',
intentpreview.IntentEmailPreviewHandler),
('/admin/features/launch/<int:feature_id>/<int:stage_id>',
intentpreview.IntentEmailPreviewHandler),
('/metrics', basehandlers.Redirector,
{'location': '/metrics/css/popularity'}),
('/metrics/css', basehandlers.Redirector,
{'location': '/metrics/css/popularity'}),
# TODO(jrobbins): These seem like they belong in metrics.py.
('/metrics/css/popularity', basehandlers.ConstHandler,
{'template_path': 'metrics/css/popularity.html'}),
('/metrics/css/animated', basehandlers.ConstHandler,
{'template_path': 'metrics/css/animated.html'}),
('/metrics/css/timeline/popularity', metrics.CssPopularityHandler),
('/metrics/css/timeline/popularity/<int:bucket_id>',
metrics.CssPopularityHandler),
('/metrics/css/timeline/animated', metrics.CssAnimatedHandler),
('/metrics/css/timeline/animated/<int:bucket_id>',
metrics.CssAnimatedHandler),
('/metrics/feature/popularity', basehandlers.ConstHandler,
{'template_path': 'metrics/feature/popularity.html'}),
('/metrics/feature/timeline/popularity', metrics.FeaturePopularityHandler),
('/metrics/feature/timeline/popularity/<int:bucket_id>',
metrics.FeaturePopularityHandler),
('/omaha_data', metrics.OmahaDataHandler),
('/myfeatures', myfeatures.MyFeaturesHandler),
('/roadmap', roadmap.RoadmapHandler),
('/samples', samples.SamplesHandler),
('/samples.json', samples.SamplesJSONHandler),
('/samples.xml', samples.SamplesXMLHandler),
('/features/schedule', schedule.ScheduleHandler),
('/settings', users.SettingsHandler),
('/admin/users/new', users.UserListHandler),
]
internals_routes = [
('/cron/metrics', fetchmetrics.YesterdayHandler),
('/cron/histograms', fetchmetrics.HistogramsHandler),
('/cron/update_blink_components', fetchmetrics.BlinkComponentHandler),
]
# All requests to the app-py3 GAE service are handled by this Flask app.
app = basehandlers.FlaskApplication(
(metrics_chart_routes + api_routes + page_routes +
internals_routes),
debug=settings.DEBUG)
# TODO(jrobbins): Make the CSP handler be a class like our others.
app.add_url_rule(
'/csp', view_func=csp.report_handler,
methods=['POST'])
if __name__ == '__main__':
# This is used when running locally only. When deploying to Google App

Просмотреть файл

@ -22,47 +22,12 @@ import collections
import json
import logging
import os
import yaml
from framework import basehandlers
from framework import permissions
from internals import models
import settings
from .schedule import construct_chrome_channels_details
class PopulateSubscribersHandler(basehandlers.FlaskHandler):
def __populate_subscribers(self):
"""Seeds the database with the team in devrel_team.yaml and adds the team
member to the specified blink components in that file. Should only be ran
if the FeatureOwner database entries have been cleared"""
f = file('%s/data/devrel_team.yaml' % settings.ROOT_DIR, 'r')
for profile in yaml.load_all(f):
blink_components = profile.get('blink_components', [])
blink_components = [
models.BlinkComponent.get_by_name(name).key
for name in blink_components]
blink_components = [f for f in blink_components if f]
user = models.FeatureOwner(
name=str(profile['name']),
email=str(profile['email']),
twitter=profile.get('twitter', None),
blink_components=blink_components,
primary_blink_components=blink_components,
watching_all_features=False,
)
user.put()
f.close()
@permissions.require_admin_site
def get_template_data(self):
if settings.PROD:
return 'Handler not allowed in production.'
models.BlinkComponent.update_db()
self.__populate_subscribers()
return self.redirect('/admin/blink')
from pages.schedule import construct_chrome_channels_details
class BlinkHandler(basehandlers.FlaskHandler):
@ -182,10 +147,3 @@ class SubscribersHandler(basehandlers.FlaskHandler):
'selected_milestone': int(milestone) if milestone else None
}
return template_data
app = basehandlers.FlaskApplication([
('/admin/blink/populate_subscribers', PopulateSubscribersHandler),
('/admin/subscribers', SubscribersHandler),
('/admin/blink', BlinkHandler),
], debug=settings.DEBUG)

Просмотреть файл

@ -19,7 +19,6 @@
import json
import logging
import settings
from framework import basehandlers
from pages import guideforms
from internals import models
@ -52,10 +51,3 @@ class FeatureDetailHandler(basehandlers.FlaskHandler):
'new_crbug_url': f.new_crbug_url(),
}
return template_data
routes = [
('/feature/<int:feature_id>', FeatureDetailHandler),
]
app = basehandlers.FlaskApplication(routes, debug=settings.DEBUG)

Просмотреть файл

@ -25,6 +25,8 @@ from internals import models
from framework import ramcache
from pages import featuredetail
test_app = flask.Flask(__name__)
class TestWithFeature(testing_config.CustomTestCase):
@ -58,7 +60,7 @@ class FeatureDetailHandlerTest(TestWithFeature):
def test_get_template_data__missing(self):
"""If a feature is not found, give a 404."""
feature_id = 123456
with featuredetail.app.test_request_context('/feature/123456'):
with test_app.test_request_context('/feature/123456'):
with self.assertRaises(werkzeug.exceptions.NotFound):
self.handler.get_template_data(feature_id=feature_id)
@ -69,14 +71,14 @@ class FeatureDetailHandlerTest(TestWithFeature):
self.feature_1.deleted = True
self.feature_1.put()
with featuredetail.app.test_request_context(self.request_path):
with test_app.test_request_context(self.request_path):
with self.assertRaises(werkzeug.exceptions.NotFound):
template_data = self.handler.get_template_data(
feature_id=self.feature_id)
def test_get_template_data__normal(self):
"""We can prep to render the feature detail page."""
with featuredetail.app.test_request_context(self.request_path):
with test_app.test_request_context(self.request_path):
template_data = self.handler.get_template_data(
feature_id=self.feature_id)
@ -90,7 +92,7 @@ class FeatureDetailTemplateTest(TestWithFeature):
def setUp(self):
super(FeatureDetailTemplateTest, self).setUp()
with featuredetail.app.test_request_context(self.request_path):
with test_app.test_request_context(self.request_path):
self.template_data = self.handler.get_template_data(
feature_id=self.feature_id)

Просмотреть файл

@ -105,21 +105,3 @@ class FeatureListXMLHandler(basehandlers.FlaskHandler):
version=2)
return utils.render_atom_feed(self.request, 'Features', feature_list)
routes = [
# Note: The only requests being made now hit /features.json and
# /features_v2.json, but both of those cause version == 2.
# There was logic to accept another version value, but it it was not used.
(r'/features.json', FeaturesJsonHandler),
(r'/features_v2.json', FeaturesJsonHandler),
('/', basehandlers.Redirector,
{'location': '/features'}),
('/features', FeatureListHandler),
('/features/<int:feature_id>', FeatureListHandler),
('/features.xml', FeatureListXMLHandler),
]
app = basehandlers.FlaskApplication(routes, debug=settings.DEBUG)

Просмотреть файл

@ -24,6 +24,8 @@ from framework import ramcache
from internals import models
from pages import featurelist
test_app = flask.Flask(__name__)
class TestWithFeature(testing_config.CustomTestCase):
@ -57,7 +59,7 @@ class FeaturesJsonHandlerTest(TestWithFeature):
def test_get_template_data(self):
"""User can get a JSON feed of all features."""
testing_config.sign_in('user@example.com', 111)
with featurelist.app.test_request_context(self.request_path):
with test_app.test_request_context(self.request_path):
json_data = self.handler.get_template_data()
self.assertEqual(1, len(json_data))
@ -69,12 +71,12 @@ class FeaturesJsonHandlerTest(TestWithFeature):
self.feature_1.put()
testing_config.sign_out()
with featurelist.app.test_request_context(self.request_path):
with test_app.test_request_context(self.request_path):
json_data = self.handler.get_template_data()
self.assertEqual(0, len(json_data))
testing_config.sign_in('user@example.com', 111)
with featurelist.app.test_request_context(self.request_path):
with test_app.test_request_context(self.request_path):
json_data = self.handler.get_template_data()
self.assertEqual(0, len(json_data))
@ -84,7 +86,7 @@ class FeaturesJsonHandlerTest(TestWithFeature):
self.feature_1.put()
testing_config.sign_in('user@google.com', 111)
with featurelist.app.test_request_context(self.request_path):
with test_app.test_request_context(self.request_path):
json_data = self.handler.get_template_data()
self.assertEqual(1, len(json_data))
self.assertEqual('feature one', json_data[0]['name'])
@ -97,7 +99,7 @@ class FeatureListHandlerTest(TestWithFeature):
def test_get_template_data(self):
"""User can get a feature list page."""
with featurelist.app.test_request_context(self.request_path):
with test_app.test_request_context(self.request_path):
template_data = self.handler.get_template_data()
self.assertIn('IMPLEMENTATION_STATUSES', template_data)
@ -110,7 +112,7 @@ class FeatureListXMLHandlerTest(TestWithFeature):
def test_get_template_data__no_filters(self):
"""User can get an XML feed of all features."""
with featurelist.app.test_request_context(self.request_path):
with test_app.test_request_context(self.request_path):
actual_text, actual_headers = self.handler.get_template_data()
self.assertTrue(actual_text.startswith('<?xml'))
@ -123,7 +125,7 @@ class FeatureListXMLHandlerTest(TestWithFeature):
def test_get_template_data__category(self):
"""User can get an XML feed of features by category."""
request_path = self.request_path + '?category=web components'
with featurelist.app.test_request_context(request_path):
with test_app.test_request_context(request_path):
actual_text, actual_headers = self.handler.get_template_data()
# It is an XML feed
@ -138,8 +140,8 @@ class FeatureListXMLHandlerTest(TestWithFeature):
request_path = self.request_path + '?category=css'
with featurelist.app.test_request_context(request_path):
with test_app.test_request_context(request_path):
actual_text, actual_headers = self.handler.get_template_data()
self.assertTrue(actual_text.startswith('<?xml'))
self.assertNotIn('feature one', actual_text)
self.assertNotIn('feature one', actual_text)

Просмотреть файл

@ -36,7 +36,6 @@ from framework import utils
from pages import guideforms
from internals import models
from internals import processes
import settings
# Forms to be used for each stage of each process.
@ -563,11 +562,3 @@ class FeatureEditAllFields(FeatureEditStage):
'flat_forms': flat_forms,
}
return template_data
app = basehandlers.FlaskApplication([
('/guide/new', FeatureNew),
('/guide/edit/<int:feature_id>', ProcessOverview),
('/guide/stage/<int:feature_id>/<int:stage_id>', FeatureEditStage),
('/guide/editall/<int:feature_id>', FeatureEditAllFields),
], debug=settings.DEBUG)

Просмотреть файл

@ -25,6 +25,9 @@ from internals import models
from pages import guide
test_app = flask.Flask(__name__)
class FeatureNewTest(testing_config.CustomTestCase):
def setUp(self):
@ -33,21 +36,21 @@ class FeatureNewTest(testing_config.CustomTestCase):
def test_get__anon(self):
"""Anon cannot create features, gets a redirect to sign in page."""
testing_config.sign_out()
with guide.app.test_request_context('/guide/new'):
with test_app.test_request_context('/guide/new'):
actual_response = self.handler.get_template_data()
self.assertEqual('302 FOUND', actual_response.status)
def test_get__non_allowed(self):
"""Non-allowed cannot create features, gets a 403."""
testing_config.sign_in('user1@example.com', 1234567890)
with guide.app.test_request_context('/guide/new'):
with test_app.test_request_context('/guide/new'):
with self.assertRaises(werkzeug.exceptions.Forbidden):
actual_response = self.handler.get_template_data()
def test_get__normal(self):
"""Allowed users render a page with a django form."""
testing_config.sign_in('user1@google.com', 1234567890)
with guide.app.test_request_context('/guide/new'):
with test_app.test_request_context('/guide/new'):
template_data = self.handler.get_template_data()
self.assertTrue('overview_form' in template_data)
@ -60,21 +63,21 @@ class FeatureNewTest(testing_config.CustomTestCase):
def test_post__anon(self):
"""Anon cannot create features, gets a 403."""
testing_config.sign_out()
with guide.app.test_request_context('/guide/new', method='POST'):
with test_app.test_request_context('/guide/new', method='POST'):
with self.assertRaises(werkzeug.exceptions.Forbidden):
self.handler.process_post_data()
def test_post__non_allowed(self):
"""Non-allowed cannot create features, gets a 403."""
testing_config.sign_in('user1@example.com', 1234567890)
with guide.app.test_request_context('/guide/new', method='POST'):
with test_app.test_request_context('/guide/new', method='POST'):
with self.assertRaises(werkzeug.exceptions.Forbidden):
self.handler.post()
def test_post__normal_valid(self):
"""Allowed user can create a feature."""
testing_config.sign_in('user1@google.com', 1234567890)
with guide.app.test_request_context(
with test_app.test_request_context(
'/guide/new', data={
'category': '1',
'name': 'Feature name',
@ -128,7 +131,7 @@ class ProcessOverviewTest(testing_config.CustomTestCase):
def test_get__anon(self):
"""Anon cannot edit features, gets a redirect to viewing page."""
testing_config.sign_out()
with guide.app.test_request_context(self.request_path):
with test_app.test_request_context(self.request_path):
actual_response = self.handler.get_template_data(
self.feature_1.key.integer_id())
self.assertEqual('302 FOUND', actual_response.status)
@ -136,7 +139,7 @@ class ProcessOverviewTest(testing_config.CustomTestCase):
def test_get__non_allowed(self):
"""Non-allowed cannot create features, gets a 403."""
testing_config.sign_in('user1@example.com', 1234567890)
with guide.app.test_request_context(self.request_path):
with test_app.test_request_context(self.request_path):
with self.assertRaises(werkzeug.exceptions.Forbidden):
self.handler.get_template_data(self.feature_1.key.integer_id())
@ -144,7 +147,7 @@ class ProcessOverviewTest(testing_config.CustomTestCase):
def test_get__not_found(self):
"""Allowed users get a 404 if there is no such feature."""
testing_config.sign_in('user1@google.com', 1234567890)
with guide.app.test_request_context(self.request_path):
with test_app.test_request_context(self.request_path):
with self.assertRaises(werkzeug.exceptions.NotFound):
self.handler.get_template_data(999)
@ -152,7 +155,7 @@ class ProcessOverviewTest(testing_config.CustomTestCase):
"""Allowed users render a page with a process overview."""
testing_config.sign_in('user1@google.com', 1234567890)
with guide.app.test_request_context(self.request_path):
with test_app.test_request_context(self.request_path):
template_data = self.handler.get_template_data(
self.feature_1.key.integer_id())
@ -179,14 +182,14 @@ class FeatureEditStageTest(testing_config.CustomTestCase):
def test_touched(self):
"""We can tell if the user meant to edit a field."""
with guide.app.test_request_context(
with test_app.test_request_context(
'path', data={'name': 'new name'}):
self.assertTrue(self.handler.touched('name'))
self.assertFalse(self.handler.touched('summary'))
def test_split_input(self):
"""We can parse items from multi-item text fields"""
with guide.app.test_request_context(
with test_app.test_request_context(
'path', data={
'empty': '',
'colors': 'yellow\nblue',
@ -204,7 +207,7 @@ class FeatureEditStageTest(testing_config.CustomTestCase):
def test_get__anon(self):
"""Anon cannot edit features, gets a redirect to viewing page."""
testing_config.sign_out()
with guide.app.test_request_context(self.request_path):
with test_app.test_request_context(self.request_path):
actual_response = self.handler.get_template_data(
self.feature_1.key.integer_id(), self.stage)
self.assertEqual('302 FOUND', actual_response.status)
@ -212,7 +215,7 @@ class FeatureEditStageTest(testing_config.CustomTestCase):
def test_get__non_allowed(self):
"""Non-allowed cannot edit features, gets a 403."""
testing_config.sign_in('user1@example.com', 1234567890)
with guide.app.test_request_context(self.request_path):
with test_app.test_request_context(self.request_path):
with self.assertRaises(werkzeug.exceptions.Forbidden):
self.handler.get_template_data(
self.feature_1.key.integer_id(), self.stage)
@ -220,7 +223,7 @@ class FeatureEditStageTest(testing_config.CustomTestCase):
def test_get__not_found(self):
"""Allowed users get a 404 if there is no such feature."""
testing_config.sign_in('user1@google.com', 1234567890)
with guide.app.test_request_context(self.request_path):
with test_app.test_request_context(self.request_path):
with self.assertRaises(werkzeug.exceptions.NotFound):
self.handler.get_template_data(999, self.stage)
@ -228,7 +231,7 @@ class FeatureEditStageTest(testing_config.CustomTestCase):
"""Allowed users render a page with a django form."""
testing_config.sign_in('user1@google.com', 1234567890)
with guide.app.test_request_context(self.request_path):
with test_app.test_request_context(self.request_path):
template_data = self.handler.get_template_data(
self.feature_1.key.integer_id(), self.stage)
@ -241,7 +244,7 @@ class FeatureEditStageTest(testing_config.CustomTestCase):
"""When feature is not on the stage for the current form, offer checkbox."""
testing_config.sign_in('user1@google.com', 1234567890)
with guide.app.test_request_context(self.request_path):
with test_app.test_request_context(self.request_path):
template_data = self.handler.get_template_data(
self.feature_1.key.integer_id(), self.stage)
@ -253,7 +256,7 @@ class FeatureEditStageTest(testing_config.CustomTestCase):
self.feature_1.put()
testing_config.sign_in('user1@google.com', 1234567890)
with guide.app.test_request_context(self.request_path):
with test_app.test_request_context(self.request_path):
template_data = self.handler.get_template_data(
self.feature_1.key.integer_id(), self.stage)
@ -262,7 +265,7 @@ class FeatureEditStageTest(testing_config.CustomTestCase):
def test_post__anon(self):
"""Anon cannot edit features, gets a 403."""
testing_config.sign_out()
with guide.app.test_request_context(self.request_path, method='POST'):
with test_app.test_request_context(self.request_path, method='POST'):
with self.assertRaises(werkzeug.exceptions.Forbidden):
self.handler.process_post_data(
self.feature_1.key.integer_id(), self.stage)
@ -270,7 +273,7 @@ class FeatureEditStageTest(testing_config.CustomTestCase):
def test_post__non_allowed(self):
"""Non-allowed cannot edit features, gets a 403."""
testing_config.sign_in('user1@example.com', 1234567890)
with guide.app.test_request_context(self.request_path, method='POST'):
with test_app.test_request_context(self.request_path, method='POST'):
with self.assertRaises(werkzeug.exceptions.Forbidden):
self.handler.process_post_data(
self.feature_1.key.integer_id(), self.stage)
@ -278,7 +281,7 @@ class FeatureEditStageTest(testing_config.CustomTestCase):
def test_post__normal_valid(self):
"""Allowed user can edit a feature."""
testing_config.sign_in('user1@google.com', 1234567890)
with guide.app.test_request_context(
with test_app.test_request_context(
self.request_path, data={
'category': '2',
'name': 'Revised feature name',

Просмотреть файл

@ -20,7 +20,6 @@
from framework import users
from internals import models
import settings
from framework import basehandlers
from framework import permissions
from internals import processes
@ -84,9 +83,3 @@ class IntentEmailPreviewHandler(basehandlers.FlaskHandler):
return 'Intent to Extend Deprecation Trial'
return 'Intent stage "%s"' % models.INTENT_STAGES[intent_stage]
app = basehandlers.FlaskApplication([
('/admin/features/launch/<int:feature_id>', IntentEmailPreviewHandler),
('/admin/features/launch/<int:feature_id>/<int:stage_id>',
IntentEmailPreviewHandler),
], debug=settings.DEBUG)

Просмотреть файл

@ -24,6 +24,7 @@ import werkzeug
from pages import intentpreview
from internals import models
test_app = flask.Flask(__name__)
class IntentEmailPreviewHandlerTest(testing_config.CustomTestCase):
@ -46,7 +47,7 @@ class IntentEmailPreviewHandlerTest(testing_config.CustomTestCase):
"""Anon cannot view this preview features, gets redirected to login."""
testing_config.sign_out()
feature_id = self.feature_1.key.integer_id()
with intentpreview.app.test_request_context(self.request_path):
with test_app.test_request_context(self.request_path):
actual_response = self.handler.get_template_data(feature_id=feature_id)
self.assertEqual('302 FOUND', actual_response.status)
@ -54,7 +55,7 @@ class IntentEmailPreviewHandlerTest(testing_config.CustomTestCase):
"""Trying to view a feature that does not exist gives a 404."""
testing_config.sign_in('user1@google.com', 123567890)
bad_feature_id = self.feature_1.key.integer_id() + 1
with intentpreview.app.test_request_context(self.request_path):
with test_app.test_request_context(self.request_path):
with self.assertRaises(werkzeug.exceptions.NotFound):
self.handler.get_template_data(feature_id=bad_feature_id)
@ -64,7 +65,7 @@ class IntentEmailPreviewHandlerTest(testing_config.CustomTestCase):
'/admin/features/launch/%d?intent' % self.feature_1.key.integer_id())
testing_config.sign_in('user1@google.com', 123567890)
feature_id = self.feature_1.key.integer_id()
with intentpreview.app.test_request_context(self.request_path):
with test_app.test_request_context(self.request_path):
actual_data = self.handler.get_template_data(feature_id=feature_id)
self.assertIn('feature', actual_data)
self.assertEqual('feature one', actual_data['feature']['name'])
@ -73,7 +74,7 @@ class IntentEmailPreviewHandlerTest(testing_config.CustomTestCase):
"""Allowed user can preview intent email for a feature."""
testing_config.sign_in('user1@google.com', 123567890)
feature_id = self.feature_1.key.integer_id()
with intentpreview.app.test_request_context(self.request_path):
with test_app.test_request_context(self.request_path):
actual_data = self.handler.get_template_data(feature_id=feature_id)
self.assertIn('feature', actual_data)
self.assertEqual('feature one', actual_data['feature']['name'])
@ -81,7 +82,7 @@ class IntentEmailPreviewHandlerTest(testing_config.CustomTestCase):
def test_get_page_data(self):
"""page_data has correct values."""
feature_id = self.feature_1.key.integer_id()
with intentpreview.app.test_request_context(self.request_path):
with test_app.test_request_context(self.request_path):
page_data = self.handler.get_page_data(
feature_id, self.feature_1, models.INTENT_IMPLEMENT)
self.assertEqual(
@ -162,4 +163,4 @@ class IntentEmailPreviewHandlerTest(testing_config.CustomTestCase):
self.assertEqual(
'Request for Deprecation Trial',
self.handler.compute_subject_prefix(
self.feature_1, models.INTENT_EXTEND_TRIAL))
self.feature_1, models.INTENT_EXTEND_TRIAL))

Просмотреть файл

@ -19,7 +19,6 @@
import json
import logging
import settings
from framework import basehandlers
from framework import utils
from pages import guideforms
@ -28,9 +27,6 @@ from framework import ramcache
from framework import utils
from internals import fetchchannels
from google.appengine.api import users
class CssPopularityHandler(basehandlers.FlaskHandler):
@ -75,30 +71,3 @@ class OmahaDataHandler(basehandlers.FlaskHandler):
def get_template_data(self):
omaha_data = fetchchannels.get_omaha_data()
return omaha_data
# Main URL routes.
routes = [
('/metrics', basehandlers.Redirector,
{'location': '/metrics/css/popularity'}),
('/metrics/css', basehandlers.Redirector,
{'location': '/metrics/css/popularity'}),
# TODO(jrobbins): These seem like they belong in metrics.py.
('/metrics/css/popularity', basehandlers.ConstHandler,
{'template_path': 'metrics/css/popularity.html'}),
('/metrics/css/animated', basehandlers.ConstHandler,
{'template_path': 'metrics/css/animated.html'}),
('/metrics/css/timeline/popularity', CssPopularityHandler),
('/metrics/css/timeline/popularity/<int:bucket_id>', CssPopularityHandler),
('/metrics/css/timeline/animated', CssAnimatedHandler),
('/metrics/css/timeline/animated/<int:bucket_id>', CssAnimatedHandler),
('/metrics/feature/popularity', basehandlers.ConstHandler,
{'template_path': 'metrics/feature/popularity.html'}),
('/metrics/feature/timeline/popularity', FeaturePopularityHandler),
('/metrics/feature/timeline/popularity/<int:bucket_id>', FeaturePopularityHandler),
('/omaha_data', OmahaDataHandler),
]
app = basehandlers.FlaskApplication(routes, debug=settings.DEBUG)

Просмотреть файл

@ -37,9 +37,3 @@ class MyFeaturesHandler(basehandlers.FlaskHandler):
template_data = {}
return template_data
routes = [
('/myfeatures', MyFeaturesHandler),
]
app = basehandlers.FlaskApplication(routes, debug=settings.DEBUG)

Просмотреть файл

@ -26,6 +26,8 @@ from framework import ramcache
from internals import models
from pages import myfeatures
test_app = flask.Flask(__name__)
class MyFeaturesHandlerTest(testing_config.CustomTestCase):
@ -39,7 +41,7 @@ class MyFeaturesHandlerTest(testing_config.CustomTestCase):
mock_gsiup.return_value = None
mock_redirect.return_value = 'mock redirect response'
with myfeatures.app.test_request_context(self.request_path):
with test_app.test_request_context(self.request_path):
actual = self.handler.get_template_data()
mock_redirect.assert_called_once_with(settings.LOGIN_PAGE_URL)
@ -50,7 +52,7 @@ class MyFeaturesHandlerTest(testing_config.CustomTestCase):
"""User can get a 'my feature' page."""
mock_gsiup.return_value = models.UserPref(
email='user@example.com')
with myfeatures.app.test_request_context(self.request_path):
with test_app.test_request_context(self.request_path):
template_data = self.handler.get_template_data()
# Everything is done in JS, so there is no template_data

Просмотреть файл

@ -19,7 +19,7 @@
__author__ = 'shivam.agrawal.2000@gmail.com (Shivam Agarwal)'
from framework import basehandlers
import settings
class RoadmapHandler(basehandlers.FlaskHandler):
@ -27,8 +27,3 @@ class RoadmapHandler(basehandlers.FlaskHandler):
def get_template_data(self):
return {}
app = basehandlers.FlaskApplication([
('/roadmap', RoadmapHandler),
], debug=settings.DEBUG)

Просмотреть файл

@ -67,12 +67,3 @@ class SamplesXMLHandler(basehandlers.FlaskHandler):
max_items = settings.RSS_FEED_LIMIT
return utils.render_atom_feed(self.request, 'Samples', feature_list)
routes = [
('/samples', SamplesHandler),
('/samples.json', SamplesJSONHandler),
('/samples.xml', SamplesXMLHandler),
]
app = basehandlers.FlaskApplication(routes, debug=settings.DEBUG)

Просмотреть файл

@ -24,6 +24,8 @@ from internals import models
from framework import ramcache
from pages import samples
test_app = flask.Flask(__name__)
class TestWithFeature(testing_config.CustomTestCase):
@ -56,7 +58,7 @@ class SamplesHandlerTest(TestWithFeature):
def test_get_template_data(self):
"""User can get a page with all samples."""
with samples.app.test_request_context(self.request_path):
with test_app.test_request_context(self.request_path):
template_data = self.handler.get_template_data()
self.assertIn('FEATURES', template_data)
@ -69,7 +71,7 @@ class SamplesJSONHandlerTest(TestWithFeature):
def test_get_template_data(self):
"""User can get a JSON feed of all samples."""
with samples.app.test_request_context(self.request_path):
with test_app.test_request_context(self.request_path):
json_data = self.handler.get_template_data()
self.assertEqual([], json_data)
@ -82,7 +84,7 @@ class SamplesXMLHandlerTest(TestWithFeature):
def test_get_template_data(self):
"""User can get an XML feed of all samples."""
with samples.app.test_request_context(self.request_path):
with test_app.test_request_context(self.request_path):
actual_text, actual_headers = self.handler.get_template_data()
# It is an XML feed
@ -92,4 +94,4 @@ class SamplesXMLHandlerTest(TestWithFeature):
# feature_1 is not in the list because it does not have a sample.
self.assertNotIn('detailed sum', actual_text)
self.assertNotIn('feature/' + str(self.feature_id), actual_text)
self.assertNotIn('feature/' + str(self.feature_id), actual_text)

Просмотреть файл

@ -30,7 +30,6 @@ from framework import users
from framework import basehandlers
from internals import models
import settings
from internals import fetchchannels
SCHEDULE_CACHE_TIME = 60 * 60 # 1 hour
@ -105,8 +104,3 @@ class ScheduleHandler(basehandlers.FlaskHandler):
indent=4)
}
return template_data
app = basehandlers.FlaskApplication([
('/features/schedule', ScheduleHandler),
], debug=settings.DEBUG)

Просмотреть файл

@ -74,9 +74,3 @@ class SettingsHandler(basehandlers.FlaskHandler):
user_pref.notify_as_starrer = bool(new_notify)
user_pref.put()
return flask.redirect(flask.request.path)
app = basehandlers.FlaskApplication([
('/settings', SettingsHandler),
('/admin/users/new', UserListHandler),
], debug=settings.DEBUG)

Просмотреть файл

@ -24,6 +24,8 @@ import flask
from internals import models
from pages import users
test_app = flask.Flask(__name__)
class SettingsHandlerTests(unittest.TestCase):
@ -36,7 +38,7 @@ class SettingsHandlerTests(unittest.TestCase):
mock_gsiup.return_value = None
mock_redirect.return_value = 'mock redirect response'
with users.app.test_request_context('/settings'):
with test_app.test_request_context('/settings'):
actual = self.handler.get_template_data()
mock_redirect.assert_called_once()

Просмотреть файл

@ -95,8 +95,6 @@ else:
SECRET_KEY = os.environ['DJANGO_SECRET']
APP_VERSION = os.environ['CURRENT_VERSION_ID'].split('.')[0]
RSS_FEED_LIMIT = 15
DEFAULT_CACHE_TIME = 60 # seconds