Update processes API to use FeatureEntry entities (#2438)
This commit is contained in:
Родитель
e2ce1d405e
Коммит
58e1dc4cf6
|
@ -26,7 +26,7 @@ class ProcessesAPI(basehandlers.APIHandler):
|
|||
"""Return the process of the feature."""
|
||||
# Load feature directly from NDB so as to never get a stale cached copy.
|
||||
feature_id = kwargs['feature_id']
|
||||
f = core_models.Feature.get_by_id(feature_id)
|
||||
f = core_models.FeatureEntry.get_by_id(feature_id)
|
||||
if f is None:
|
||||
self.abort(404, msg=f'Feature {feature_id} not found')
|
||||
|
||||
|
@ -44,13 +44,13 @@ class ProgressAPI(basehandlers.APIHandler):
|
|||
def do_get(self, **kwargs):
|
||||
"""Return the progress of the feature."""
|
||||
feature_id = kwargs['feature_id']
|
||||
f = core_models.Feature.get_by_id(feature_id)
|
||||
if f is None:
|
||||
fe = core_models.FeatureEntry.get_by_id(feature_id)
|
||||
if fe is None:
|
||||
self.abort(404, msg=f'Feature {feature_id} not found')
|
||||
|
||||
stages = core_models.Stage.get_feature_stages(fe.key.integer_id())
|
||||
progress_so_far = {}
|
||||
for progress_item, detector in list(processes.PROGRESS_DETECTORS.items()):
|
||||
detected = detector(f)
|
||||
detected = detector(fe, stages)
|
||||
if detected:
|
||||
progress_so_far[progress_item] = str(detected)
|
||||
return progress_so_far
|
||||
|
|
|
@ -18,6 +18,7 @@ import testing_config # Must be imported before the module under test.
|
|||
import flask
|
||||
|
||||
from api import processes_api
|
||||
from internals import core_enums
|
||||
from internals import core_models
|
||||
from internals import processes
|
||||
from internals import core_enums
|
||||
|
@ -28,15 +29,22 @@ test_app = flask.Flask(__name__)
|
|||
class ProcessesAPITest(testing_config.CustomTestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.feature_1 = core_models.Feature(
|
||||
name='feature one', summary='sum', category=1)
|
||||
self.feature_1 = core_models.FeatureEntry(
|
||||
name='feature one', summary='sum', category=1, feature_type=0)
|
||||
self.feature_1.put()
|
||||
self.feature_id = self.feature_1.key.integer_id()
|
||||
|
||||
stage_types = [110, 120, 130, 140, 150, 151, 160]
|
||||
self.stages: list[core_models.Stage] = []
|
||||
for s_type in stage_types:
|
||||
stage = core_models.Stage(feature_id=self.feature_id, stage_type=s_type)
|
||||
stage.put()
|
||||
self.stages.append(stage)
|
||||
self.handler = processes_api.ProcessesAPI()
|
||||
self.request_path = f'/api/v0/features/{self.feature_id}/process'
|
||||
|
||||
def tearDown(self):
|
||||
for stage in self.stages:
|
||||
stage.key.delete()
|
||||
self.feature_1.key.delete()
|
||||
|
||||
def test_get__default_feature_type(self):
|
||||
|
@ -82,17 +90,33 @@ class ProcessesAPITest(testing_config.CustomTestCase):
|
|||
class ProgressAPITest(testing_config.CustomTestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.feature_1 = core_models.Feature(
|
||||
self.feature_1 = core_models.FeatureEntry(
|
||||
name='feature one', summary='sum Z',
|
||||
owner=['feature_owner@example.com'],
|
||||
ready_for_trial_url='fake ready for trial url',
|
||||
intent_to_experiment_url='fake intent to experiment url',
|
||||
owner_emails=['feature_owner@example.com'],
|
||||
spec_link='fake spec link', category=1, web_dev_views=1,
|
||||
impl_status_chrome=5, intent_stage=core_enums.INTENT_IMPLEMENT,
|
||||
shipped_milestone=1)
|
||||
feature_type=0)
|
||||
self.feature_1.put()
|
||||
self.feature_id = self.feature_1.key.integer_id()
|
||||
|
||||
stage_types = [110, 120, 130, 140, 150, 151, 160]
|
||||
self.stages: list[core_models.Stage] = []
|
||||
for s_type in stage_types:
|
||||
stage = core_models.Stage(feature_id=self.feature_id, stage_type=s_type)
|
||||
if s_type == 120:
|
||||
stage.intent_thread_url = 'https://example.com/prototype'
|
||||
elif s_type == 130:
|
||||
stage.announcement_url = 'https://example.com/ready_for_trial'
|
||||
elif s_type == 150:
|
||||
stage.intent_thread_url = 'https://example.com/ot'
|
||||
elif s_type == 151:
|
||||
stage.intent_thread_url = 'https://example.com/extend'
|
||||
elif s_type == 160:
|
||||
stage.milestones = core_models.MilestoneSet(desktop_first=1)
|
||||
stage.intent_thread_url = 'https://example.com/ship'
|
||||
stage.put()
|
||||
self.stages.append(stage)
|
||||
|
||||
self.handler = processes_api.ProgressAPI()
|
||||
self.request_path = f'/api/v0/features/{self.feature_id}/progress'
|
||||
|
||||
|
@ -110,8 +134,10 @@ class ProgressAPITest(testing_config.CustomTestCase):
|
|||
'Draft API spec': 'fake spec link',
|
||||
'Estimated target milestone': 'True',
|
||||
'Final target milestone': 'True',
|
||||
'Intent to Experiment email': 'fake intent to experiment url',
|
||||
'Ready for Trial email': 'fake ready for trial url',
|
||||
'Intent to Prototype email': 'https://example.com/prototype',
|
||||
'Intent to Experiment email': 'https://example.com/ot',
|
||||
'Ready for Trial email': 'https://example.com/ready_for_trial',
|
||||
'Intent to Ship email': 'https://example.com/ship',
|
||||
'Spec link': 'fake spec link',
|
||||
'Web developer signals': 'True',
|
||||
}, actual)
|
||||
|
|
|
@ -17,7 +17,6 @@ import collections
|
|||
|
||||
from internals import approval_defs
|
||||
from internals import core_enums
|
||||
from internals import core_models
|
||||
|
||||
|
||||
Process = collections.namedtuple(
|
||||
|
@ -523,99 +522,94 @@ def review_is_done(status):
|
|||
# be used as a link URL.
|
||||
PROGRESS_DETECTORS = {
|
||||
'Initial public proposal':
|
||||
lambda f: f.initial_public_proposal_url,
|
||||
lambda f, _: f.initial_public_proposal_url,
|
||||
|
||||
'Explainer':
|
||||
lambda f: f.explainer_links and f.explainer_links[0],
|
||||
lambda f, _: f.explainer_links and f.explainer_links[0],
|
||||
|
||||
'Security review issues addressed':
|
||||
lambda f: review_is_done(f.security_review_status),
|
||||
lambda f, _: review_is_done(f.security_review_status),
|
||||
|
||||
'Privacy review issues addressed':
|
||||
lambda f: review_is_done(f.privacy_review_status),
|
||||
lambda f, _: review_is_done(f.privacy_review_status),
|
||||
|
||||
'Intent to Prototype email':
|
||||
lambda f: f.intent_to_implement_url,
|
||||
lambda f, stages: (
|
||||
core_enums.STAGE_TYPES_PROTOTYPE[f.feature_type] and
|
||||
stages[core_enums.STAGE_TYPES_PROTOTYPE[f.feature_type]].intent_thread_url),
|
||||
|
||||
'Intent to Ship email':
|
||||
lambda f: f.intent_to_ship_url,
|
||||
lambda f, stages: (core_enums.STAGE_TYPES_SHIPPING[f.feature_type] and
|
||||
stages[core_enums.STAGE_TYPES_SHIPPING[f.feature_type]].intent_thread_url),
|
||||
|
||||
'Ready for Trial email':
|
||||
lambda f: f.ready_for_trial_url,
|
||||
lambda f, stages: (core_enums.STAGE_TYPES_DEV_TRIAL[f.feature_type] and
|
||||
stages[core_enums.STAGE_TYPES_DEV_TRIAL[f.feature_type]].announcement_url),
|
||||
|
||||
'Intent to Experiment email':
|
||||
lambda f: f.intent_to_experiment_url,
|
||||
|
||||
'One LGTM on Intent to Experiment':
|
||||
lambda f: f.i2e_lgtms,
|
||||
|
||||
'One LGTM on Request for Deprecation Trial':
|
||||
lambda f: f.i2e_lgtms,
|
||||
|
||||
'Three LGTMs on Intent to Ship':
|
||||
lambda f: f.i2s_lgtms and len(f.i2s_lgtms) >= 3,
|
||||
lambda f, stages: (core_enums.STAGE_TYPES_ORIGIN_TRIAL[f.feature_type] and
|
||||
stages[core_enums.STAGE_TYPES_ORIGIN_TRIAL[f.feature_type]].intent_thread_url),
|
||||
|
||||
'Samples':
|
||||
lambda f: f.sample_links and f.sample_links[0],
|
||||
lambda f, _: f.sample_links and f.sample_links[0],
|
||||
|
||||
'Doc links':
|
||||
lambda f: f.doc_links and f.doc_links[0],
|
||||
lambda f, _: f.doc_links and f.doc_links[0],
|
||||
|
||||
'Spec link':
|
||||
lambda f: f.spec_link,
|
||||
lambda f, _: f.spec_link,
|
||||
|
||||
'Draft API spec':
|
||||
lambda f: f.spec_link,
|
||||
lambda f, _: f.spec_link,
|
||||
|
||||
'API spec':
|
||||
lambda f: f.api_spec,
|
||||
lambda f, _: f.api_spec,
|
||||
|
||||
'Spec mentor':
|
||||
lambda f: f.spec_mentors,
|
||||
lambda f, _: f.spec_mentor_emails,
|
||||
|
||||
'TAG review requested':
|
||||
lambda f: f.tag_review,
|
||||
lambda f, _: f.tag_review,
|
||||
|
||||
'TAG review issues addressed':
|
||||
lambda f: review_is_done(f.tag_review_status),
|
||||
lambda f, _: review_is_done(f.tag_review_status),
|
||||
|
||||
'Web developer signals':
|
||||
lambda f: bool(f.web_dev_views and
|
||||
f.web_dev_views != core_enums.DEV_NO_SIGNALS),
|
||||
lambda f, _: bool(f.web_dev_views and
|
||||
f.web_dev_views != core_enums.DEV_NO_SIGNALS),
|
||||
|
||||
'Vendor signals':
|
||||
lambda f: bool(
|
||||
lambda f, _: bool(
|
||||
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
|
||||
f.safari_views != core_enums.NO_PUBLIC_SIGNALS),
|
||||
|
||||
'Updated vendor signals':
|
||||
lambda f: bool(
|
||||
lambda f, _: bool(
|
||||
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
|
||||
f.safari_views != core_enums.NO_PUBLIC_SIGNALS),
|
||||
|
||||
'Final vendor signals':
|
||||
lambda f: bool(
|
||||
lambda f, _: bool(
|
||||
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
|
||||
f.safari_views != core_enums.NO_PUBLIC_SIGNALS),
|
||||
|
||||
'Estimated target milestone':
|
||||
lambda f: bool(f.shipped_milestone),
|
||||
lambda f, stages: bool(core_enums.STAGE_TYPES_SHIPPING[f.feature_type] and
|
||||
stages[core_enums.STAGE_TYPES_SHIPPING[f.feature_type]].milestones.desktop_first),
|
||||
|
||||
'Final target milestone':
|
||||
lambda f: bool(f.shipped_milestone),
|
||||
lambda f, stages: bool(core_enums.STAGE_TYPES_SHIPPING[f.feature_type] and
|
||||
stages[core_enums.STAGE_TYPES_SHIPPING[f.feature_type]].milestones.desktop_first),
|
||||
|
||||
'Code in Chromium':
|
||||
lambda f: f.impl_status_chrome in (
|
||||
lambda f, _: f.impl_status_chrome in (
|
||||
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),
|
||||
lambda f, _: bool(f.motivation),
|
||||
|
||||
'Code removed':
|
||||
lambda f: f.impl_status_chrome == core_enums.REMOVED,
|
||||
lambda f, _: f.impl_status_chrome == core_enums.REMOVED,
|
||||
}
|
||||
|
|
|
@ -141,140 +141,130 @@ class ProcessesWellFormedTest(testing_config.CustomTestCase):
|
|||
class ProgressDetectorsTest(testing_config.CustomTestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.feature_1 = core_models.Feature(
|
||||
self.feature_1 = core_models.FeatureEntry(
|
||||
name='feature one', summary='sum', category=1,
|
||||
intent_stage=core_enums.INTENT_IMPLEMENT)
|
||||
intent_stage=core_enums.INTENT_IMPLEMENT, feature_type=0)
|
||||
self.feature_1.put()
|
||||
stage_types = [110, 120, 130, 140, 150, 151, 160]
|
||||
self.stages: list[core_models.Stage] = []
|
||||
for s_type in stage_types:
|
||||
stage = core_models.Stage(feature_id=self.feature_1.key.integer_id(),
|
||||
stage_type=s_type)
|
||||
stage.put()
|
||||
self.stages.append(stage)
|
||||
self.stages_dict = core_models.Stage.get_feature_stages(
|
||||
self.feature_1.key.integer_id())
|
||||
|
||||
def tearDown(self):
|
||||
self.feature_1.key.delete()
|
||||
for stage in self.stages:
|
||||
stage.key.delete()
|
||||
|
||||
def test_initial_public_proposal_url(self):
|
||||
detector = processes.PROGRESS_DETECTORS['Initial public proposal']
|
||||
self.assertFalse(detector(self.feature_1))
|
||||
self.assertFalse(detector(self.feature_1, self.stages_dict))
|
||||
self.feature_1.initial_public_proposal_url = 'http://example.com'
|
||||
self.assertTrue(detector(self.feature_1))
|
||||
self.assertTrue(detector(self.feature_1, self.stages_dict))
|
||||
|
||||
def test_explainer(self):
|
||||
detector = processes.PROGRESS_DETECTORS['Explainer']
|
||||
self.assertFalse(detector(self.feature_1))
|
||||
self.assertFalse(detector(self.feature_1, self.stages_dict))
|
||||
self.feature_1.explainer_links = ['http://example.com']
|
||||
self.assertTrue(detector(self.feature_1))
|
||||
self.assertTrue(detector(self.feature_1, self.stages_dict))
|
||||
|
||||
def test_security_review_completed(self):
|
||||
detector = processes.PROGRESS_DETECTORS['Security review issues addressed']
|
||||
self.assertFalse(detector(self.feature_1))
|
||||
self.assertFalse(detector(self.feature_1, self.stages_dict))
|
||||
self.feature_1.security_review_status = core_enums.REVIEW_ISSUES_ADDRESSED
|
||||
self.assertTrue(detector(self.feature_1))
|
||||
self.assertTrue(detector(self.feature_1, self.stages_dict))
|
||||
|
||||
def test_privacy_review_completed(self):
|
||||
detector = processes.PROGRESS_DETECTORS['Privacy review issues addressed']
|
||||
self.assertFalse(detector(self.feature_1))
|
||||
self.assertFalse(detector(self.feature_1, self.stages_dict))
|
||||
self.feature_1.privacy_review_status = core_enums.REVIEW_ISSUES_ADDRESSED
|
||||
self.assertTrue(detector(self.feature_1))
|
||||
self.assertTrue(detector(self.feature_1, self.stages_dict))
|
||||
|
||||
def test_intent_to_prototype_email(self):
|
||||
detector = processes.PROGRESS_DETECTORS['Intent to Prototype email']
|
||||
self.assertFalse(detector(self.feature_1))
|
||||
self.feature_1.intent_to_implement_url = 'http://example.com'
|
||||
self.assertTrue(detector(self.feature_1))
|
||||
self.assertFalse(detector(self.feature_1, self.stages_dict))
|
||||
self.stages_dict[120].intent_thread_url = 'http://example.com/prototype'
|
||||
self.assertTrue(detector(self.feature_1, self.stages_dict))
|
||||
|
||||
def test_intent_to_ship_email(self):
|
||||
detector = processes.PROGRESS_DETECTORS['Intent to Ship email']
|
||||
self.assertFalse(detector(self.feature_1))
|
||||
self.feature_1.intent_to_ship_url = 'http://example.com'
|
||||
self.assertTrue(detector(self.feature_1))
|
||||
self.assertFalse(detector(self.feature_1, self.stages_dict))
|
||||
self.stages_dict[160].intent_thread_url = 'http://example.com/ship'
|
||||
self.assertTrue(detector(self.feature_1, self.stages_dict))
|
||||
|
||||
def test_ready_for_trial_email(self):
|
||||
detector = processes.PROGRESS_DETECTORS['Ready for Trial email']
|
||||
self.assertFalse(detector(self.feature_1))
|
||||
self.feature_1.ready_for_trial_url = 'http://example.com'
|
||||
self.assertTrue(detector(self.feature_1))
|
||||
self.assertFalse(detector(self.feature_1, self.stages_dict))
|
||||
self.stages_dict[130].announcement_url = 'http://example.com/trial_ready'
|
||||
self.assertTrue(detector(self.feature_1, self.stages_dict))
|
||||
|
||||
def test_intent_to_experiment_email(self):
|
||||
detector = processes.PROGRESS_DETECTORS['Intent to Experiment email']
|
||||
self.assertFalse(detector(self.feature_1))
|
||||
self.feature_1.intent_to_experiment_url = 'http://example.com'
|
||||
self.assertTrue(detector(self.feature_1))
|
||||
|
||||
def test_one_i2e_lgtm(self):
|
||||
detector = processes.PROGRESS_DETECTORS['One LGTM on Intent to Experiment']
|
||||
self.assertFalse(detector(self.feature_1))
|
||||
self.feature_1.i2e_lgtms = ['api_owner@chromium.org']
|
||||
self.assertTrue(detector(self.feature_1))
|
||||
|
||||
def test_two_i2e_lgtm(self):
|
||||
detector = processes.PROGRESS_DETECTORS[
|
||||
'One LGTM on Request for Deprecation Trial']
|
||||
self.assertFalse(detector(self.feature_1))
|
||||
self.feature_1.i2e_lgtms = ['api_owner@chromium.org']
|
||||
self.assertTrue(detector(self.feature_1))
|
||||
|
||||
def test_three_i2s_lgtm(self):
|
||||
detector = processes.PROGRESS_DETECTORS['Three LGTMs on Intent to Ship']
|
||||
self.assertFalse(detector(self.feature_1))
|
||||
self.feature_1.i2s_lgtms = [
|
||||
'one@chromium.org',
|
||||
'two@chromium.org',
|
||||
'three@chromium.org']
|
||||
self.assertTrue(detector(self.feature_1))
|
||||
self.assertFalse(detector(self.feature_1, self.stages_dict))
|
||||
self.stages_dict[150].intent_thread_url = 'http://example.com/ot'
|
||||
self.assertTrue(detector(self.feature_1, self.stages_dict))
|
||||
|
||||
def test_samples(self):
|
||||
detector = processes.PROGRESS_DETECTORS['Samples']
|
||||
self.assertFalse(detector(self.feature_1))
|
||||
self.assertFalse(detector(self.feature_1, self.stages_dict))
|
||||
self.feature_1.sample_links = ['http://example.com']
|
||||
self.assertTrue(detector(self.feature_1))
|
||||
self.assertTrue(detector(self.feature_1, self.stages_dict))
|
||||
|
||||
def test_doc_links(self):
|
||||
detector = processes.PROGRESS_DETECTORS['Doc links']
|
||||
self.assertFalse(detector(self.feature_1))
|
||||
self.assertFalse(detector(self.feature_1, self.stages_dict))
|
||||
self.feature_1.doc_links = ['http://example.com']
|
||||
self.assertTrue(detector(self.feature_1))
|
||||
self.assertTrue(detector(self.feature_1, self.stages_dict))
|
||||
|
||||
def test_tag_review_requested(self):
|
||||
detector = processes.PROGRESS_DETECTORS['TAG review requested']
|
||||
self.assertFalse(detector(self.feature_1))
|
||||
self.assertFalse(detector(self.feature_1, self.stages_dict))
|
||||
self.feature_1.tag_review = 'http://example.com'
|
||||
self.assertTrue(detector(self.feature_1))
|
||||
self.assertTrue(detector(self.feature_1, self.stages_dict))
|
||||
|
||||
def test_tag_review_completed(self):
|
||||
detector = processes.PROGRESS_DETECTORS['TAG review issues addressed']
|
||||
self.assertFalse(detector(self.feature_1))
|
||||
self.assertFalse(detector(self.feature_1, self.stages_dict))
|
||||
self.feature_1.tag_review_status = core_enums.REVIEW_ISSUES_ADDRESSED
|
||||
self.assertTrue(detector(self.feature_1))
|
||||
self.assertTrue(detector(self.feature_1, self.stages_dict))
|
||||
|
||||
def test_web_dav_signals(self):
|
||||
def test_web_dev_signals(self):
|
||||
detector = processes.PROGRESS_DETECTORS['Web developer signals']
|
||||
self.assertFalse(detector(self.feature_1))
|
||||
self.assertFalse(detector(self.feature_1, self.stages_dict))
|
||||
self.feature_1.web_dev_views = core_enums.PUBLIC_SUPPORT
|
||||
self.assertTrue(detector(self.feature_1))
|
||||
self.assertTrue(detector(self.feature_1, self.stages_dict))
|
||||
|
||||
def test_vendor_signals(self):
|
||||
detector = processes.PROGRESS_DETECTORS['Vendor signals']
|
||||
self.assertFalse(detector(self.feature_1))
|
||||
self.assertFalse(detector(self.feature_1, self.stages_dict))
|
||||
self.feature_1.ff_views = core_enums.PUBLIC_SUPPORT
|
||||
self.assertTrue(detector(self.feature_1))
|
||||
self.assertTrue(detector(self.feature_1, self.stages_dict))
|
||||
|
||||
def test_estimated_target_milestone(self):
|
||||
detector = processes.PROGRESS_DETECTORS['Estimated target milestone']
|
||||
self.assertFalse(detector(self.feature_1))
|
||||
self.feature_1.shipped_milestone = 99
|
||||
self.assertTrue(detector(self.feature_1))
|
||||
self.stages_dict[160].milestones = core_models.MilestoneSet()
|
||||
self.assertFalse(detector(self.feature_1, self.stages_dict))
|
||||
self.stages_dict[160].milestones.desktop_first = 99
|
||||
self.assertTrue(detector(self.feature_1, self.stages_dict))
|
||||
|
||||
def test_code_in_chromium(self):
|
||||
detector = processes.PROGRESS_DETECTORS['Code in Chromium']
|
||||
self.assertFalse(detector(self.feature_1))
|
||||
self.assertFalse(detector(self.feature_1, self.stages_dict))
|
||||
self.feature_1.impl_status_chrome = core_enums.ENABLED_BY_DEFAULT
|
||||
self.assertTrue(detector(self.feature_1))
|
||||
self.assertTrue(detector(self.feature_1, self.stages_dict))
|
||||
|
||||
def test_motivation(self):
|
||||
detector = processes.PROGRESS_DETECTORS['Motivation']
|
||||
self.assertFalse(detector(self.feature_1))
|
||||
self.assertFalse(detector(self.feature_1, self.stages_dict))
|
||||
self.feature_1.motivation = 'test motivation'
|
||||
self.assertTrue(detector(self.feature_1))
|
||||
self.assertTrue(detector(self.feature_1, self.stages_dict))
|
||||
|
||||
def test_code_removed(self):
|
||||
detector = processes.PROGRESS_DETECTORS['Code removed']
|
||||
self.assertFalse(detector(self.feature_1))
|
||||
self.assertFalse(detector(self.feature_1, self.stages_dict))
|
||||
self.feature_1.impl_status_chrome = core_enums.REMOVED
|
||||
self.assertTrue(detector(self.feature_1))
|
||||
self.assertTrue(detector(self.feature_1, self.stages_dict))
|
||||
|
|
Загрузка…
Ссылка в новой задаче