Refactor models.py enums into core_enums.py. (#2106)

This commit is contained in:
Jason Robbins 2022-08-12 15:49:32 -07:00 коммит произвёл GitHub
Родитель e0651d191b
Коммит 0972d89600
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
14 изменённых файлов: 522 добавлений и 498 удалений

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

@ -19,6 +19,7 @@ from unittest import mock
import werkzeug.exceptions # Flask HTTP stuff.
from api import features_api
from internals import core_enums
from internals import models
from framework import ramcache
@ -31,7 +32,7 @@ class FeaturesAPITestDelete(testing_config.CustomTestCase):
self.feature_1 = models.Feature(
name='feature one', summary='sum', category=1, visibility=1,
standardization=1, web_dev_views=1, impl_status_chrome=1,
intent_stage=models.INTENT_IMPLEMENT)
intent_stage=core_enums.INTENT_IMPLEMENT)
self.feature_1.put()
self.feature_id = self.feature_1.key.integer_id()
@ -101,7 +102,7 @@ class FeaturesAPITestGet(testing_config.CustomTestCase):
name='feature one', summary='sum Z',
owner=['feature_owner@example.com'],
category=1, visibility=1, standardization=1, web_dev_views=1,
impl_status_chrome=5, intent_stage=models.INTENT_IMPLEMENT,
impl_status_chrome=5, intent_stage=core_enums.INTENT_IMPLEMENT,
shipped_milestone=1)
self.feature_1.put()
self.feature_1_id = self.feature_1.key.integer_id()
@ -110,7 +111,7 @@ class FeaturesAPITestGet(testing_config.CustomTestCase):
name='feature two', summary='sum K',
owner=['other_owner@example.com'],
category=1, visibility=1, standardization=1, web_dev_views=1,
impl_status_chrome=5, intent_stage=models.INTENT_IMPLEMENT,
impl_status_chrome=5, intent_stage=core_enums.INTENT_IMPLEMENT,
shipped_milestone=2)
self.feature_2.put()
self.feature_2_id = self.feature_2.key.integer_id()
@ -119,7 +120,7 @@ class FeaturesAPITestGet(testing_config.CustomTestCase):
name='feature three', summary='sum A',
owner=['other_owner@example.com'],
category=1, visibility=1, standardization=1, web_dev_views=1,
impl_status_chrome=5, intent_stage=models.INTENT_IMPLEMENT,
impl_status_chrome=5, intent_stage=core_enums.INTENT_IMPLEMENT,
shipped_milestone=2, unlisted=True)
self.feature_3.put()
self.feature_3_id = self.feature_3.key.integer_id()

317
internals/core_enums.py Normal file
Просмотреть файл

@ -0,0 +1,317 @@
# Copyright 2022 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 collections
WEBCOMPONENTS = 1
MISC = 2
SECURITY = 3
MULTIMEDIA = 4
DOM = 5
FILE = 6
OFFLINE = 7
DEVICE = 8
COMMUNICATION = 9
JAVASCRIPT = 10
NETWORKING = 11
INPUT = 12
PERFORMANCE = 13
GRAPHICS = 14
CSS = 15
HOUDINI = 16
SERVICEWORKER = 17
WEBRTC = 18
LAYERED = 19
WEBASSEMBLY = 20
CAPABILITIES = 21
FEATURE_CATEGORIES = {
CSS: 'CSS',
WEBCOMPONENTS: 'Web Components',
MISC: 'Miscellaneous',
SECURITY: 'Security',
MULTIMEDIA: 'Multimedia',
DOM: 'DOM',
FILE: 'File APIs',
OFFLINE: 'Offline / Storage',
DEVICE: 'Device',
COMMUNICATION: 'Realtime / Communication',
JAVASCRIPT: 'JavaScript',
NETWORKING: 'Network / Connectivity',
INPUT: 'User input',
PERFORMANCE: 'Performance',
GRAPHICS: 'Graphics',
HOUDINI: 'Houdini',
SERVICEWORKER: 'Service Worker',
WEBRTC: 'Web RTC',
LAYERED: 'Layered APIs',
WEBASSEMBLY: 'WebAssembly',
CAPABILITIES: 'Capabilities (Fugu)'
}
FEATURE_TYPE_INCUBATE_ID = 0
FEATURE_TYPE_EXISTING_ID = 1
FEATURE_TYPE_CODE_CHANGE_ID = 2
FEATURE_TYPE_DEPRECATION_ID = 3
FEATURE_TYPES = {
FEATURE_TYPE_INCUBATE_ID: 'New feature incubation',
FEATURE_TYPE_EXISTING_ID: 'Existing feature implementation',
FEATURE_TYPE_CODE_CHANGE_ID: 'Web developer facing change to existing code',
FEATURE_TYPE_DEPRECATION_ID: 'Feature deprecation',
}
# Intent stages and mapping from stage to stage name.
INTENT_NONE = 0
INTENT_INCUBATE = 7 # Start incubating
INTENT_IMPLEMENT = 1 # Start prototyping
INTENT_EXPERIMENT = 2 # Dev trials
INTENT_IMPLEMENT_SHIP = 4 # Eval readiness to ship
INTENT_EXTEND_TRIAL = 3 # Origin trials
INTENT_SHIP = 5 # Prepare to ship
INTENT_REMOVED = 6
INTENT_SHIPPED = 8
INTENT_PARKED = 9
INTENT_STAGES = collections.OrderedDict([
(INTENT_NONE, 'None'),
(INTENT_INCUBATE, 'Start incubating'),
(INTENT_IMPLEMENT, 'Start prototyping'),
(INTENT_EXPERIMENT, 'Dev trials'),
(INTENT_IMPLEMENT_SHIP, 'Evaluate readiness to ship'),
(INTENT_EXTEND_TRIAL, 'Origin Trial'),
(INTENT_SHIP, 'Prepare to ship'),
(INTENT_REMOVED, 'Removed'),
(INTENT_SHIPPED, 'Shipped'),
(INTENT_PARKED, 'Parked'),
])
NO_ACTIVE_DEV = 1
PROPOSED = 2
IN_DEVELOPMENT = 3
BEHIND_A_FLAG = 4
ENABLED_BY_DEFAULT = 5
DEPRECATED = 6
REMOVED = 7
ORIGIN_TRIAL = 8
INTERVENTION = 9
ON_HOLD = 10
NO_LONGER_PURSUING = 1000 # insure bottom of list
RELEASE_IMPL_STATES = {
BEHIND_A_FLAG, ENABLED_BY_DEFAULT,
DEPRECATED, REMOVED, ORIGIN_TRIAL, INTERVENTION,
}
# Ordered dictionary, make sure the order of this dictionary matches that of
# the sorted list above!
IMPLEMENTATION_STATUS = collections.OrderedDict()
IMPLEMENTATION_STATUS[NO_ACTIVE_DEV] = 'No active development'
IMPLEMENTATION_STATUS[PROPOSED] = 'Proposed'
IMPLEMENTATION_STATUS[IN_DEVELOPMENT] = 'In development'
IMPLEMENTATION_STATUS[BEHIND_A_FLAG] = 'In developer trial (Behind a flag)'
IMPLEMENTATION_STATUS[ENABLED_BY_DEFAULT] = 'Enabled by default'
IMPLEMENTATION_STATUS[DEPRECATED] = 'Deprecated'
IMPLEMENTATION_STATUS[REMOVED] = 'Removed'
IMPLEMENTATION_STATUS[ORIGIN_TRIAL] = 'Origin trial'
IMPLEMENTATION_STATUS[INTERVENTION] = 'Browser Intervention'
IMPLEMENTATION_STATUS[ON_HOLD] = 'On hold'
IMPLEMENTATION_STATUS[NO_LONGER_PURSUING] = 'No longer pursuing'
MAJOR_NEW_API = 1
MAJOR_MINOR_NEW_API = 2
SUBSTANTIVE_CHANGES = 3
MINOR_EXISTING_CHANGES = 4
EXTREMELY_SMALL_CHANGE = 5
# Status for security and privacy reviews.
REVIEW_PENDING = 1
REVIEW_ISSUES_OPEN = 2
REVIEW_ISSUES_ADDRESSED = 3
REVIEW_NA = 4
REVIEW_STATUS_CHOICES = {
REVIEW_PENDING: 'Pending',
REVIEW_ISSUES_OPEN: 'Issues open',
REVIEW_ISSUES_ADDRESSED: 'Issues addressed',
REVIEW_NA: 'Not applicable',
}
FOOTPRINT_CHOICES = {
MAJOR_NEW_API: ('A major new independent API (e.g. adding many '
'independent concepts with many methods/properties/objects)'),
MAJOR_MINOR_NEW_API: ('Major changes to an existing API OR a minor new '
'independent API (e.g. adding many new '
'methods/properties or introducing new concepts to '
'augment an existing API)'),
SUBSTANTIVE_CHANGES: ('Substantive changes to an existing API (e.g. small '
'number of new methods/properties)'),
MINOR_EXISTING_CHANGES: (
'Minor changes to an existing API (e.g. adding a new keyword/allowed '
'argument to a property/method)'),
EXTREMELY_SMALL_CHANGE: ('Extremely small tweaks to an existing API (e.g. '
'how existing keywords/arguments are interpreted)'),
}
MAINSTREAM_NEWS = 1
WARRANTS_ARTICLE = 2
IN_LARGER_ARTICLE = 3
SMALL_NUM_DEVS = 4
SUPER_SMALL = 5
# Signals from other implementations in an intent-to-ship
SHIPPED = 1
IN_DEV = 2
PUBLIC_SUPPORT = 3
MIXED_SIGNALS = 4 # Deprecated
NO_PUBLIC_SIGNALS = 5
PUBLIC_SKEPTICISM = 6 # Deprecated
OPPOSED = 7
NEUTRAL = 8
SIGNALS_NA = 9
GECKO_UNDER_CONSIDERATION = 10
GECKO_IMPORTANT = 11
GECKO_WORTH_PROTOTYPING = 12
GECKO_NONHARMFUL = 13
GECKO_DEFER = 14
GECKO_HARMFUL = 15
VENDOR_VIEWS_COMMON = {
SHIPPED: 'Shipped/Shipping',
IN_DEV: 'In development',
PUBLIC_SUPPORT: 'Positive',
NO_PUBLIC_SIGNALS: 'No signal',
OPPOSED: 'Negative',
NEUTRAL: 'Neutral',
SIGNALS_NA: 'N/A',
}
VENDOR_VIEWS_GECKO = VENDOR_VIEWS_COMMON.copy()
VENDOR_VIEWS_GECKO.update({
GECKO_UNDER_CONSIDERATION: 'Under consideration',
GECKO_IMPORTANT: 'Important',
GECKO_WORTH_PROTOTYPING: 'Worth prototyping',
GECKO_NONHARMFUL: 'Non-harmful',
GECKO_DEFER: 'Defer',
GECKO_HARMFUL: 'Harmful',
})
# These vendors have no "custom" views values yet.
VENDOR_VIEWS_EDGE = VENDOR_VIEWS_COMMON
VENDOR_VIEWS_WEBKIT = VENDOR_VIEWS_COMMON
VENDOR_VIEWS = {}
VENDOR_VIEWS.update(VENDOR_VIEWS_GECKO)
VENDOR_VIEWS.update(VENDOR_VIEWS_EDGE)
VENDOR_VIEWS.update(VENDOR_VIEWS_WEBKIT)
DEFACTO_STD = 1
ESTABLISHED_STD = 2
WORKING_DRAFT = 3
EDITORS_DRAFT = 4
PUBLIC_DISCUSSION = 5
NO_STD_OR_DISCUSSION = 6
STANDARDIZATION = {
DEFACTO_STD: 'De-facto standard',
ESTABLISHED_STD: 'Established standard',
WORKING_DRAFT: 'Working draft or equivalent',
EDITORS_DRAFT: "Editor's draft",
PUBLIC_DISCUSSION: 'Public discussion',
NO_STD_OR_DISCUSSION: 'No public standards discussion',
}
UNSET_STD = 0
UNKNOWN_STD = 1
PROPOSAL_STD = 2
INCUBATION_STD = 3
WORKINGDRAFT_STD = 4
STANDARD_STD = 5
STANDARD_MATURITY_CHOICES = {
# No text for UNSET_STD. One of the values below will be set on first edit.
UNKNOWN_STD: 'Unknown standards status - check spec link for status',
PROPOSAL_STD: 'Proposal in a personal repository, no adoption from community',
INCUBATION_STD: 'Specification being incubated in a Community Group',
WORKINGDRAFT_STD: ('Specification currently under development in a '
'Working Group'),
STANDARD_STD: ('Final published standard: Recommendation, Living Standard, '
'Candidate Recommendation, or similar final form'),
}
STANDARD_MATURITY_SHORT = {
UNSET_STD: 'Unknown status',
UNKNOWN_STD: 'Unknown status',
PROPOSAL_STD: 'Pre-incubation',
INCUBATION_STD: 'Incubation',
WORKINGDRAFT_STD: 'Working draft',
STANDARD_STD: 'Published standard',
}
# For features that don't have a standard_maturity value set, but do have
# the old standardization field, infer a maturity.
STANDARD_MATURITY_BACKFILL = {
DEFACTO_STD: STANDARD_STD,
ESTABLISHED_STD: STANDARD_STD,
WORKING_DRAFT: WORKINGDRAFT_STD,
EDITORS_DRAFT: INCUBATION_STD,
PUBLIC_DISCUSSION: INCUBATION_STD,
NO_STD_OR_DISCUSSION: PROPOSAL_STD,
}
DEV_STRONG_POSITIVE = 1
DEV_POSITIVE = 2
DEV_MIXED_SIGNALS = 3
DEV_NO_SIGNALS = 4
DEV_NEGATIVE = 5
DEV_STRONG_NEGATIVE = 6
WEB_DEV_VIEWS = {
DEV_STRONG_POSITIVE: 'Strongly positive',
DEV_POSITIVE: 'Positive',
DEV_MIXED_SIGNALS: 'Mixed signals',
DEV_NO_SIGNALS: 'No signals',
DEV_NEGATIVE: 'Negative',
DEV_STRONG_NEGATIVE: 'Strongly negative',
}
PROPERTY_NAMES_TO_ENUM_DICTS = {
'category': FEATURE_CATEGORIES,
'intent_stage': INTENT_STAGES,
'impl_status_chrome': IMPLEMENTATION_STATUS,
'security_review_status': REVIEW_STATUS_CHOICES,
'privacy_review_status': REVIEW_STATUS_CHOICES,
'standard_maturity': STANDARD_MATURITY_CHOICES,
'standardization': STANDARDIZATION,
'ff_views': VENDOR_VIEWS,
'ie_views': VENDOR_VIEWS,
'safari_views': VENDOR_VIEWS,
'web_dev_views': WEB_DEV_VIEWS,
}
def convert_enum_int_to_string(property_name, value):
"""If the property is an enum, return human-readable string, else value."""
if type(value) != int:
return value
enum_dict = PROPERTY_NAMES_TO_ENUM_DICTS.get(property_name, {})
converted_value = enum_dict.get(value, value)
return converted_value

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

