def test_process_insight_category(mocker):
    mocker.patch("robotoff.insights.annotate.get_product",
                 return_value={"categories_tags": []})
    mock = mocker.patch("robotoff.off.update_product")
    # a processed insight exists
    date0 = datetime.utcnow() - timedelta(minutes=10)
    id0, code0 = _create_insight(type="category",
                                 completed_at=date0,
                                 annotation=1)
    # an insight to be processed
    id1, code1 = _create_insight(type="category")
    # run process
    process_insights()
    # insight 0 not touched
    assert ProductInsight.get(id=id0).completed_at == date0
    # insight 1 processed
    insight = ProductInsight.get(id=id1)
    assert insight.completed_at is not None
    assert insight.completed_at <= datetime.utcnow()
    assert insight.annotation == 1
    # update_product calledfor item 1
    mock.assert_called_once_with(
        {
            "code": code1,
            "add_categories": "en:Salmons",
            "comment": f"[robotoff] Adding category 'en:Salmons', ID: {id1}",
        },
        auth=None,
        server_domain=settings.OFF_SERVER_DOMAIN,
    )
Exemplo n.º 2
0
def test_mark_insights():
    now = datetime.utcnow()
    # not automatic
    not_auto = ProductInsightFactory(automatic_processing=False)
    # already marked
    marked = ProductInsightFactory(
        automatic_processing=True,
        annotation=None,
        process_after=now - timedelta(minutes=2),
    )
    # already annotated
    annotated = ProductInsightFactory(automatic_processing=True, annotation=1)
    # ready to be marked
    ready1 = ProductInsightFactory(automatic_processing=True)
    ready2 = ProductInsightFactory(automatic_processing=True)
    # run
    start = datetime.utcnow()
    num_marked = scheduler.mark_insights()
    end = datetime.utcnow()
    ten_min = timedelta(minutes=10)
    # two marked
    assert num_marked == 2
    assert (start + ten_min < ProductInsight.get(id=ready1.id).process_after <
            end + ten_min)
    assert (start + ten_min < ProductInsight.get(id=ready2.id).process_after <
            end + ten_min)
    # other did not change
    assert ProductInsight.get(id=not_auto).process_after is None
    assert ProductInsight.get(id=annotated).process_after is None
    assert ProductInsight.get(id=marked).process_after < start

    # run again should not mark anything more
    num_marked = scheduler.mark_insights()
    assert num_marked == 0
def test_process_insight_update_product_raises(mocker):
    def raise_for_salmons(params, *args, **kwargs):
        if "en:Salmons" in params.values():
            raise Exception("Boom !")
        else:
            return

    mocker.patch("robotoff.insights.annotate.get_product",
                 return_value={"categories_tags": []})
    mock = mocker.patch("robotoff.off.update_product",
                        side_effect=raise_for_salmons)
    # an insight to be processed, that will raise
    id1, code1 = _create_insight(type="category")
    # add another insight that should pass
    id2, code2 = _create_insight(type="category", value_tag="en:Tuna")
    # run process
    start = datetime.utcnow()
    process_insights()
    end = datetime.utcnow()
    # insight1 not marked processed
    insight = ProductInsight.get(id=id1)
    assert insight.completed_at is None
    assert insight.annotation is None
    # but update_product was called
    mock.assert_any_call(
        {
            "code": code1,
            "add_categories": "en:Salmons",
            "comment": f"[robotoff] Adding category 'en:Salmons', ID: {id1}",
        },
        auth=None,
        server_domain=settings.OFF_SERVER_DOMAIN,
    )
    # insight2 processed
    # and update_product was called
    insight = ProductInsight.get(id=id2)
    assert insight.completed_at is not None
    assert start < insight.completed_at < end
    assert insight.annotation == 1
    mock.assert_any_call(
        {
            "code": code2,
            "add_categories": "en:Tuna",
            "comment": f"[robotoff] Adding category 'en:Tuna', ID: {id2}",
        },
        auth=None,
        server_domain=settings.OFF_SERVER_DOMAIN,
    )
    # we add only two calls
    assert mock.call_count == 2
 def test_import_one(self, predictions):
     imported = self._run_import(predictions)
     assert imported == 1
     # no insight created
     assert ProductInsight.select().count() == 1
     inserted = ProductInsight.get(ProductInsight.id != insight_id1)
     assert inserted.value_tag == "en:smoked-salmons"
     assert inserted.server_domain == settings.OFF_SERVER_DOMAIN
     assert not inserted.automatic_processing
 def test_import_auto(self):
     imported = self._run_import([
         neural_prediction("en:smoked-salmons", confidence=0.91, auto=True)
     ])
     assert imported == 1
     # no insight created
     assert ProductInsight.select().count() == 1
     inserted = ProductInsight.get(ProductInsight.id != insight_id1)
     assert inserted.value_tag == "en:smoked-salmons"
     assert inserted.server_domain == settings.OFF_SERVER_DOMAIN
     assert inserted.automatic_processing
def test_process_insight_non_existing_product(mocker):
    mocker.patch("robotoff.insights.annotate.get_product", return_value=None)
    mock = mocker.patch("robotoff.off.update_product")
    # an insight to be processed
    id1, code1 = _create_insight(type="category")
    # run process
    process_insights()
    # insight processed
    insight = ProductInsight.get(id=id1)
    assert insight.completed_at is not None
    assert insight.completed_at <= datetime.utcnow()
    assert insight.annotation == 1
    # but update_product wasn't called
    mock.assert_not_called()
Exemplo n.º 7
0
def test_annotation_fails_is_rolledback(mocker):
    annotator = CategoryAnnotator  # should be enough to test with one annotator

    # make it raise
    mocked = mocker.patch.object(annotator,
                                 "process_annotation",
                                 side_effect=Exception("Blah"))
    insight = ProductInsightFactory()
    with pytest.raises(Exception):
        annotator().annotate(
            insight=insight,
            annotation=1,
            automatic=True,
        )
    insight = ProductInsight.get(id=insight.id)
    # unchanged
    assert insight.completed_at is None
    assert insight.annotation is None
    # while process_annotation was called
    assert mocked.called
def test_process_insight_same_product(mocker):
    mocker.patch(
        "robotoff.insights.annotate.get_product",
        return_value={"categories_tags": ["en:Salmons"]},
    )
    mock = mocker.patch("robotoff.off.update_product")
    # an insight to be processed but already there
    id1, code1 = _create_insight(type="category", value_tag="en:Salmons")
    # a new category
    id2, code2 = _create_insight(type="category", value_tag="en:Big fish")
    # another new category
    id3, code3 = _create_insight(type="category", value_tag="en:Smoked Salmon")
    # run process
    process_insights()
    # insights processed
    for id_ in [id1, id2, id3]:
        insight = ProductInsight.get(id=id_)
        assert insight.completed_at is not None
        assert insight.completed_at <= datetime.utcnow()
        assert insight.annotation == 1
    # update_product was called twice
    assert mock.call_count == 2
    mock.assert_any_call(
        {
            "code": code2,
            "add_categories": "en:Big fish",
            "comment": f"[robotoff] Adding category 'en:Big fish', ID: {id2}",
        },
        auth=None,
        server_domain=settings.OFF_SERVER_DOMAIN,
    )
    mock.assert_any_call(
        {
            "code": code3,
            "add_categories": "en:Smoked Salmon",
            "comment":
            f"[robotoff] Adding category 'en:Smoked Salmon', ID: {id3}",
        },
        auth=None,
        server_domain=settings.OFF_SERVER_DOMAIN,
    )