def test_setting_signature_doesnt_change_canonical_json(self): recipe = RecipeFactory(name='unchanged', signed=False) serialized = recipe.canonical_json() recipe.signature = SignatureFactory() recipe.save() assert recipe.signature is not None assert recipe.canonical_json() == serialized
def test_cant_change_signature_and_other_fields(self): recipe = RecipeFactory(name='unchanged', signed=False) recipe.signature = SignatureFactory() recipe.name = 'changed' with pytest.raises(ValidationError) as exc_info: recipe.save() assert exc_info.value.message == 'Signatures must change alone'
def test_setting_signature_doesnt_change_canonical_json(self): recipe = RecipeFactory(name="unchanged", signed=False) serialized = recipe.canonical_json() recipe.signature = SignatureFactory() recipe.save() assert recipe.signature is not None assert recipe.canonical_json() == serialized
def test_disabling_recipe_removes_approval(self): recipe = RecipeFactory(approver=UserFactory(), enabled=True) assert recipe.is_approved recipe.enabled = False recipe.save() recipe.refresh_from_db() assert not recipe.is_approved
def test_revision_id_increments(self): """Ensure that the revision id is incremented on each save""" recipe = RecipeFactory() # The factory saves a couple times so revision id is not 0 revision_id = recipe.revision_id recipe.save() assert recipe.revision_id == revision_id + 1
def test_latest_revision_not_created_if_no_changes(self): """ latest_revision should remain fixed if a recipe is saved with no changes. """ recipe = RecipeFactory() # The factory saves a couple times so revision id is not 0 revision_id = recipe.latest_revision.id recipe.save() assert recipe.latest_revision.id == revision_id
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.name = 'changed' recipe.save() 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_revision_id_doesnt_increment_if_no_changes(self): """ revision_id should not increment if a recipe is saved with no changes. """ recipe = RecipeFactory() # The factory saves a couple times so revision id is not 0 revision_id = recipe.revision_id recipe.save() assert recipe.revision_id == revision_id
def test_update_signature(self, mocker): # Mock the Autographer mock_autograph = mocker.patch('normandy.recipes.models.Autographer') mock_autograph.return_value.sign_data.return_value = [ {'signature': 'fake signature'}, ] recipe = RecipeFactory(signed=False) recipe.update_signature() recipe.save() assert recipe.signature is not None assert recipe.signature.signature == 'fake signature'
def test_signature_is_cleared_if_autograph_unavailable(self, mocker): # Mock the Autographer 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.name = 'changed' recipe.save() assert recipe.name == 'changed' assert recipe.signature is not original_signature assert recipe.signature is None
def test_revision_id_doesnt_change_if_no_changes(self): """ revision_id should not increment if a recipe is saved with no changes. """ recipe = RecipeFactory() # The factory saves a couple times so revision id is not 0 revision_id = recipe.revision_id recipe.save() assert recipe.revision_id == revision_id
def test_signature_is_updated_if_autograph_available(self, mocker): # Mock the Autographer mock_autograph = mocker.patch('normandy.recipes.models.Autographer') mock_autograph.return_value.sign_data.return_value = [ {'signature': 'fake signature'}, ] recipe = RecipeFactory(name='unchanged', signed=True) original_signature = recipe.signature recipe.name = 'changed' recipe.save() assert recipe.name == 'changed' assert recipe.signature is not original_signature assert recipe.signature.signature == 'fake signature'
def test_skip_last_updated(self): # set last_updated to avoid timestamp precision problems recipe = RecipeFactory(name='one', last_updated=datetime.now() - timedelta(30)) last_updated_1 = recipe.last_updated recipe.name = 'two' recipe.save() last_updated_2 = recipe.last_updated recipe.name = 'three' recipe.save(skip_last_updated=True) last_updated_3 = recipe.last_updated assert last_updated_1 != last_updated_2 assert last_updated_2 == last_updated_3
def test_history(self, api_client): with reversion.create_revision(): recipe = RecipeFactory(name='version 1') with reversion.create_revision(): recipe.name = 'version 2' recipe.save() with reversion.create_revision(): recipe.name = 'version 3' recipe.save() 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_signatures_update_correctly_on_enable(self, mocker): mock_autograph = mocker.patch('normandy.recipes.models.Autographer') def fake_sign(datas): sigs = [] for d in datas: sigs.append({'signature': hashlib.sha256(d).hexdigest()}) return sigs mock_autograph.return_value.sign_data.side_effect = fake_sign recipe = RecipeFactory(enabled=False, signed=False) recipe.enabled = True recipe.save() recipe.refresh_from_db() assert recipe.signature is not None assert recipe.signature.signature == hashlib.sha256(recipe.canonical_json()).hexdigest()
def test_signatures_update_correctly_on_enable(self, mocker): mock_autograph = mocker.patch('normandy.recipes.models.Autographer') def fake_sign(datas): sigs = [] for d in datas: sigs.append({'signature': hashlib.sha256(d).hexdigest()}) return sigs mock_autograph.return_value.sign_data.side_effect = fake_sign recipe = RecipeFactory(enabled=False, signed=False) recipe.enabled = True recipe.save() recipe.refresh_from_db() assert recipe.signature is not None assert recipe.signature.signature == hashlib.sha256( recipe.canonical_json()).hexdigest()
def test_update_signature(self, mocker, mock_logger): # Mock the Autographer mock_autograph = mocker.patch('normandy.recipes.models.Autographer') mock_autograph.return_value.sign_data.return_value = [ { 'signature': 'fake signature' }, ] recipe = RecipeFactory(signed=False) recipe.update_signature() mock_logger.info.assert_called_with( Whatever.contains(str(recipe.id)), extra={ 'code': INFO_REQUESTING_RECIPE_SIGNATURES, 'recipe_ids': [recipe.id] }) recipe.save() assert recipe.signature is not None assert recipe.signature.signature == 'fake signature'
def test_cannot_enable_unapproved_recipe(self): recipe = RecipeFactory(enabled=False) with pytest.raises(Recipe.NotApproved): recipe.enabled = True recipe.save()