@ -18,6 +18,7 @@ import flask
from unittest import mock
import werkzeug
from internals import core_enums
from internals import models
from internals import approval_defs
from internals import detect_intent
@ -31,7 +32,7 @@ class FunctionTest(testing_config.CustomTestCase):
self.feature_1 = models.Feature(
name='feature one', summary='detailed sum', category=1, visibility=1,
standardization=1, web_dev_views=1, impl_status_chrome=1,
intent_stage=models.INTENT_IMPLEMENT)
intent_stage=core_enums.INTENT_IMPLEMENT)
self.feature_1.put()
def tearDown(self):
@ -324,7 +325,7 @@ class IntentEmailHandlerTest(testing_config.CustomTestCase):
self.feature_1 = models.Feature(
name='feature one', summary='detailed sum', category=1, visibility=1,
standardization=1, web_dev_views=1, impl_status_chrome=1,
intent_stage=models.INTENT_IMPLEMENT)
intent_stage=core_enums.INTENT_IMPLEMENT)
self.feature_1.put()
self.feature_id = self.feature_1.key.integer_id()

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

@ -28,6 +28,7 @@ from framework import users
from framework import cloud_tasks_helpers
from framework import utils
import settings
from internals.core_enums import *
from internals import fetchchannels
import hack_components
@ -39,305 +40,6 @@ from django import forms
SIMPLE_TYPES = (int, float, bool, dict, str, list)
WEBCOMPONENTS = 1
MISC = 2
SECURITY = 3
MULTIMEDIA = 4
DOM = 5
FILE = 6
OFFLINE = 7
DEVICE = 8
COMMUNICATION = 9
JAVASCRIPT = 10
NETWORKING = 11
INPUT = 12
PERFORMANCE = 13
GRAPHICS = 14
CSS = 15
HOUDINI = 16
SERVICEWORKER = 17
WEBRTC = 18
LAYERED = 19
WEBASSEMBLY = 20
CAPABILITIES = 21
FEATURE_CATEGORIES = {
CSS: 'CSS',
WEBCOMPONENTS: 'Web Components',
MISC: 'Miscellaneous',
SECURITY: 'Security',
MULTIMEDIA: 'Multimedia',
DOM: 'DOM',
FILE: 'File APIs',
OFFLINE: 'Offline / Storage',
DEVICE: 'Device',
COMMUNICATION: 'Realtime / Communication',
JAVASCRIPT: 'JavaScript',
NETWORKING: 'Network / Connectivity',
INPUT: 'User input',
PERFORMANCE: 'Performance',
GRAPHICS: 'Graphics',
HOUDINI: 'Houdini',
SERVICEWORKER: 'Service Worker',
WEBRTC: 'Web RTC',
LAYERED: 'Layered APIs',
WEBASSEMBLY: 'WebAssembly',
CAPABILITIES: 'Capabilities (Fugu)'
}
FEATURE_TYPE_INCUBATE_ID = 0
FEATURE_TYPE_EXISTING_ID = 1
FEATURE_TYPE_CODE_CHANGE_ID = 2
FEATURE_TYPE_DEPRECATION_ID = 3
FEATURE_TYPES = {
FEATURE_TYPE_INCUBATE_ID: 'New feature incubation',
FEATURE_TYPE_EXISTING_ID: 'Existing feature implementation',
FEATURE_TYPE_CODE_CHANGE_ID: 'Web developer facing change to existing code',
FEATURE_TYPE_DEPRECATION_ID: 'Feature deprecation',
}
# Intent stages and mapping from stage to stage name.
INTENT_NONE = 0
INTENT_INCUBATE = 7 # Start incubating
INTENT_IMPLEMENT = 1 # Start prototyping
INTENT_EXPERIMENT = 2 # Dev trials
INTENT_IMPLEMENT_SHIP = 4 # Eval readiness to ship
INTENT_EXTEND_TRIAL = 3 # Origin trials
INTENT_SHIP = 5 # Prepare to ship
INTENT_REMOVED = 6
INTENT_SHIPPED = 8
INTENT_PARKED = 9
INTENT_STAGES = collections.OrderedDict([
(INTENT_NONE, 'None'),
(INTENT_INCUBATE, 'Start incubating'),
(INTENT_IMPLEMENT, 'Start prototyping'),
(INTENT_EXPERIMENT, 'Dev trials'),
(INTENT_IMPLEMENT_SHIP, 'Evaluate readiness to ship'),
(INTENT_EXTEND_TRIAL, 'Origin Trial'),
(INTENT_SHIP, 'Prepare to ship'),
(INTENT_REMOVED, 'Removed'),
(INTENT_SHIPPED, 'Shipped'),
(INTENT_PARKED, 'Parked'),
])
NO_ACTIVE_DEV = 1
PROPOSED = 2
IN_DEVELOPMENT = 3
BEHIND_A_FLAG = 4
ENABLED_BY_DEFAULT = 5
DEPRECATED = 6
REMOVED = 7
ORIGIN_TRIAL = 8
INTERVENTION = 9
ON_HOLD = 10
NO_LONGER_PURSUING = 1000 # insure bottom of list
RELEASE_IMPL_STATES = {
BEHIND_A_FLAG, ENABLED_BY_DEFAULT,
DEPRECATED, REMOVED, ORIGIN_TRIAL, INTERVENTION,
}
# Ordered dictionary, make sure the order of this dictionary matches that of
# the sorted list above!
IMPLEMENTATION_STATUS = OrderedDict()
IMPLEMENTATION_STATUS[NO_ACTIVE_DEV] = 'No active development'
IMPLEMENTATION_STATUS[PROPOSED] = 'Proposed'
IMPLEMENTATION_STATUS[IN_DEVELOPMENT] = 'In development'
IMPLEMENTATION_STATUS[BEHIND_A_FLAG] = 'In developer trial (Behind a flag)'
IMPLEMENTATION_STATUS[ENABLED_BY_DEFAULT] = 'Enabled by default'
IMPLEMENTATION_STATUS[DEPRECATED] = 'Deprecated'
IMPLEMENTATION_STATUS[REMOVED] = 'Removed'
IMPLEMENTATION_STATUS[ORIGIN_TRIAL] = 'Origin trial'
IMPLEMENTATION_STATUS[INTERVENTION] = 'Browser Intervention'
IMPLEMENTATION_STATUS[ON_HOLD] = 'On hold'
IMPLEMENTATION_STATUS[NO_LONGER_PURSUING] = 'No longer pursuing'
MAJOR_NEW_API = 1
MAJOR_MINOR_NEW_API = 2
SUBSTANTIVE_CHANGES = 3
MINOR_EXISTING_CHANGES = 4
EXTREMELY_SMALL_CHANGE = 5
# Status for security and privacy reviews.
REVIEW_PENDING = 1
REVIEW_ISSUES_OPEN = 2
REVIEW_ISSUES_ADDRESSED = 3
REVIEW_NA = 4
REVIEW_STATUS_CHOICES = {
REVIEW_PENDING: 'Pending',
REVIEW_ISSUES_OPEN: 'Issues open',
REVIEW_ISSUES_ADDRESSED: 'Issues addressed',
REVIEW_NA: 'Not applicable',
}
FOOTPRINT_CHOICES = {
MAJOR_NEW_API: ('A major new independent API (e.g. adding many '
'independent concepts with many methods/properties/objects)'),
MAJOR_MINOR_NEW_API: ('Major changes to an existing API OR a minor new '
'independent API (e.g. adding many new '
'methods/properties or introducing new concepts to '
'augment an existing API)'),
SUBSTANTIVE_CHANGES: ('Substantive changes to an existing API (e.g. small '
'number of new methods/properties)'),
MINOR_EXISTING_CHANGES: (
'Minor changes to an existing API (e.g. adding a new keyword/allowed '
'argument to a property/method)'),
EXTREMELY_SMALL_CHANGE: ('Extremely small tweaks to an existing API (e.g. '
'how existing keywords/arguments are interpreted)'),
}
MAINSTREAM_NEWS = 1
WARRANTS_ARTICLE = 2
IN_LARGER_ARTICLE = 3
SMALL_NUM_DEVS = 4
SUPER_SMALL = 5
# Signals from other implementations in an intent-to-ship
SHIPPED = 1
IN_DEV = 2
PUBLIC_SUPPORT = 3
MIXED_SIGNALS = 4 # Deprecated
NO_PUBLIC_SIGNALS = 5
PUBLIC_SKEPTICISM = 6 # Deprecated
OPPOSED = 7
NEUTRAL = 8
SIGNALS_NA = 9
GECKO_UNDER_CONSIDERATION = 10
GECKO_IMPORTANT = 11
GECKO_WORTH_PROTOTYPING = 12
GECKO_NONHARMFUL = 13
GECKO_DEFER = 14
GECKO_HARMFUL = 15
VENDOR_VIEWS_COMMON = {
SHIPPED: 'Shipped/Shipping',
IN_DEV: 'In development',
PUBLIC_SUPPORT: 'Positive',
NO_PUBLIC_SIGNALS: 'No signal',
OPPOSED: 'Negative',
NEUTRAL: 'Neutral',
SIGNALS_NA: 'N/A',
}
VENDOR_VIEWS_GECKO = VENDOR_VIEWS_COMMON.copy()
VENDOR_VIEWS_GECKO.update({
GECKO_UNDER_CONSIDERATION: 'Under consideration',
GECKO_IMPORTANT: 'Important',
GECKO_WORTH_PROTOTYPING: 'Worth prototyping',
GECKO_NONHARMFUL: 'Non-harmful',
GECKO_DEFER: 'Defer',
GECKO_HARMFUL: 'Harmful',
})
# These vendors have no "custom" views values yet.
VENDOR_VIEWS_EDGE = VENDOR_VIEWS_COMMON
VENDOR_VIEWS_WEBKIT = VENDOR_VIEWS_COMMON
VENDOR_VIEWS = {}
VENDOR_VIEWS.update(VENDOR_VIEWS_GECKO)
VENDOR_VIEWS.update(VENDOR_VIEWS_EDGE)
VENDOR_VIEWS.update(VENDOR_VIEWS_WEBKIT)
DEFACTO_STD = 1
ESTABLISHED_STD = 2
WORKING_DRAFT = 3
EDITORS_DRAFT = 4
PUBLIC_DISCUSSION = 5
NO_STD_OR_DISCUSSION = 6
STANDARDIZATION = {
DEFACTO_STD: 'De-facto standard',
ESTABLISHED_STD: 'Established standard',
WORKING_DRAFT: 'Working draft or equivalent',
EDITORS_DRAFT: "Editor's draft",
PUBLIC_DISCUSSION: 'Public discussion',
NO_STD_OR_DISCUSSION: 'No public standards discussion',
}
UNSET_STD = 0
UNKNOWN_STD = 1
PROPOSAL_STD = 2
INCUBATION_STD = 3
WORKINGDRAFT_STD = 4
STANDARD_STD = 5
STANDARD_MATURITY_CHOICES = {
# No text for UNSET_STD. One of the values below will be set on first edit.
UNKNOWN_STD: 'Unknown standards status - check spec link for status',
PROPOSAL_STD: 'Proposal in a personal repository, no adoption from community',
INCUBATION_STD: 'Specification being incubated in a Community Group',
WORKINGDRAFT_STD: ('Specification currently under development in a '
'Working Group'),
STANDARD_STD: ('Final published standard: Recommendation, Living Standard, '
'Candidate Recommendation, or similar final form'),
}
STANDARD_MATURITY_SHORT = {
UNSET_STD: 'Unknown status',
UNKNOWN_STD: 'Unknown status',
PROPOSAL_STD: 'Pre-incubation',
INCUBATION_STD: 'Incubation',
WORKINGDRAFT_STD: 'Working draft',
STANDARD_STD: 'Published standard',
}
# For features that don't have a standard_maturity value set, but do have
# the old standardization field, infer a maturity.
STANDARD_MATURITY_BACKFILL = {
DEFACTO_STD: STANDARD_STD,
ESTABLISHED_STD: STANDARD_STD,
WORKING_DRAFT: WORKINGDRAFT_STD,
EDITORS_DRAFT: INCUBATION_STD,
PUBLIC_DISCUSSION: INCUBATION_STD,
NO_STD_OR_DISCUSSION: PROPOSAL_STD,
}
DEV_STRONG_POSITIVE = 1
DEV_POSITIVE = 2
DEV_MIXED_SIGNALS = 3
DEV_NO_SIGNALS = 4
DEV_NEGATIVE = 5
DEV_STRONG_NEGATIVE = 6
WEB_DEV_VIEWS = {
DEV_STRONG_POSITIVE: 'Strongly positive',
DEV_POSITIVE: 'Positive',
DEV_MIXED_SIGNALS: 'Mixed signals',
DEV_NO_SIGNALS: 'No signals',
DEV_NEGATIVE: 'Negative',
DEV_STRONG_NEGATIVE: 'Strongly negative',
}
PROPERTY_NAMES_TO_ENUM_DICTS = {
'category': FEATURE_CATEGORIES,
'intent_stage': INTENT_STAGES,
'impl_status_chrome': IMPLEMENTATION_STATUS,
'security_review_status': REVIEW_STATUS_CHOICES,
'privacy_review_status': REVIEW_STATUS_CHOICES,
'standard_maturity': STANDARD_MATURITY_CHOICES,
'standardization': STANDARDIZATION,
'ff_views': VENDOR_VIEWS,
'ie_views': VENDOR_VIEWS,
'safari_views': VENDOR_VIEWS,
'web_dev_views': WEB_DEV_VIEWS,
}
def convert_enum_int_to_string(property_name, value):
"""If the property is an enum, return human-readable string, else value."""
if type(value) != int:
return value
enum_dict = PROPERTY_NAMES_TO_ENUM_DICTS.get(property_name, {})
converted_value = enum_dict.get(value, value)
return converted_value
def del_none(d):

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

