def test_history(self, api_client): recipe = RecipeFactory(name='version 1') recipe.update(name='version 2') recipe.update(name='version 3') res = api_client.get('/api/v1/recipe/%s/history/' % recipe.id) assert res.data[0]['recipe']['name'] == 'version 3' assert res.data[1]['recipe']['name'] == 'version 2' assert res.data[2]['recipe']['name'] == 'version 1'
def test_recipe_doesnt_update_when_clean(self): channel = ChannelFactory() recipe = RecipeFactory(name='my name', channels=[channel]) revision_id = recipe.revision_id last_updated = recipe.last_updated recipe.update(name='my name', channels=[channel]) assert revision_id == recipe.revision_id assert last_updated == recipe.last_updated
def test_signature_is_cleared_if_autograph_unavailable(self, mocker): # Mock the Autographer to return an error mock_autograph = mocker.patch('normandy.recipes.models.Autographer') mock_autograph.return_value.sign_data.side_effect = ImproperlyConfigured recipe = RecipeFactory(name='unchanged', signed=True) original_signature = recipe.signature recipe.update(name='changed') assert recipe.name == 'changed' assert recipe.signature is not original_signature assert recipe.signature is None
def test_signature_is_updated_if_autograph_available( self, mocked_autograph): recipe = RecipeFactory(name='unchanged') original_signature = recipe.signature assert original_signature is not None recipe.update(name='changed') assert recipe.name == 'changed' assert recipe.signature is not original_signature expected_sig = hashlib.sha256(recipe.canonical_json()).hexdigest() assert recipe.signature.signature == expected_sig
def test_recipe_update_partial(self): a1 = ActionFactory() recipe = RecipeFactory( name='unchanged', action=a1, arguments={'message': 'something'}, extra_filter_expression='something !== undefined') a2 = ActionFactory() c = ChannelFactory(slug='beta') recipe.update(name='changed', action=a2, channels=[c]) assert recipe.action == a2 assert recipe.name == 'changed' assert recipe.arguments == {'message': 'something'} assert recipe.filter_expression == ( "(normandy.channel in ['beta']) && " "(something !== undefined)")
def test_filter_expression(self): channel1 = ChannelFactory(slug='beta', name='Beta') channel2 = ChannelFactory(slug='release', name='Release') country1 = CountryFactory(code='US', name='USA') country2 = CountryFactory(code='CA', name='Canada') locale1 = LocaleFactory(code='en-US', name='English (US)') locale2 = LocaleFactory(code='fr-CA', name='French (CA)') r = RecipeFactory() assert r.filter_expression == '' r = RecipeFactory(channels=[channel1]) assert r.filter_expression == "normandy.channel in ['beta']" r.update(channels=[channel1, channel2]) assert r.filter_expression == "normandy.channel in ['beta', 'release']" r = RecipeFactory(countries=[country1]) assert r.filter_expression == "normandy.country in ['US']" r.update(countries=[country1, country2]) assert r.filter_expression == "normandy.country in ['CA', 'US']" r = RecipeFactory(locales=[locale1]) assert r.filter_expression == "normandy.locale in ['en-US']" r.update(locales=[locale1, locale2]) assert r.filter_expression == "normandy.locale in ['en-US', 'fr-CA']" r = RecipeFactory(extra_filter_expression='2 + 2 == 4') assert r.filter_expression == '2 + 2 == 4' r.update(channels=[channel1], countries=[country1], locales=[locale1]) assert r.filter_expression == ("(normandy.locale in ['en-US']) && " "(normandy.country in ['US']) && " "(normandy.channel in ['beta']) && " "(2 + 2 == 4)")
def test_recipe_update_locales(self): l1 = LocaleFactory(code='en-US') recipe = RecipeFactory(locales=[l1]) l2 = LocaleFactory(code='fr-CA') recipe.update(locales=[l2]) assert recipe.locales.count() == 1 assert list(recipe.locales.all()) == [l2] recipe.update(locales=[l1, l2]) locales = list(recipe.locales.all()) assert recipe.locales.count() == 2 assert l1 in locales assert l2 in locales recipe.update(locales=[]) assert recipe.locales.count() == 0
def test_recipe_update_countries(self): c1 = CountryFactory(code='CA') recipe = RecipeFactory(countries=[c1]) c2 = CountryFactory(code='US') recipe.update(countries=[c2]) assert recipe.countries.count() == 1 assert list(recipe.countries.all()) == [c2] recipe.update(countries=[c1, c2]) countries = list(recipe.countries.all()) assert recipe.countries.count() == 2 assert c1 in countries assert c2 in countries recipe.update(countries=[]) assert recipe.countries.count() == 0
def test_recipe_update_channels(self): c1 = ChannelFactory(slug='beta') recipe = RecipeFactory(channels=[c1]) c2 = ChannelFactory(slug='release') recipe.update(channels=[c2]) assert recipe.channels.count() == 1 assert list(recipe.channels.all()) == [c2] recipe.update(channels=[c1, c2]) channels = list(recipe.channels.all()) assert recipe.channels.count() == 2 assert c1 in channels assert c2 in channels recipe.update(channels=[]) assert recipe.channels.count() == 0
def test_revision_id_changes(self): """Ensure that the revision id is incremented on each save""" recipe = RecipeFactory() revision_id = recipe.revision_id recipe.update(action=ActionFactory()) assert recipe.revision_id != revision_id
def test_update_logging(self, mock_logger): recipe = RecipeFactory(name='my name') recipe.update(name='my name', force=True) mock_logger.info.assert_called_with( Whatever.contains(str(recipe.id)), extra={'code': INFO_CREATE_REVISION})
def test_recipe_force_update(self): recipe = RecipeFactory(name='my name') revision_id = recipe.revision_id recipe.update(name='my name', force=True) assert revision_id != recipe.revision_id
def test_recipe_update_arguments(self): recipe = RecipeFactory(arguments_json='') recipe.update(arguments={'something': 'value'}) assert recipe.arguments_json == '{"something": "value"}'
def test_cant_change_signature_and_other_fields(self): recipe = RecipeFactory(name='unchanged', signed=False) recipe.signature = SignatureFactory() with pytest.raises(ValidationError) as exc_info: recipe.update(name='changed') assert exc_info.value.message == 'Signatures must change alone'