Skip to content

Commit

Permalink
test: ✅ add e2e and api tests
Browse files Browse the repository at this point in the history
  • Loading branch information
nutfdt committed Oct 7, 2024
1 parent b074365 commit 6d05bac
Show file tree
Hide file tree
Showing 16 changed files with 144 additions and 125 deletions.
7 changes: 5 additions & 2 deletions backend/src/router.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

from basegun_ml.classification import get_typology
from basegun_ml.measure import get_lengths
from basegun_ml.ocr import is_alarm_weapon, LowQuality, MissingText
from basegun_ml.ocr import LowQuality, MissingText, is_alarm_weapon
from fastapi import (
APIRouter,
BackgroundTasks,
Expand Down Expand Up @@ -37,6 +37,7 @@ def home():
def version():
return APP_VERSION


@router.post("/upload")
async def imageupload(
request: Request,
Expand Down Expand Up @@ -78,7 +79,7 @@ async def imageupload(

except Exception as e:
extras_logging["bg_error_type"] = e.__class__.__name__
logging.exception(e, extra=extras_logging)
logging.exception(e, extra=extras_logging)
# Temporary fix while ML package send 0 instead of None
# https://github.com/dnum-mi/basegun-ml/issues/14
gun_length = None if gun_length == 0 else gun_length
Expand Down Expand Up @@ -109,6 +110,7 @@ async def imageupload(
logging.exception(e, extra=extras_logging)
raise HTTPException(status_code=500, detail=str(e))


@router.post("/identification-blank-gun")
async def imageblankgun(
image: UploadFile = File(...),
Expand Down Expand Up @@ -138,6 +140,7 @@ async def imageblankgun(
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))


@router.post("/identification-feedback")
async def log_feedback(request: Request, user_id: Union[str, None] = Cookie(None)):
res = await request.json()
Expand Down
Binary file added backend/tests/blank_gun.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added backend/tests/low_quality.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added backend/tests/no_text.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
38 changes: 38 additions & 0 deletions backend/tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,3 +187,41 @@ def test_403(self):
response = client.post("/api/expert-contact")
response.data = response.json()
assert response.status_code == 403


class TestBlankGunUpload:
def test_blank_gun(self):
with open("./tests/blank_gun.jpg", "rb") as f:
response = client.post(
"/api/identification-blank-gun",
files={"image": f},
)
response.data = response.json()
assert response.status_code == 200
response.data["alarm_model"] == "Alarm_model"
not response.data["missing_text"]
not response.data["low_quality"]

def test_bad_quality(self):
with open("./tests/low_quality.jpg", "rb") as f:
response = client.post(
"/api/identification-blank-gun",
files={"image": f},
)
response.data = response.json()
assert response.status_code == 200
response.data["alarm_model"] is None
not response.data["missing_text"]
response.data["missing_text"]

def test_missing_text(self):
with open("./tests/no_text.jpg", "rb") as f:
response = client.post(
"/api/identification-blank-gun",
files={"image": f},
)
response.data = response.json()
assert response.status_code == 200
response.data["alarm_model"] is None
response.data["missing_text"]
not response.data["low_quality"]
53 changes: 53 additions & 0 deletions frontend/cypress/e2e/blank-gun-detection.cy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
describe("Blank Gun Detection", () => {
it("should identificate real blank gun", () => {
cy.Identification();

cy.getByDataTestid("select-file").as("fileInput");
cy.intercept("POST", "/api/upload").as("upload");
cy.get("@fileInput").selectFile("./cypress/images/blank-gun.jpg", {
force: true,
});
cy.wait("@upload").then(({ response }) => {
expect(response.statusCode).to.eq(200);
});
cy.getByDataTestid("next-step").click();
cy.IdentificationPistoletSemiAuto();
cy.wait(5000);
cy.url().should("contain", "/guide-identification/resultat-final");
cy.getByDataTestid("arm-category").should("contain", "Catégorie C");
});

it("should identificate firearm with missing text", () => {
cy.Identification();

cy.getByDataTestid("select-file").as("fileInput");
cy.intercept("POST", "/api/upload").as("upload");
cy.get("@fileInput").selectFile("./cypress/images/no-text.jpg", {
force: true,
});
cy.wait("@upload").then(({ response }) => {
expect(response.statusCode).to.eq(200);
});
cy.getByDataTestid("next-step").click();
cy.IdentificationBlankGunMissingText();
cy.url().should("contain", "/guide-identification/resultat-final");
cy.getByDataTestid("arm-category").should("contain", "Catégorie B");
});

it("should identificate firearm with low quality", () => {
cy.Identification();

cy.getByDataTestid("select-file").as("fileInput");
cy.intercept("POST", "/api/upload").as("upload");
cy.get("@fileInput").selectFile("./cypress/images/low-quality.jpg", {
force: true,
});
cy.wait("@upload").then(({ response }) => {
expect(response.statusCode).to.eq(200);
});
cy.getByDataTestid("next-step").click();
cy.IdentificationBlankGunLowQuality();
cy.url().should("contain", "/guide-identification/resultat-final");
cy.getByDataTestid("arm-category").should("contain", "Catégorie B");
});
});
1 change: 1 addition & 0 deletions frontend/cypress/e2e/firearm-confidence.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ describe("Firearm Confidence", () => {
});
cy.getByDataTestid("next-step").click();
cy.IdentificationPistoletSemiAuto();
cy.wait(5000);
cy.url().should("contain", "/guide-identification/resultat-final");
cy.getByDataTestid("arm-category").should("contain", "Catégorie B");
});
Expand Down
1 change: 1 addition & 0 deletions frontend/cypress/e2e/firearm-identification.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ describe("Firearm Identification", () => {
});
cy.getByDataTestid("next-step").click();
cy.IdentificationPistoletSemiAuto();
cy.wait(5000);
cy.url().should("contain", "/guide-identification/resultat-final");
cy.getByDataTestid("arm-category").should("contain", "Catégorie B");
cy.getByDataTestid("return-to-home-end").click();
Expand Down
1 change: 1 addition & 0 deletions frontend/cypress/e2e/firearm-securing.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ describe("Securing Firearm and Identification", () => {
cy.contains("p", "Basegun a identifié votre arme");
cy.getByDataTestid("next-step").click();
cy.IdentificationPistoletSemiAuto();
cy.wait(5000);
cy.url().should("contain", "/guide-identification/resultat-final");
cy.getByDataTestid("arm-category").should("contain", "Catégorie B");
cy.getByDataTestid("return-to-home-end").click();
Expand Down
Binary file added frontend/cypress/images/blank-gun.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added frontend/cypress/images/low-quality.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added frontend/cypress/images/no-text.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
53 changes: 43 additions & 10 deletions frontend/cypress/support/commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,11 +109,11 @@ Cypress.Commands.add("IdentificationPistoletSemiAuto", () => {
cy.contains("Cartouches").first().click();
cy.getByDataTestid("next-step").should("not.have.attr", "disabled");
cy.getByDataTestid("next-step").click();
cy.url().should("contain", "/guide-identification/armes-alarme");
cy.getByDataTestid("instruction-armeAlarme").should("contain", "Votre arme");
cy.getByDataTestid("next-step").click();
cy.getByDataTestid("aucune-correspondance").click();
cy.getByDataTestid("next-step").click();
cy.url().should("contain", "/guide-identification/qualite-image");
cy.getByDataTestid("title-page").should(
"contain",
"Identification d'une arme d'alarme",
);
});

Cypress.Commands.add("IdentificationRevolver", () => {
Expand All @@ -133,11 +133,9 @@ Cypress.Commands.add("IdentificationRevolver", () => {
cy.contains("Balles").first().click();
cy.getByDataTestid("next-step").should("not.have.attr", "disabled");
cy.getByDataTestid("next-step").click();
cy.url().should("contain", "/guide-identification/armes-alarme");
cy.getByDataTestid("instruction-armeAlarme").should("contain", "Votre arme");
cy.getByDataTestid("next-step").click();
cy.getByDataTestid("aucune-correspondance").click();
cy.getByDataTestid("next-step").click();
cy.url().should("contain", "/guide-identification/qualite-image");
cy.getByDataTestid("title-page").should("contain", "Marquages non détéctés");
cy.get('.fr-col-12 > [data-testid="next-step"]').click();
});

Cypress.Commands.add("arrierePlatRevolver", () => {
Expand Down Expand Up @@ -198,3 +196,38 @@ Cypress.Commands.add("pasDeGuide", () => {
cy.getByDataTestid("go-to-identification").click();
cy.url().should("contain", "/guide-identification/resultat-typologie");
});

Cypress.Commands.add("IdentificationBlankGunMissingText", () => {
cy.url().should(
"contain",
"guide-identification/informations-complementaires",
);
cy.getByDataTestid("next-step").click();
cy.url().should("contain", "/guide-identification/munition-type");
cy.getByDataTestid("next-step").should("have.attr", "disabled");
cy.contains("Cartouches").first().click();
cy.getByDataTestid("next-step").should("not.have.attr", "disabled");
cy.getByDataTestid("next-step").click();
cy.url().should("contain", "/guide-identification/qualite-image");
cy.getByDataTestid("title-page").should("contain", "Marquages non détéctés");
cy.get('.fr-col-12 > [data-testid="next-step"]').click();
});

Cypress.Commands.add("IdentificationBlankGunLowQuality", () => {
cy.url().should(
"contain",
"guide-identification/informations-complementaires",
);
cy.getByDataTestid("next-step").click();
cy.url().should("contain", "/guide-identification/munition-type");
cy.getByDataTestid("next-step").should("have.attr", "disabled");
cy.contains("Cartouches").first().click();
cy.getByDataTestid("next-step").should("not.have.attr", "disabled");
cy.getByDataTestid("next-step").click();
cy.url().should("contain", "/guide-identification/qualite-image");
cy.getByDataTestid("title-page").should(
"contain",
"Qualité d'image insuffisante",
);
cy.get('.fr-col-12 > [data-testid="next-step"]').click();
});
112 changes: 0 additions & 112 deletions frontend/src/auto-imports.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -425,115 +425,3 @@ declare module "vue" {
>;
}
}
declare module "@vue/runtime-core" {
interface GlobalComponents {}
interface ComponentCustomProperties {
readonly EffectScope: UnwrapRef<(typeof import("vue"))["EffectScope"]>;
readonly OhVueIcon: UnwrapRef<(typeof import("oh-vue-icons"))["OhVueIcon"]>;
readonly addIcons: UnwrapRef<(typeof import("oh-vue-icons"))["addIcons"]>;
readonly computed: UnwrapRef<(typeof import("vue"))["computed"]>;
readonly createApp: UnwrapRef<(typeof import("vue"))["createApp"]>;
readonly customRef: UnwrapRef<(typeof import("vue"))["customRef"]>;
readonly defineAsyncComponent: UnwrapRef<
(typeof import("vue"))["defineAsyncComponent"]
>;
readonly defineComponent: UnwrapRef<
(typeof import("vue"))["defineComponent"]
>;
readonly effectScope: UnwrapRef<(typeof import("vue"))["effectScope"]>;
readonly getCurrentInstance: UnwrapRef<
(typeof import("vue"))["getCurrentInstance"]
>;
readonly getCurrentScope: UnwrapRef<
(typeof import("vue"))["getCurrentScope"]
>;
readonly h: UnwrapRef<(typeof import("vue"))["h"]>;
readonly inject: UnwrapRef<(typeof import("vue"))["inject"]>;
readonly isProxy: UnwrapRef<(typeof import("vue"))["isProxy"]>;
readonly isReactive: UnwrapRef<(typeof import("vue"))["isReactive"]>;
readonly isReadonly: UnwrapRef<(typeof import("vue"))["isReadonly"]>;
readonly isRef: UnwrapRef<(typeof import("vue"))["isRef"]>;
readonly markRaw: UnwrapRef<(typeof import("vue"))["markRaw"]>;
readonly nextTick: UnwrapRef<(typeof import("vue"))["nextTick"]>;
readonly onActivated: UnwrapRef<(typeof import("vue"))["onActivated"]>;
readonly onBeforeMount: UnwrapRef<(typeof import("vue"))["onBeforeMount"]>;
readonly onBeforeRouteLeave: UnwrapRef<
(typeof import("vue-router"))["onBeforeRouteLeave"]
>;
readonly onBeforeRouteUpdate: UnwrapRef<
(typeof import("vue-router"))["onBeforeRouteUpdate"]
>;
readonly onBeforeUnmount: UnwrapRef<
(typeof import("vue"))["onBeforeUnmount"]
>;
readonly onBeforeUpdate: UnwrapRef<
(typeof import("vue"))["onBeforeUpdate"]
>;
readonly onDeactivated: UnwrapRef<(typeof import("vue"))["onDeactivated"]>;
readonly onErrorCaptured: UnwrapRef<
(typeof import("vue"))["onErrorCaptured"]
>;
readonly onMounted: UnwrapRef<(typeof import("vue"))["onMounted"]>;
readonly onRenderTracked: UnwrapRef<
(typeof import("vue"))["onRenderTracked"]
>;
readonly onRenderTriggered: UnwrapRef<
(typeof import("vue"))["onRenderTriggered"]
>;
readonly onScopeDispose: UnwrapRef<
(typeof import("vue"))["onScopeDispose"]
>;
readonly onServerPrefetch: UnwrapRef<
(typeof import("vue"))["onServerPrefetch"]
>;
readonly onUnmounted: UnwrapRef<(typeof import("vue"))["onUnmounted"]>;
readonly onUpdated: UnwrapRef<(typeof import("vue"))["onUpdated"]>;
readonly provide: UnwrapRef<(typeof import("vue"))["provide"]>;
readonly reactive: UnwrapRef<(typeof import("vue"))["reactive"]>;
readonly readonly: UnwrapRef<(typeof import("vue"))["readonly"]>;
readonly ref: UnwrapRef<(typeof import("vue"))["ref"]>;
readonly resolveComponent: UnwrapRef<
(typeof import("vue"))["resolveComponent"]
>;
readonly shallowReactive: UnwrapRef<
(typeof import("vue"))["shallowReactive"]
>;
readonly shallowReadonly: UnwrapRef<
(typeof import("vue"))["shallowReadonly"]
>;
readonly shallowRef: UnwrapRef<(typeof import("vue"))["shallowRef"]>;
readonly toRaw: UnwrapRef<(typeof import("vue"))["toRaw"]>;
readonly toRef: UnwrapRef<(typeof import("vue"))["toRef"]>;
readonly toRefs: UnwrapRef<(typeof import("vue"))["toRefs"]>;
readonly toValue: UnwrapRef<(typeof import("vue"))["toValue"]>;
readonly triggerRef: UnwrapRef<(typeof import("vue"))["triggerRef"]>;
readonly unref: UnwrapRef<(typeof import("vue"))["unref"]>;
readonly useAttrs: UnwrapRef<(typeof import("vue"))["useAttrs"]>;
readonly useCssModule: UnwrapRef<(typeof import("vue"))["useCssModule"]>;
readonly useCssVars: UnwrapRef<(typeof import("vue"))["useCssVars"]>;
readonly useLink: UnwrapRef<(typeof import("vue-router"))["useLink"]>;
readonly useRoute: UnwrapRef<(typeof import("vue-router"))["useRoute"]>;
readonly useRouter: UnwrapRef<(typeof import("vue-router"))["useRouter"]>;
readonly useScheme: UnwrapRef<
(typeof import("@gouvminint/vue-dsfr"))["useScheme"]
>;
readonly useSlots: UnwrapRef<(typeof import("vue"))["useSlots"]>;
readonly useSnackbarStore: UnwrapRef<
(typeof import("./stores/snackbar"))["useSnackbarStore"]
>;
readonly useStore: UnwrapRef<
(typeof import("./stores/result"))["useStore"]
>;
readonly useTabs: UnwrapRef<
(typeof import("@gouvminint/vue-dsfr"))["useTabs"]
>;
readonly watch: UnwrapRef<(typeof import("vue"))["watch"]>;
readonly watchEffect: UnwrapRef<(typeof import("vue"))["watchEffect"]>;
readonly watchPostEffect: UnwrapRef<
(typeof import("vue"))["watchPostEffect"]
>;
readonly watchSyncEffect: UnwrapRef<
(typeof import("vue"))["watchSyncEffect"]
>;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,7 @@ watch(alarmModel, (newVal) => {
<DsfrButton
class="flex justify-center !w-full"
data-testid="next-step"
:label="footerValue.next"
:icon-right="true"
icon="ri-checkbox-circle-line"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ const alert = computed(() => {
</script>
<template>
<h2 class="fr-mt-3w flex justify-center titlePage">
<span> {{ title }}</span>
<span data-testid="title-page"> {{ title }}</span>
</h2>

<div class="fr-p-1w">
Expand Down

0 comments on commit 6d05bac

Please sign in to comment.