@ -35,6 +35,7 @@ from framework import cloud_tasks_helpers
from framework import users
import settings
from internals import approval_defs
from internals import core_enums
from internals import models
@ -69,7 +70,7 @@ def format_email_body(is_update, feature, changes):
'updater_email': feature.updated_by.email(),
'id': feature.key.integer_id(),
'milestone': milestone_str,
'status': models.IMPLEMENTATION_STATUS[feature.impl_status_chrome],
'status': core_enums.IMPLEMENTATION_STATUS[feature.impl_status_chrome],
'formatted_changes': formatted_changes,
'moz_link_urls': moz_link_urls,
}
@ -393,7 +394,7 @@ def get_existing_thread_subject(feature, approval_field):
def generate_thread_subject(feature, approval_field):
"""Use the expected subject based on the feature type and approval type."""
intent_phrase = approval_field.name
if feature.feature_type == models.FEATURE_TYPE_DEPRECATION_ID:
if feature.feature_type == core_enums.FEATURE_TYPE_DEPRECATION_ID:
if approval_field == approval_defs.PrototypeApproval:
intent_phrase = 'Intent to Deprecate and Remove'
if approval_field == approval_defs.ExperimentApproval:

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

@ -16,6 +16,7 @@
import collections
from internals import approval_defs
from internals import core_enums
from internals import models
@ -160,7 +161,7 @@ BLINK_PROCESS_STAGES = [
],
[],
[],
models.INTENT_NONE, models.INTENT_INCUBATE),
core_enums.INTENT_NONE, core_enums.INTENT_INCUBATE),
ProcessStage(
'Start prototyping',
@ -175,7 +176,7 @@ BLINK_PROCESS_STAGES = [
[PI_INITIAL_PUBLIC_PROPOSAL.name, PI_MOTIVATION.name,
PI_EXPLAINER.name])],
[approval_defs.PrototypeApproval],
models.INTENT_INCUBATE, models.INTENT_IMPLEMENT),
core_enums.INTENT_INCUBATE, core_enums.INTENT_IMPLEMENT),
ProcessStage(
'Dev trials and iterate on design',
@ -194,7 +195,7 @@ BLINK_PROCESS_STAGES = [
[PI_INITIAL_PUBLIC_PROPOSAL.name, PI_MOTIVATION.name,
PI_EXPLAINER.name, PI_SPEC_LINK.name])],
[],
models.INTENT_IMPLEMENT, models.INTENT_EXPERIMENT),
core_enums.INTENT_IMPLEMENT, core_enums.INTENT_EXPERIMENT),
ProcessStage(
'Evaluate readiness to ship',
@ -208,7 +209,7 @@ BLINK_PROCESS_STAGES = [
],
[],
[],
models.INTENT_EXPERIMENT, models.INTENT_IMPLEMENT_SHIP),
core_enums.INTENT_EXPERIMENT, core_enums.INTENT_IMPLEMENT_SHIP),
ProcessStage(
'Origin Trial',
@ -225,7 +226,7 @@ BLINK_PROCESS_STAGES = [
PI_EXPLAINER.name, PI_SPEC_LINK.name,
PI_EST_TARGET_MILESTONE.name])],
[approval_defs.ExperimentApproval],
models.INTENT_IMPLEMENT_SHIP, models.INTENT_EXTEND_TRIAL),
core_enums.INTENT_IMPLEMENT_SHIP, core_enums.INTENT_EXTEND_TRIAL),
ProcessStage(
'Prepare to ship',
@ -244,7 +245,7 @@ BLINK_PROCESS_STAGES = [
PI_TAG_ADDRESSED.name, PI_UPDATED_VENDOR_SIGNALS.name,
PI_UPDATED_TARGET_MILESTONE.name])],
[approval_defs.ShipApproval],
models.INTENT_IMPLEMENT_SHIP, models.INTENT_SHIP),
core_enums.INTENT_IMPLEMENT_SHIP, core_enums.INTENT_SHIP),
ProcessStage(
'Ship',
@ -255,7 +256,7 @@ BLINK_PROCESS_STAGES = [
],
[],
[],
models.INTENT_SHIP, models.INTENT_SHIPPED),
core_enums.INTENT_SHIP, core_enums.INTENT_SHIPPED),
]
@ -277,7 +278,7 @@ BLINK_FAST_TRACK_STAGES = [
[Action('Draft Intent to Prototype email', INTENT_EMAIL_URL,
[PI_SPEC_LINK.name])],
[approval_defs.PrototypeApproval],
models.INTENT_NONE, models.INTENT_IMPLEMENT),
core_enums.INTENT_NONE, core_enums.INTENT_IMPLEMENT),
ProcessStage(
'Dev trials and iterate on implementation',
@ -293,7 +294,7 @@ BLINK_FAST_TRACK_STAGES = [
[Action('Draft Ready for Trial email', INTENT_EMAIL_URL,
[PI_SPEC_LINK.name, PI_EST_TARGET_MILESTONE.name])],
[],
models.INTENT_IMPLEMENT, models.INTENT_EXPERIMENT),
core_enums.INTENT_IMPLEMENT, core_enums.INTENT_EXPERIMENT),
ProcessStage(
'Origin Trial',
@ -308,7 +309,7 @@ BLINK_FAST_TRACK_STAGES = [
[Action('Draft Intent to Experiment email', INTENT_EMAIL_URL,
[PI_SPEC_LINK.name, PI_EST_TARGET_MILESTONE.name])],
[approval_defs.ExperimentApproval],
models.INTENT_EXPERIMENT, models.INTENT_EXTEND_TRIAL),
core_enums.INTENT_EXPERIMENT, core_enums.INTENT_EXTEND_TRIAL),
ProcessStage(
'Prepare to ship',
@ -322,7 +323,7 @@ BLINK_FAST_TRACK_STAGES = [
[Action('Draft Intent to Ship email', INTENT_EMAIL_URL,
[PI_SPEC_LINK.name, PI_UPDATED_TARGET_MILESTONE.name])],
[approval_defs.ShipApproval],
models.INTENT_EXPERIMENT, models.INTENT_SHIP),
core_enums.INTENT_EXPERIMENT, core_enums.INTENT_SHIP),
ProcessStage(
'Ship',
@ -333,7 +334,7 @@ BLINK_FAST_TRACK_STAGES = [
],
[],
[],
models.INTENT_SHIP, models.INTENT_SHIPPED),
core_enums.INTENT_SHIP, core_enums.INTENT_SHIPPED),
]
@ -353,7 +354,7 @@ PSA_ONLY_STAGES = [
],
[],
[],
models.INTENT_NONE, models.INTENT_IMPLEMENT),
core_enums.INTENT_NONE, core_enums.INTENT_IMPLEMENT),
ProcessStage(
'Dev trials and iterate on implementation',
@ -366,7 +367,7 @@ PSA_ONLY_STAGES = [
[Action('Draft Ready for Trial email', INTENT_EMAIL_URL,
[PI_SPEC_LINK.name, PI_EST_TARGET_MILESTONE.name])],
[],
models.INTENT_IMPLEMENT, models.INTENT_EXPERIMENT),
core_enums.INTENT_IMPLEMENT, core_enums.INTENT_EXPERIMENT),
ProcessStage(
'Prepare to ship',
@ -378,7 +379,7 @@ PSA_ONLY_STAGES = [
[Action('Draft Intent to Ship email', INTENT_EMAIL_URL,
[PI_SPEC_LINK.name, PI_UPDATED_TARGET_MILESTONE.name])],
[approval_defs.ShipApproval],
models.INTENT_EXPERIMENT, models.INTENT_SHIP),
core_enums.INTENT_EXPERIMENT, core_enums.INTENT_SHIP),
ProcessStage(
'Ship',
@ -389,7 +390,7 @@ PSA_ONLY_STAGES = [
],
[],
[],
models.INTENT_SHIP, models.INTENT_SHIPPED),
core_enums.INTENT_SHIP, core_enums.INTENT_SHIPPED),
]
@ -412,7 +413,7 @@ DEPRECATION_STAGES = [
[Action('Draft Intent to Deprecate and Remove email', INTENT_EMAIL_URL,
[PI_MOTIVATION.name])],
[approval_defs.PrototypeApproval],
models.INTENT_NONE, models.INTENT_IMPLEMENT),
core_enums.INTENT_NONE, core_enums.INTENT_IMPLEMENT),
# TODO(cwilso): Work out additional steps for flag defaulting to disabled.
ProcessStage(
@ -426,7 +427,7 @@ DEPRECATION_STAGES = [
[PI_MOTIVATION.name, PI_VENDOR_SIGNALS.name,
PI_EST_TARGET_MILESTONE.name])],
[],
models.INTENT_IMPLEMENT, models.INTENT_EXPERIMENT),
core_enums.INTENT_IMPLEMENT, core_enums.INTENT_EXPERIMENT),
ProcessStage(
'Prepare for Deprecation Trial',
@ -442,7 +443,7 @@ DEPRECATION_STAGES = [
PI_EST_TARGET_MILESTONE.name])],
# TODO(jrobbins): Intent to extend deprecation.
[approval_defs.ExperimentApproval],
models.INTENT_EXPERIMENT, models.INTENT_EXTEND_TRIAL),
core_enums.INTENT_EXPERIMENT, core_enums.INTENT_EXTEND_TRIAL),
ProcessStage(
'Prepare to ship',
@ -456,7 +457,7 @@ DEPRECATION_STAGES = [
[PI_MOTIVATION.name, PI_VENDOR_SIGNALS.name,
PI_UPDATED_TARGET_MILESTONE.name])],
[approval_defs.ShipApproval],
models.INTENT_EXPERIMENT, models.INTENT_SHIP),
core_enums.INTENT_EXPERIMENT, core_enums.INTENT_SHIP),
ProcessStage(
'Remove code',
@ -469,7 +470,7 @@ DEPRECATION_STAGES = [
PI_UPDATED_TARGET_MILESTONE.name]),
],
[],
models.INTENT_SHIP, models.INTENT_REMOVED),
core_enums.INTENT_SHIP, core_enums.INTENT_REMOVED),
]
@ -481,40 +482,40 @@ DEPRECATION_PROCESS = Process(
ALL_PROCESSES = {
models.FEATURE_TYPE_INCUBATE_ID: BLINK_LAUNCH_PROCESS,
models.FEATURE_TYPE_EXISTING_ID: BLINK_FAST_TRACK_PROCESS,
models.FEATURE_TYPE_CODE_CHANGE_ID: PSA_ONLY_PROCESS,
models.FEATURE_TYPE_DEPRECATION_ID: DEPRECATION_PROCESS,
core_enums.FEATURE_TYPE_INCUBATE_ID: BLINK_LAUNCH_PROCESS,
core_enums.FEATURE_TYPE_EXISTING_ID: BLINK_FAST_TRACK_PROCESS,
core_enums.FEATURE_TYPE_CODE_CHANGE_ID: PSA_ONLY_PROCESS,
core_enums.FEATURE_TYPE_DEPRECATION_ID: DEPRECATION_PROCESS,
}
INTENT_EMAIL_SECTIONS = {
models.INTENT_NONE: [],
models.INTENT_INCUBATE: [],
models.INTENT_IMPLEMENT: ['motivation'],
models.INTENT_EXPERIMENT: ['i2p_thread', 'experiment'],
models.INTENT_IMPLEMENT_SHIP: [
core_enums.INTENT_NONE: [],
core_enums.INTENT_INCUBATE: [],
core_enums.INTENT_IMPLEMENT: ['motivation'],
core_enums.INTENT_EXPERIMENT: ['i2p_thread', 'experiment'],
core_enums.INTENT_IMPLEMENT_SHIP: [
'need_api_owners_lgtms', 'motivation', 'tracking_bug', 'sample_links'],
models.INTENT_EXTEND_TRIAL: [
core_enums.INTENT_EXTEND_TRIAL: [
'i2p_thread', 'experiment', 'extension_reason'],
models.INTENT_SHIP: [
core_enums.INTENT_SHIP: [
'need_api_owners_lgtms', 'i2p_thread', 'tracking_bug', 'sample_links',
'anticipated_spec_changes', 'ship'],
models.INTENT_REMOVED: [],
models.INTENT_SHIPPED: [],
models.INTENT_PARKED: [],
core_enums.INTENT_REMOVED: [],
core_enums.INTENT_SHIPPED: [],
core_enums.INTENT_PARKED: [],
}
def initial_tag_review_status(feature_type):
"""Incubating a new feature requires a TAG review, other types do not."""
if feature_type == models.FEATURE_TYPE_INCUBATE_ID:
return models.REVIEW_PENDING
return models.REVIEW_NA
if feature_type == core_enums.FEATURE_TYPE_INCUBATE_ID:
return core_enums.REVIEW_PENDING
return core_enums.REVIEW_NA
def review_is_done(status):
return status in (models.REVIEW_ISSUES_ADDRESSED, models.REVIEW_NA)
return status in (core_enums.REVIEW_ISSUES_ADDRESSED, core_enums.REVIEW_NA)
# These functions return a true value when the checkmark should be shown.
@ -580,25 +581,25 @@ PROGRESS_DETECTORS = {
'Web developer signals':
lambda f: bool(f.web_dev_views and
f.web_dev_views != models.DEV_NO_SIGNALS),
f.web_dev_views != core_enums.DEV_NO_SIGNALS),
'Vendor signals':
lambda f: bool(
f.ff_views != models.NO_PUBLIC_SIGNALS or
f.safari_views != models.NO_PUBLIC_SIGNALS or
f.ie_views != models.NO_PUBLIC_SIGNALS), # IE Deprecated
f.ff_views != core_enums.NO_PUBLIC_SIGNALS or
f.safari_views != core_enums.NO_PUBLIC_SIGNALS or
f.ie_views != core_enums.NO_PUBLIC_SIGNALS), # IE Deprecated
'Updated vendor signals':
lambda f: bool(
f.ff_views != models.NO_PUBLIC_SIGNALS or
f.safari_views != models.NO_PUBLIC_SIGNALS or
f.ie_views != models.NO_PUBLIC_SIGNALS), # IE Deprecated
f.ff_views != core_enums.NO_PUBLIC_SIGNALS or
f.safari_views != core_enums.NO_PUBLIC_SIGNALS or
f.ie_views != core_enums.NO_PUBLIC_SIGNALS), # IE Deprecated
'Final vendor signals':
lambda f: bool(
f.ff_views != models.NO_PUBLIC_SIGNALS or
f.safari_views != models.NO_PUBLIC_SIGNALS or
f.ie_views != models.NO_PUBLIC_SIGNALS), # IE Deprecated
f.ff_views != core_enums.NO_PUBLIC_SIGNALS or
f.safari_views != core_enums.NO_PUBLIC_SIGNALS or
f.ie_views != core_enums.NO_PUBLIC_SIGNALS), # IE Deprecated
'Estimated target milestone':
lambda f: bool(f.shipped_milestone),
@ -608,12 +609,13 @@ PROGRESS_DETECTORS = {
'Code in Chromium':
lambda f: f.impl_status_chrome in (
models.IN_DEVELOPMENT, models.BEHIND_A_FLAG, models.ENABLED_BY_DEFAULT,
models.ORIGIN_TRIAL, models.INTERVENTION),
core_enums.IN_DEVELOPMENT, core_enums.BEHIND_A_FLAG,
core_enums.ENABLED_BY_DEFAULT,
core_enums.ORIGIN_TRIAL, core_enums.INTERVENTION),
'Motivation':
lambda f: bool(f.motivation),
'Code removed':
lambda f: f.impl_status_chrome == models.REMOVED,
lambda f: f.impl_status_chrome == core_enums.REMOVED,
}

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

