Repository: CERT-Polska/mwdb-core (language: python)

Issue:
Change name of path from sample to file
**Feature Category**

- [x] Correctness
- [x] User Interface / User Experience

**Describe the problem**

This is confusing when in the UI all redirections related to a file type refer to the sample path.
For this reason, we often have to additionally convert the type to path and vice versa.

**Describe the solution you'd like**

Change /sample/... path to /file/... in frontend components



Discussion / hints:

Fix patch:
diff --git a/mwdb/web/src/App.js b/mwdb/web/src/App.js
index 72bec7b1d..b05ca3606 100644
--- a/mwdb/web/src/App.js
+++ b/mwdb/web/src/App.js
@@ -159,7 +159,8 @@ export default function App() {
                 path="/profile/:login"
                 component={UserProfile}
             />
-            <AuthenticatedRoute path="/sample/:hash" component={ShowSample} />
+            <Redirect from="/sample/:hash" to="/file/:hash" />
+            <AuthenticatedRoute path="/file/:hash" component={ShowSample} />
             <AuthenticatedRoute path="/config/:hash" component={ShowConfig} />
             <AuthenticatedRoute path="/blob/:hash" component={ShowTextBlob} />
             <AuthenticatedRoute
@@ -230,7 +231,7 @@ export default function App() {
                 component={RemoteRecentBlobs}
             />
             <AuthenticatedRoute
-                path="/remote/:remote/sample/:hash"
+                path="/remote/:remote/file/:hash"
                 component={RemoteShowSample}
             />
             <AuthenticatedRoute
diff --git a/mwdb/web/src/commons/helpers/index.js b/mwdb/web/src/commons/helpers/index.js
index 8e2bd4206..676ea5384 100644
--- a/mwdb/web/src/commons/helpers/index.js
+++ b/mwdb/web/src/commons/helpers/index.js
@@ -24,7 +24,7 @@ export function mapObjectType(objectType) {
     return (
         {
             object: "object",
-            file: "sample",
+            file: "file",
             static_config: "config",
             text_blob: "blob",
         }[objectType] || objectType
diff --git a/mwdb/web/src/components/RelationsPlot.js b/mwdb/web/src/components/RelationsPlot.js
index 9b1c6e8b5..c87e2690e 100644
--- a/mwdb/web/src/components/RelationsPlot.js
+++ b/mwdb/web/src/components/RelationsPlot.js
@@ -11,14 +11,14 @@ import { Tag } from "@mwdb-web/commons/ui";
 
 function RelationsNode(props) {
     const typeMapping = {
-        file: "sample",
+        file: "file",
         config: "config",
         static_config: "config",
         text_blob: "blob",
     };
 
     const styleMapping = {
-        sample: "bg-danger",
+        file: "bg-danger",
         config: "bg-success",
         blob: "bg-info",
     };
diff --git a/mwdb/web/src/components/ShowObject/Actions/PullAction.js b/mwdb/web/src/components/ShowObject/Actions/PullAction.js
index 5eeebdf7f..4e80042ca 100644
--- a/mwdb/web/src/components/ShowObject/Actions/PullAction.js
+++ b/mwdb/web/src/components/ShowObject/Actions/PullAction.js
@@ -6,6 +6,7 @@ import { ConfigContext } from "@mwdb-web/commons/config";
 import { ObjectContext } from "@mwdb-web/commons/context";
 import { ObjectAction } from "@mwdb-web/commons/ui";
 import { ConfirmationModal } from "@mwdb-web/commons/ui";
+import { mapObjectType } from "@mwdb-web/commons/helpers";
 
 export default function PullAction() {
     const api = useContext(APIContext);
@@ -14,11 +15,7 @@ export default function PullAction() {
     const [isPullModalOpen, setPullModalOpen] = useState(false);
 
     async function pullRemote() {
-        let type = {
-            file: "file",
-            static_config: "config",
-            text_blob: "blob",
-        }[context.object.type];
+        let type = mapObjectType(context.object.type);
         try {
             await api.pullObjectRemote(api.remote, type, context.object.id);
         } catch (error) {
diff --git a/mwdb/web/src/components/ShowObject/Actions/PushAction.js b/mwdb/web/src/components/ShowObject/Actions/PushAction.js
index 93912345c..ffd0d0a66 100644
--- a/mwdb/web/src/components/ShowObject/Actions/PushAction.js
+++ b/mwdb/web/src/components/ShowObject/Actions/PushAction.js
@@ -7,6 +7,7 @@ import { ConfigContext } from "@mwdb-web/commons/config";
 import { ObjectContext } from "@mwdb-web/commons/context";
 import { ObjectAction } from "@mwdb-web/commons/ui";
 import { ConfirmationModal } from "@mwdb-web/commons/ui";
+import { mapObjectType } from "@mwdb-web/commons/helpers";
 
 export default function PushAction() {
     const api = useContext(APIContext);
@@ -16,11 +17,7 @@ export default function PushAction() {
     const [remoteName, setRemoteName] = useState("");
 
     async function pushRemote() {
-        let type = {
-            file: "file",
-            static_config: "config",
-            text_blob: "blob",
-        }[context.object.type];
+        let type = mapObjectType(context.object.type);
         try {
             await api.pushObjectRemote(remoteName, type, context.object.id);
         } catch (error) {
diff --git a/mwdb/web/src/components/Upload.js b/mwdb/web/src/components/Upload.js
index ac9514adc..d74c3303f 100644
--- a/mwdb/web/src/components/Upload.js
+++ b/mwdb/web/src/components/Upload.js
@@ -136,7 +136,7 @@ export default class Upload extends Component {
                 this.state.attributes
             );
             this.sha256 = response.data.sha256;
-            this.props.history.replace("/sample/" + this.sha256);
+            this.props.history.replace("/file/" + this.sha256);
         } catch (error) {
             this.setState({ error });
         }


Test patch:
diff --git a/tests/frontend/cypress/integration/sample.js b/tests/frontend/cypress/integration/sample.js
index 034b69caa..73268ffd2 100644
--- a/tests/frontend/cypress/integration/sample.js
+++ b/tests/frontend/cypress/integration/sample.js
@@ -1,71 +1,78 @@
 import { requestLogin, browserLogin } from "./util";
 
 describe("Sample view test - mwdb-core", function () {
-  it("Sample view test - existent and non-existent md5 and sha256 hashes", function () {
-    requestLogin(Cypress.env("user"), Cypress.env("password"));
+    it("Sample view test - existent and non-existent md5 and sha256 hashes", function () {
+        requestLogin(Cypress.env("user"), Cypress.env("password"));
 
-    const fileName = "TEST";
-    const method = "POST";
-    const apiUrl = "/api/file";
-    const fileType = "text/plain";
+        const fileName = "TEST";
+        const method = "POST";
+        const apiUrl = "/api/file";
+        const fileType = "text/plain";
 
-    const addedFile = new Cypress.Promise((resolve) => {
-      cy.get("@token").then((token) => {
-        cy.fixture(fileName).then((bin) => {
-          return Cypress.Blob.binaryStringToBlob(bin, fileType).then((blob) => {
-            const formData = new FormData();
-            formData.set("file", blob, fileName);
+        const addedFile = new Cypress.Promise((resolve) => {
+            cy.get("@token").then((token) => {
+                cy.fixture(fileName).then((bin) => {
+                    return Cypress.Blob.binaryStringToBlob(bin, fileType).then(
+                        (blob) => {
+                            const formData = new FormData();
+                            formData.set("file", blob, fileName);
 
-            cy.formRequest(method, apiUrl, formData, token).then(
-              (response) => {
-                expect(response.status).to.eq(200);
-                resolve(response.response.body);
-              }
-            );
-          });
+                            cy.formRequest(
+                                method,
+                                apiUrl,
+                                formData,
+                                token
+                            ).then((response) => {
+                                expect(response.status).to.eq(200);
+                                resolve(response.response.body);
+                            });
+                        }
+                    );
+                });
+            });
         });
-      });
-    });
 
-    addedFile.then((fileData) => {
-      cy.visit("/");
-      browserLogin(Cypress.env("user"), Cypress.env("password"));
+        addedFile.then((fileData) => {
+            cy.visit("/");
+            browserLogin(Cypress.env("user"), Cypress.env("password"));
 
-      cy.contains("Samples").click();
-      cy.get('.d-none a[href*="'+fileData.md5+'"] > div').click();
-      cy.contains(fileData.md5);
-      cy.contains("File name");
-      cy.contains("TEST");
-      cy.contains("12");
-      cy.contains("File type");
-      cy.contains("ASCII text");
-      cy.contains("sha1");
-      cy.contains("sha256");
-      cy.contains("sha512");
-      cy.contains("crc32");
-      cy.contains("ssdeep");
-      cy.contains("Upload time");
+            cy.contains("Samples").click();
+            cy.get('.d-none a[href*="' + fileData.md5 + '"] > div').click();
+            cy.contains(fileData.md5);
+            cy.contains("File name");
+            cy.contains("TEST");
+            cy.contains("12");
+            cy.contains("File type");
+            cy.contains("ASCII text");
+            cy.contains("sha1");
+            cy.contains("sha256");
+            cy.contains("sha512");
+            cy.contains("crc32");
+            cy.contains("ssdeep");
+            cy.contains("Upload time");
 
-      cy.get("a").contains("Relations").click()
-      cy.get("g[class='node expanded-node']");
+            cy.get("a").contains("Relations").click();
+            cy.get("g[class='node expanded-node']");
 
-      cy.get("a").contains("Preview").click()
-      cy.get("div[class='ace_line']");
+            cy.get("a").contains("Preview").click();
+            cy.get("div[class='ace_line']");
 
-      cy.contains("Samples").click();
+            cy.contains("Samples").click();
 
-      cy.get('.d-none a[href*="'+fileData.sha256+'"] > div').should("be.visible").click();
+            cy.get('.d-none a[href*="' + fileData.sha256 + '"] > div')
+                .should("be.visible")
+                .click();
 
-      cy.contains(fileData.sha256);
+            cy.contains(fileData.sha256);
 
-      cy.visit("/sample/fake");
-      cy.contains(
-        "The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again."
-      );
-      cy.visit("/sample/03040506708090aabbccddeeff112233");
-      cy.contains("Object not found");
+            cy.visit("/file/fake");
+            cy.contains(
+                "The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again."
+            );
+            cy.visit("/file/03040506708090aabbccddeeff112233");
+            cy.contains("Object not found");
 
-      cy.contains("Logout").click();
+            cy.contains("Logout").click();
+        });
     });
-  });
 });