@ -18,6 +18,7 @@ import testing_config # Must be imported before the module under test.
from unittest import mock
from internals import approval_defs
from internals import core_enums
from internals import models
from internals import processes
@ -99,10 +100,10 @@ class HelperFunctionsTest(testing_config.CustomTestCase):
"""A review step is done if the review has completed or was N/a."""
self.assertFalse(processes.review_is_done(None))
self.assertFalse(processes.review_is_done(0))
self.assertFalse(processes.review_is_done(models.REVIEW_PENDING))
self.assertFalse(processes.review_is_done(models.REVIEW_ISSUES_OPEN))
self.assertTrue(processes.review_is_done(models.REVIEW_ISSUES_ADDRESSED))
self.assertTrue(processes.review_is_done(models.REVIEW_NA))
self.assertFalse(processes.review_is_done(core_enums.REVIEW_PENDING))
self.assertFalse(processes.review_is_done(core_enums.REVIEW_ISSUES_OPEN))
self.assertTrue(processes.review_is_done(core_enums.REVIEW_ISSUES_ADDRESSED))
self.assertTrue(processes.review_is_done(core_enums.REVIEW_NA))
class ProcessesWellFormedTest(testing_config.CustomTestCase):
@ -141,9 +142,9 @@ class ProgressDetectorsTest(testing_config.CustomTestCase):
def setUp(self):
self.feature_1 = models.Feature(
name='feature one', summary='sum', category=1, visibility=1,
standardization=1, web_dev_views=models.DEV_NO_SIGNALS,
standardization=1, web_dev_views=core_enums.DEV_NO_SIGNALS,
impl_status_chrome=1,
intent_stage=models.INTENT_IMPLEMENT)
intent_stage=core_enums.INTENT_IMPLEMENT)
self.feature_1.put()
def tearDown(self):
@ -164,13 +165,13 @@ class ProgressDetectorsTest(testing_config.CustomTestCase):
def test_security_review_completed(self):
detector = processes.PROGRESS_DETECTORS['Security review issues addressed']
self.assertFalse(detector(self.feature_1))
self.feature_1.security_review_status = models.REVIEW_ISSUES_ADDRESSED
self.feature_1.security_review_status = core_enums.REVIEW_ISSUES_ADDRESSED
self.assertTrue(detector(self.feature_1))
def test_privacy_review_completed(self):
detector = processes.PROGRESS_DETECTORS['Privacy review issues addressed']
self.assertFalse(detector(self.feature_1))
self.feature_1.privacy_review_status = models.REVIEW_ISSUES_ADDRESSED
self.feature_1.privacy_review_status = core_enums.REVIEW_ISSUES_ADDRESSED
self.assertTrue(detector(self.feature_1))
def test_intent_to_prototype_email(self):
@ -240,19 +241,19 @@ class ProgressDetectorsTest(testing_config.CustomTestCase):
def test_tag_review_completed(self):
detector = processes.PROGRESS_DETECTORS['TAG review issues addressed']
self.assertFalse(detector(self.feature_1))
self.feature_1.tag_review_status = models.REVIEW_ISSUES_ADDRESSED
self.feature_1.tag_review_status = core_enums.REVIEW_ISSUES_ADDRESSED
self.assertTrue(detector(self.feature_1))
def test_web_dav_signals(self):
detector = processes.PROGRESS_DETECTORS['Web developer signals']
self.assertFalse(detector(self.feature_1))
self.feature_1.web_dev_views = models.PUBLIC_SUPPORT
self.feature_1.web_dev_views = core_enums.PUBLIC_SUPPORT
self.assertTrue(detector(self.feature_1))
def test_vendor_signals(self):
detector = processes.PROGRESS_DETECTORS['Vendor signals']
self.assertFalse(detector(self.feature_1))
self.feature_1.ff_views = models.PUBLIC_SUPPORT
self.feature_1.ff_views = core_enums.PUBLIC_SUPPORT
self.assertTrue(detector(self.feature_1))
def test_estimated_target_milestone(self):
@ -264,7 +265,7 @@ class ProgressDetectorsTest(testing_config.CustomTestCase):
def test_code_in_chromium(self):
detector = processes.PROGRESS_DETECTORS['Code in Chromium']
self.assertFalse(detector(self.feature_1))
self.feature_1.impl_status_chrome = models.ENABLED_BY_DEFAULT
self.feature_1.impl_status_chrome = core_enums.ENABLED_BY_DEFAULT
self.assertTrue(detector(self.feature_1))
def test_motivation(self):
@ -276,5 +277,5 @@ class ProgressDetectorsTest(testing_config.CustomTestCase):
def test_code_removed(self):
detector = processes.PROGRESS_DETECTORS['Code removed']
self.assertFalse(detector(self.feature_1))
self.feature_1.impl_status_chrome = models.REMOVED
self.feature_1.impl_status_chrome = core_enums.REMOVED
self.assertTrue(detector(self.feature_1))

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

@ -13,8 +13,6 @@
# limitations under the License.
import testing_config # Must be imported first
import os
@ -22,6 +20,7 @@ import flask
import werkzeug
import html5lib
from internals import core_enums
from internals import models
from framework import ramcache
from pages import featuredetail
@ -38,7 +37,7 @@ class TestWithFeature(testing_config.CustomTestCase):
self.feature_1 = models.Feature(
name='feature one', summary='detailed sum', category=1, visibility=1,
standardization=1, web_dev_views=1, impl_status_chrome=1,
intent_stage=models.INTENT_IMPLEMENT)
intent_stage=core_enums.INTENT_IMPLEMENT)
self.feature_1.put()
self.feature_id = self.feature_1.key.integer_id()

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

@ -13,9 +13,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import json
import logging
@ -24,6 +21,7 @@ from framework import basehandlers
from framework import permissions
from framework import utils
from internals import models
from internals import core_enums
from framework import ramcache
# from google.appengine.api import users
@ -56,19 +54,19 @@ class FeatureListHandler(basehandlers.FlaskHandler):
template_data = {}
template_data['categories'] = [
(v, utils.normalized_name(v)) for k,v in
list(models.FEATURE_CATEGORIES.items())]
list(core_enums.FEATURE_CATEGORIES.items())]
template_data['IMPLEMENTATION_STATUSES'] = json.dumps([
{'key': k, 'val': v} for k,v in
list(models.IMPLEMENTATION_STATUS.items())])
list(core_enums.IMPLEMENTATION_STATUS.items())])
template_data['VENDOR_VIEWS'] = json.dumps([
{'key': k, 'val': v} for k,v in
list(models.VENDOR_VIEWS.items())])
list(core_enums.VENDOR_VIEWS.items())])
template_data['WEB_DEV_VIEWS'] = json.dumps([
{'key': k, 'val': v} for k,v in
list(models.WEB_DEV_VIEWS.items())])
list(core_enums.WEB_DEV_VIEWS.items())])
template_data['STANDARDS_VALS'] = json.dumps([
{'key': k, 'val': v} for k,v in
list(models.STANDARDIZATION.items())])
list(core_enums.STANDARDIZATION.items())])
return template_data
@ -92,7 +90,7 @@ class FeatureListXMLHandler(basehandlers.FlaskHandler):
max_items = settings.RSS_FEED_LIMIT
if category is not None:
for k,v in list(models.FEATURE_CATEGORIES.items()):
for k,v in list(core_enums.FEATURE_CATEGORIES.items()):
normalized = utils.normalized_name(v)
if category == normalized:
filterby = ('category', k)

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

@ -31,6 +31,7 @@ from framework import basehandlers
from framework import permissions
from framework import utils
from pages import guideforms
from internals import core_enums
from internals import models
from internals import processes
@ -38,56 +39,56 @@ from internals import processes
# Forms to be used for each stage of each process.
# { feature_type_id: { stage_id: stage_specific_form} }
STAGE_FORMS = {
models.FEATURE_TYPE_INCUBATE_ID: {
models.INTENT_INCUBATE: guideforms.NewFeature_Incubate,
models.INTENT_IMPLEMENT: guideforms.NewFeature_Prototype,
models.INTENT_EXPERIMENT: guideforms.Any_DevTrial,
models.INTENT_IMPLEMENT_SHIP: guideforms.NewFeature_EvalReadinessToShip,
models.INTENT_EXTEND_TRIAL: guideforms.NewFeature_OriginTrial,
models.INTENT_SHIP: guideforms.Most_PrepareToShip,
models.INTENT_SHIPPED: guideforms.Any_Ship,
core_enums.FEATURE_TYPE_INCUBATE_ID: {
core_enums.INTENT_INCUBATE: guideforms.NewFeature_Incubate,
core_enums.INTENT_IMPLEMENT: guideforms.NewFeature_Prototype,
core_enums.INTENT_EXPERIMENT: guideforms.Any_DevTrial,
core_enums.INTENT_IMPLEMENT_SHIP: guideforms.NewFeature_EvalReadinessToShip,
core_enums.INTENT_EXTEND_TRIAL: guideforms.NewFeature_OriginTrial,
core_enums.INTENT_SHIP: guideforms.Most_PrepareToShip,
core_enums.INTENT_SHIPPED: guideforms.Any_Ship,
},
models.FEATURE_TYPE_EXISTING_ID: {
models.INTENT_IMPLEMENT: guideforms.Existing_Prototype,
models.INTENT_EXPERIMENT: guideforms.Any_DevTrial,
models.INTENT_EXTEND_TRIAL: guideforms.Existing_OriginTrial,
models.INTENT_SHIP: guideforms.Most_PrepareToShip,
models.INTENT_SHIPPED: guideforms.Any_Ship,
core_enums.FEATURE_TYPE_EXISTING_ID: {
core_enums.INTENT_IMPLEMENT: guideforms.Existing_Prototype,
core_enums.INTENT_EXPERIMENT: guideforms.Any_DevTrial,
core_enums.INTENT_EXTEND_TRIAL: guideforms.Existing_OriginTrial,
core_enums.INTENT_SHIP: guideforms.Most_PrepareToShip,
core_enums.INTENT_SHIPPED: guideforms.Any_Ship,
},
models.FEATURE_TYPE_CODE_CHANGE_ID: {
models.INTENT_IMPLEMENT: guideforms.PSA_Implement,
models.INTENT_EXPERIMENT: guideforms.Any_DevTrial,
models.INTENT_SHIP: guideforms.PSA_PrepareToShip,
models.INTENT_SHIPPED: guideforms.Any_Ship,
core_enums.FEATURE_TYPE_CODE_CHANGE_ID: {
core_enums.INTENT_IMPLEMENT: guideforms.PSA_Implement,
core_enums.INTENT_EXPERIMENT: guideforms.Any_DevTrial,
core_enums.INTENT_SHIP: guideforms.PSA_PrepareToShip,
core_enums.INTENT_SHIPPED: guideforms.Any_Ship,
},
models.FEATURE_TYPE_DEPRECATION_ID: {
models.INTENT_IMPLEMENT: guideforms.Deprecation_Implement,
models.INTENT_EXPERIMENT: guideforms.Any_DevTrial,
models.INTENT_EXTEND_TRIAL: guideforms.Deprecation_DeprecationTrial,
models.INTENT_SHIP: guideforms.Deprecation_PrepareToShip,
models.INTENT_REMOVED: guideforms.Deprecation_Removed,
core_enums.FEATURE_TYPE_DEPRECATION_ID: {
core_enums.INTENT_IMPLEMENT: guideforms.Deprecation_Implement,
core_enums.INTENT_EXPERIMENT: guideforms.Any_DevTrial,
core_enums.INTENT_EXTEND_TRIAL: guideforms.Deprecation_DeprecationTrial,
core_enums.INTENT_SHIP: guideforms.Deprecation_PrepareToShip,
core_enums.INTENT_REMOVED: guideforms.Deprecation_Removed,
},
}
IMPL_STATUS_FORMS = {
models.INTENT_INCUBATE:
core_enums.INTENT_INCUBATE:
(None, guideforms.ImplStatus_Incubate),
models.INTENT_EXPERIMENT:
(models.BEHIND_A_FLAG, guideforms.ImplStatus_DevTrial),
models.INTENT_EXTEND_TRIAL:
(models.ORIGIN_TRIAL, guideforms.ImplStatus_OriginTrial),
models.INTENT_IMPLEMENT_SHIP:
core_enums.INTENT_EXPERIMENT:
(core_enums.BEHIND_A_FLAG, guideforms.ImplStatus_DevTrial),
core_enums.INTENT_EXTEND_TRIAL:
(core_enums.ORIGIN_TRIAL, guideforms.ImplStatus_OriginTrial),
core_enums.INTENT_IMPLEMENT_SHIP:
(None, guideforms.ImplStatus_EvalReadinessToShip),
models.INTENT_SHIP:
(models.ENABLED_BY_DEFAULT, guideforms.ImplStatus_AllMilestones),
models.INTENT_SHIPPED:
(models.ENABLED_BY_DEFAULT, guideforms.ImplStatus_AllMilestones),
models.INTENT_REMOVED:
(models.REMOVED, guideforms.ImplStatus_AllMilestones),
core_enums.INTENT_SHIP:
(core_enums.ENABLED_BY_DEFAULT, guideforms.ImplStatus_AllMilestones),
core_enums.INTENT_SHIPPED:
(core_enums.ENABLED_BY_DEFAULT, guideforms.ImplStatus_AllMilestones),
core_enums.INTENT_REMOVED:
(core_enums.REMOVED, guideforms.ImplStatus_AllMilestones),
}
# Forms to be used on the "Edit all" page that shows a flat list of fields.
@ -137,16 +138,16 @@ class FeatureNew(basehandlers.FlaskHandler):
category=int(self.form.get('category')),
name=self.form.get('name'),
feature_type=feature_type,
intent_stage=models.INTENT_NONE,
intent_stage=core_enums.INTENT_NONE,
summary=self.form.get('summary'),
owner=owners,
editors=editors,
creator=signed_in_user.email(),
accurate_as_of=datetime.now(),
impl_status_chrome=models.NO_ACTIVE_DEV,
standardization=models.EDITORS_DRAFT,
impl_status_chrome=core_enums.NO_ACTIVE_DEV,
standardization=core_enums.EDITORS_DRAFT,
unlisted=self.form.get('unlisted') == 'on',
web_dev_views=models.DEV_NO_SIGNALS,
web_dev_views=core_enums.DEV_NO_SIGNALS,
blink_components=blink_components,
tag_review_status=processes.initial_tag_review_status(feature_type),
created_by=signed_in_user,
@ -287,7 +288,7 @@ class FeatureEditStage(basehandlers.FlaskHandler):
'already_on_this_impl_status':
impl_status_offered == f.impl_status_chrome,
'impl_status_form': impl_status_form,
'impl_status_name': models.IMPLEMENTATION_STATUS.get(
'impl_status_name': core_enums.IMPLEMENTATION_STATUS.get(
impl_status_offered, None),
'impl_status_offered': impl_status_offered,
})
@ -445,7 +446,7 @@ class FeatureEditStage(basehandlers.FlaskHandler):
if self.touched('owner'):
feature.owner = self.split_emails('owner')
if self.touched('editors'):
feature.editors = self.split_emails('editors')
@ -571,7 +572,7 @@ class FeatureEditStage(basehandlers.FlaskHandler):
'experiment_extension_reason')
if self.touched('ongoing_constraints'):
feature.ongoing_constraints = self.form.get('ongoing_constraints')
# Add user who updated to list of editors if not currently an editor.
# TODO(danielrsmith): This should be removed when enabling new permissions.
associated_with_feature = permissions.strict_can_edit_feature(

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

@ -21,6 +21,7 @@ import werkzeug
import html5lib
from framework import ramcache
from internals import core_enums
from internals import models
from pages import guide
@ -139,7 +140,7 @@ class ProcessOverviewTest(testing_config.CustomTestCase):
self.feature_1 = models.Feature(
name='feature one', summary='sum', owner=['user1@google.com'],
category=1, visibility=1, standardization=1,
web_dev_views=models.DEV_NO_SIGNALS, impl_status_chrome=1)
web_dev_views=core_enums.DEV_NO_SIGNALS, impl_status_chrome=1)
self.feature_1.put()
self.request_path = '/guide/edit/%d' % self.feature_1.key.integer_id()
@ -211,7 +212,7 @@ class ProcessOverviewTemplateTest(TestWithFeature):
self.feature_1 = models.Feature(
name='feature one', summary='sum', owner=['user1@google.com'],
category=1, visibility=1, standardization=1,
web_dev_views=models.DEV_NO_SIGNALS, impl_status_chrome=1)
web_dev_views=core_enums.DEV_NO_SIGNALS, impl_status_chrome=1)
self.feature_1.put()
self.request_path = '/guide/edit/%d' % self.feature_1.key.integer_id()
@ -247,7 +248,7 @@ class FeatureEditStageTest(testing_config.CustomTestCase):
category=1, visibility=1, standardization=1, web_dev_views=1,
impl_status_chrome=1)
self.feature_1.put()
self.stage = models.INTENT_INCUBATE # Shows first form
self.stage = core_enums.INTENT_INCUBATE # Shows first form
self.request_path = ('/guide/stage/%d/%d' % (
self.feature_1.key.integer_id(), self.stage))
@ -397,9 +398,9 @@ class FeatureEditStageTemplateTest(TestWithFeature):
self.feature_1 = models.Feature(
name='feature one', summary='sum', owner=['user1@google.com'],
category=1, visibility=1, standardization=1,
web_dev_views=models.DEV_NO_SIGNALS, impl_status_chrome=1)
web_dev_views=core_enums.DEV_NO_SIGNALS, impl_status_chrome=1)
self.feature_1.put()
self.stage = models.INTENT_INCUBATE # Shows first form
self.stage = core_enums.INTENT_INCUBATE # Shows first form
testing_config.sign_in('user1@google.com', 1234567890)
with test_app.test_request_context(self.request_path):
@ -429,9 +430,9 @@ class FeatureEditAllFieldsTemplateTest(TestWithFeature):
self.feature_1 = models.Feature(
name='feature one', summary='sum', owner=['user1@google.com'],
category=1, visibility=1, standardization=1,
web_dev_views=models.DEV_NO_SIGNALS, impl_status_chrome=1)
web_dev_views=core_enums.DEV_NO_SIGNALS, impl_status_chrome=1)
self.feature_1.put()
self.stage = models.INTENT_INCUBATE # Shows first form
self.stage = core_enums.INTENT_INCUBATE # Shows first form
testing_config.sign_in('user1@google.com', 1234567890)
with test_app.test_request_context(self.request_path):
@ -459,9 +460,9 @@ class FeatureVerifyAccuracyTemplateTest(TestWithFeature):
self.feature_1 = models.Feature(
name='feature one', summary='sum', owner=['user1@google.com'],
category=1, visibility=1, standardization=1,
web_dev_views=models.DEV_NO_SIGNALS, impl_status_chrome=1)
web_dev_views=core_enums.DEV_NO_SIGNALS, impl_status_chrome=1)
self.feature_1.put()
self.stage = models.INTENT_INCUBATE # Shows first form
self.stage = core_enums.INTENT_INCUBATE # Shows first form
testing_config.sign_in('user1@google.com', 1234567890)
with test_app.test_request_context(self.request_path):

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

@ -27,6 +27,7 @@ from django.utils.safestring import mark_safe
# from google.appengine.api import users
from framework import users
from internals import core_enums
from internals import models
from internals import processes
@ -155,18 +156,18 @@ ALL_FIELDS = {
'category': forms.ChoiceField(
required=False, label='',
initial=models.MISC,
choices=sorted(models.FEATURE_CATEGORIES.items(), key=lambda x: x[1])),
initial=core_enums.MISC,
choices=sorted(core_enums.FEATURE_CATEGORIES.items(), key=lambda x: x[1])),
'feature_type': forms.ChoiceField(
required=False, label='',
initial=models.FEATURE_TYPE_INCUBATE_ID,
choices=sorted(models.FEATURE_TYPES.items())),
initial=core_enums.FEATURE_TYPE_INCUBATE_ID,
choices=sorted(core_enums.FEATURE_TYPES.items())),
'intent_stage': forms.ChoiceField(
required=False, label='',
initial=models.INTENT_IMPLEMENT,
choices=list(models.INTENT_STAGES.items())),
initial=core_enums.INTENT_IMPLEMENT,
choices=list(core_enums.INTENT_STAGES.items())),
'motivation': forms.CharField(
label='', required=False,
@ -188,8 +189,8 @@ ALL_FIELDS = {
'standard_maturity': forms.ChoiceField(
required=False, label='',
choices=list(models.STANDARD_MATURITY_CHOICES.items()),
initial=models.PROPOSAL_STD),
choices=list(core_enums.STANDARD_MATURITY_CHOICES.items()),
initial=core_enums.PROPOSAL_STD),
'unlisted': forms.BooleanField(
label='',
@ -216,14 +217,14 @@ ALL_FIELDS = {
'security_review_status': forms.ChoiceField(
label='',
required=False,
choices=list(models.REVIEW_STATUS_CHOICES.items()),
initial=models.REVIEW_PENDING),
choices=list(core_enums.REVIEW_STATUS_CHOICES.items()),
initial=core_enums.REVIEW_PENDING),
'privacy_review_status': forms.ChoiceField(
label='',
required=False,
choices=list(models.REVIEW_STATUS_CHOICES.items()),
initial=models.REVIEW_PENDING),
choices=list(core_enums.REVIEW_STATUS_CHOICES.items()),
initial=core_enums.REVIEW_PENDING),
'tag_review': forms.CharField(
label='', required=False,
@ -232,8 +233,8 @@ ALL_FIELDS = {
'tag_review_status': forms.ChoiceField(
label='',
required=False,
choices=list(models.REVIEW_STATUS_CHOICES.items()),
initial=models.REVIEW_PENDING),
choices=list(core_enums.REVIEW_STATUS_CHOICES.items()),
initial=core_enums.REVIEW_PENDING),
'intent_to_implement_url': forms.URLField(
required=False, label='',
@ -265,8 +266,8 @@ ALL_FIELDS = {
'safari_views': forms.ChoiceField(
required=False, label='',
choices=list(models.VENDOR_VIEWS_WEBKIT.items()),
initial=models.NO_PUBLIC_SIGNALS),
choices=list(core_enums.VENDOR_VIEWS_WEBKIT.items()),
initial=core_enums.NO_PUBLIC_SIGNALS),
'safari_views_link': forms.URLField(
required=False, label='',
@ -279,8 +280,8 @@ ALL_FIELDS = {
'ff_views': forms.ChoiceField(
required=False, label='',
choices=list(models.VENDOR_VIEWS_GECKO.items()),
initial=models.NO_PUBLIC_SIGNALS),
choices=list(core_enums.VENDOR_VIEWS_GECKO.items()),
initial=core_enums.NO_PUBLIC_SIGNALS),
'ff_views_link': forms.URLField(
required=False, label='',
@ -293,8 +294,8 @@ ALL_FIELDS = {
'web_dev_views': forms.ChoiceField(
required=False, label='',
choices=list(models.WEB_DEV_VIEWS.items()),
initial=models.DEV_NO_SIGNALS),
choices=list(core_enums.WEB_DEV_VIEWS.items()),
initial=core_enums.DEV_NO_SIGNALS),
'web_dev_views_link': forms.URLField(
required=False, label='',
@ -456,7 +457,7 @@ ALL_FIELDS = {
'impl_status_chrome': forms.ChoiceField(
required=False, label='',
choices=list(models.IMPLEMENTATION_STATUS.items())),
choices=list(core_enums.IMPLEMENTATION_STATUS.items())),
'shipped_milestone': forms.IntegerField(
required=False, label='',
@ -943,13 +944,13 @@ DISPLAY_FIELDS_IN_STAGES = {
'Metadata': make_display_specs(
'category', 'feature_type', 'intent_stage', 'accurate_as_of'
),
models.INTENT_INCUBATE: make_display_specs(
core_enums.INTENT_INCUBATE: make_display_specs(
'initial_public_proposal_url', 'explainer_links',
'requires_embedder_support'),
models.INTENT_IMPLEMENT: make_display_specs(
core_enums.INTENT_IMPLEMENT: make_display_specs(
'spec_link', 'standard_maturity', 'api_spec', 'spec_mentors',
'intent_to_implement_url'),
models.INTENT_EXPERIMENT: make_display_specs(
core_enums.INTENT_EXPERIMENT: make_display_specs(
'devtrial_instructions', 'doc_links',
'interop_compat_risks',
'safari_views', 'safari_views_link', 'safari_views_notes',
@ -964,13 +965,13 @@ DISPLAY_FIELDS_IN_STAGES = {
'dt_milestone_desktop_start', 'dt_milestone_android_start',
'dt_milestone_ios_start',
'flag_name'),
models.INTENT_IMPLEMENT_SHIP: make_display_specs(
core_enums.INTENT_IMPLEMENT_SHIP: make_display_specs(
'launch_bug_url',
'tag_review', 'tag_review_status',
'webview_risks',
'measurement', 'prefixed', 'non_oss_deps',
),
models.INTENT_EXTEND_TRIAL: make_display_specs(
core_enums.INTENT_EXTEND_TRIAL: make_display_specs(
'experiment_goals', 'experiment_risks',
'experiment_extension_reason', 'ongoing_constraints',
'origin_trial_feedback_url', 'intent_to_experiment_url',
@ -982,12 +983,12 @@ DISPLAY_FIELDS_IN_STAGES = {
'ot_milestone_webview_start', 'ot_milestone_webview_end',
'experiment_timeline', # Deprecated
),
models.INTENT_SHIP: make_display_specs(
core_enums.INTENT_SHIP: make_display_specs(
'finch_url', 'anticipated_spec_changes',
'shipped_milestone', 'shipped_android_milestone',
'shipped_ios_milestone', 'shipped_webview_milestone',
'intent_to_ship_url', 'i2s_lgtms'),
models.INTENT_SHIPPED: make_display_specs(
core_enums.INTENT_SHIPPED: make_display_specs(
),
'Misc': make_display_specs(
),

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

@ -13,12 +13,10 @@
# See the License for the specific language governing permissions and
# limitations under the License.
# from google.appengine.api import users
from framework import users
from internals import core_enums
from internals import models
from framework import basehandlers
from framework import permissions
@ -65,21 +63,21 @@ class IntentEmailPreviewHandler(basehandlers.FlaskHandler):
def compute_subject_prefix(self, feature, intent_stage):
"""Return part of the subject line for an intent email."""
if intent_stage == models.INTENT_INCUBATE:
if feature.feature_type == models.FEATURE_TYPE_DEPRECATION_ID:
if intent_stage == core_enums.INTENT_INCUBATE:
if feature.feature_type == core_enums.FEATURE_TYPE_DEPRECATION_ID:
return 'Intent to Deprecate and Remove'
elif intent_stage == models.INTENT_IMPLEMENT:
elif intent_stage == core_enums.INTENT_IMPLEMENT:
return 'Intent to Prototype'
elif intent_stage == models.INTENT_EXPERIMENT:
elif intent_stage == core_enums.INTENT_EXPERIMENT:
return 'Ready for Trial'
elif intent_stage == models.INTENT_EXTEND_TRIAL:
if feature.feature_type == models.FEATURE_TYPE_DEPRECATION_ID:
elif intent_stage == core_enums.INTENT_EXTEND_TRIAL:
if feature.feature_type == core_enums.FEATURE_TYPE_DEPRECATION_ID:
return 'Request for Deprecation Trial'
else:
return 'Intent to Experiment'
elif intent_stage == models.INTENT_SHIP:
elif intent_stage == core_enums.INTENT_SHIP:
return 'Intent to Ship'
elif intent_stage == models.INTENT_REMOVED:
elif intent_stage == core_enums.INTENT_REMOVED:
return 'Intent to Extend Deprecation Trial'
return 'Intent stage "%s"' % models.INTENT_STAGES[intent_stage]
return 'Intent stage "%s"' % core_enums.INTENT_STAGES[intent_stage]

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

@ -22,6 +22,7 @@ import werkzeug
import html5lib
from pages import intentpreview
from internals import core_enums
from internals import models
test_app = flask.Flask(__name__)
@ -33,11 +34,11 @@ class IntentEmailPreviewHandlerTest(testing_config.CustomTestCase):
self.feature_1 = models.Feature(
name='feature one', summary='sum', owner=['user1@google.com'],
category=1, visibility=1, standardization=1, web_dev_views=1,
impl_status_chrome=1, intent_stage=models.INTENT_IMPLEMENT)
impl_status_chrome=1, intent_stage=core_enums.INTENT_IMPLEMENT)
self.feature_1.put()
self.request_path = '/admin/features/launch/%d/%d?intent' % (
models.INTENT_SHIP, self.feature_1.key.integer_id())
core_enums.INTENT_SHIP, self.feature_1.key.integer_id())
self.handler = intentpreview.IntentEmailPreviewHandler()
def tearDown(self):
@ -84,7 +85,7 @@ class IntentEmailPreviewHandlerTest(testing_config.CustomTestCase):
feature_id = self.feature_1.key.integer_id()
with test_app.test_request_context(self.request_path):
page_data = self.handler.get_page_data(
feature_id, self.feature_1, models.INTENT_IMPLEMENT)
feature_id, self.feature_1, core_enums.INTENT_IMPLEMENT)
self.assertEqual(
'http://localhost/feature/%d' % feature_id,
page_data['default_url'])
@ -100,7 +101,7 @@ class IntentEmailPreviewHandlerTest(testing_config.CustomTestCase):
feature_id = self.feature_1.key.integer_id()
with test_app.test_request_context(self.request_path):
page_data = self.handler.get_page_data(
feature_id, self.feature_1, models.INTENT_SHIP)
feature_id, self.feature_1, core_enums.INTENT_SHIP)
self.assertEqual(
'http://localhost/feature/%d' % feature_id,
page_data['default_url'])
@ -114,70 +115,70 @@ class IntentEmailPreviewHandlerTest(testing_config.CustomTestCase):
self.assertEqual(
'Intent stage "None"',
self.handler.compute_subject_prefix(
self.feature_1, models.INTENT_NONE))
self.feature_1, core_enums.INTENT_NONE))
self.assertEqual(
'Intent stage "Start incubating"',
self.handler.compute_subject_prefix(
self.feature_1, models.INTENT_INCUBATE))
self.feature_1, core_enums.INTENT_INCUBATE))
self.assertEqual(
'Intent to Prototype',
self.handler.compute_subject_prefix(
self.feature_1, models.INTENT_IMPLEMENT))
self.feature_1, core_enums.INTENT_IMPLEMENT))
self.assertEqual(
'Ready for Trial',
self.handler.compute_subject_prefix(
self.feature_1, models.INTENT_EXPERIMENT))
self.feature_1, core_enums.INTENT_EXPERIMENT))
self.assertEqual(
'Intent stage "Evaluate readiness to ship"',
self.handler.compute_subject_prefix(
self.feature_1, models.INTENT_IMPLEMENT_SHIP))
self.feature_1, core_enums.INTENT_IMPLEMENT_SHIP))
self.assertEqual(
'Intent to Experiment',
self.handler.compute_subject_prefix(
self.feature_1, models.INTENT_EXTEND_TRIAL))
self.feature_1, core_enums.INTENT_EXTEND_TRIAL))
self.assertEqual(
'Intent to Ship',
self.handler.compute_subject_prefix(
self.feature_1, models.INTENT_SHIP))
self.feature_1, core_enums.INTENT_SHIP))
self.assertEqual(
'Intent to Extend Deprecation Trial',
self.handler.compute_subject_prefix(
self.feature_1, models.INTENT_REMOVED))
self.feature_1, core_enums.INTENT_REMOVED))
self.assertEqual(
'Intent stage "Shipped"',
self.handler.compute_subject_prefix(
self.feature_1, models.INTENT_SHIPPED))
self.feature_1, core_enums.INTENT_SHIPPED))
self.assertEqual(
'Intent stage "Parked"',
self.handler.compute_subject_prefix(
self.feature_1, models.INTENT_PARKED))
self.feature_1, core_enums.INTENT_PARKED))
def test_compute_subject_prefix__deprecate_feature(self):
"""We offer users the correct subject line for each intent stage."""
self.feature_1.feature_type = models.FEATURE_TYPE_DEPRECATION_ID
self.feature_1.feature_type = core_enums.FEATURE_TYPE_DEPRECATION_ID
self.assertEqual(
'Intent stage "None"',
self.handler.compute_subject_prefix(
self.feature_1, models.INTENT_NONE))
self.feature_1, core_enums.INTENT_NONE))
self.assertEqual(
'Intent to Deprecate and Remove',
self.handler.compute_subject_prefix(
self.feature_1, models.INTENT_INCUBATE))
self.feature_1, core_enums.INTENT_INCUBATE))
self.assertEqual(
'Request for Deprecation Trial',
self.handler.compute_subject_prefix(
self.feature_1, models.INTENT_EXTEND_TRIAL))
self.feature_1, core_enums.INTENT_EXTEND_TRIAL))
class IntentEmailPreviewTemplateTest(testing_config.CustomTestCase):
@ -189,11 +190,11 @@ class IntentEmailPreviewTemplateTest(testing_config.CustomTestCase):
self.feature_1 = models.Feature(
name='feature one', summary='sum', owner=['user1@google.com'],
category=1, visibility=1, standardization=1, web_dev_views=1,
impl_status_chrome=1, intent_stage=models.INTENT_IMPLEMENT)
impl_status_chrome=1, intent_stage=core_enums.INTENT_IMPLEMENT)
self.feature_1.put()
self.request_path = '/admin/features/launch/%d/%d?intent' % (
models.INTENT_SHIP, self.feature_1.key.integer_id())
core_enums.INTENT_SHIP, self.feature_1.key.integer_id())
self.handler = self.HANDLER_CLASS()
self.feature_id = self.feature_1.key.integer_id()
@ -201,7 +202,7 @@ class IntentEmailPreviewTemplateTest(testing_config.CustomTestCase):
self.template_data = self.handler.get_template_data(
self.feature_id)
page_data = self.handler.get_page_data(
self.feature_id, self.feature_1, models.INTENT_IMPLEMENT)
self.feature_id, self.feature_1, core_enums.INTENT_IMPLEMENT)
self.template_data.update(page_data)
self.template_data['nonce'] = 'fake nonce'