[go: nahoru, domu]

Skip to content

Commit

Permalink
test(ui): test cases to adapt private key changes
Browse files Browse the repository at this point in the history
This commit is aimed to add the test cases for the refactor of the
private keys components and store.
  • Loading branch information
luannmoreira authored and gustavosbarreto committed Mar 22, 2024
1 parent 40882bb commit 8cd7502
Show file tree
Hide file tree
Showing 13 changed files with 581 additions and 74 deletions.
20 changes: 6 additions & 14 deletions ui/src/components/PrivateKeys/PrivateKeyDelete.vue
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
<template>
<v-list-item @click="showDialog = true">
<v-list-item @click="showDialog = true" data-test="privatekey-delete-btn">
<div class="d-flex align-center">
<div data-test="privatekey-delete-icon" class="mr-2">
<v-icon> mdi-delete </v-icon>
</div>

<v-list-item-title data-test="privatekey-delete-title">
<v-list-item-title data-test="privatekey-delete-btn-title">
Remove
</v-list-item-title>
</div>
</v-list-item>

<v-dialog max-width="450" v-model="showDialog">
<v-card class="bg-v-theme-surface">
<v-card-title class="text-h5 pa-5 bg-primary">
<v-card-title class="text-h5 pa-5 bg-primary" data-test="privatekey-dialog-title">
Are you sure?
</v-card-title>
<v-divider />

<v-card-text class="mt-4 mb-0 pb-1">
<v-card-text class="mt-4 mb-0 pb-1" data-test="privatekey-dialog-text">
<p class="text-body-2 mb-2">
You are about to remove this private key.
</p>
Expand All @@ -31,9 +31,9 @@
<v-card-actions>
<v-spacer />

<v-btn variant="text" @click="showDialog = false"> Close </v-btn>
<v-btn variant="text" @click="showDialog = false" data-test="privatekey-close-btn"> Close </v-btn>

<v-btn color="red darken-1" variant="text" @click="remove()">
<v-btn color="red darken-1" variant="text" @click="remove()" data-test="privatekey-remove-btn">
Remove
</v-btn>
</v-card-actions>
Expand All @@ -44,11 +44,9 @@
<script setup lang="ts">
import { ref } from "vue";
import {
INotificationsError,
INotificationsSuccess,
} from "../../interfaces/INotifications";
import { useStore } from "../../store";
import handleError from "@/utils/handleError";
const props = defineProps({
id: {
Expand All @@ -68,12 +66,6 @@ const remove = async () => {
INotificationsSuccess.privateKeyDeleting,
);
emit("update");
} catch (error: unknown) {
store.dispatch(
"snackbar/showSnackbarErrorAction",
INotificationsError.privateKeyDeleting,
);
handleError(error);
} finally {
showDialog.value = false;
}
Expand Down
5 changes: 3 additions & 2 deletions ui/src/components/PrivateKeys/PrivateKeyEdit.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
<div>
<v-list-item @click="showDialog = true" v-bind="$props">
<v-list-item @click="showDialog = true" v-bind="$props" data-test="privatekey-edit-btn">
<div class="d-flex align-center">
<div data-test="privatekey-icon" class="mr-2">
<v-icon> mdi-pencil </v-icon>
Expand Down Expand Up @@ -183,8 +183,9 @@ const edit = async () => {
"snackbar/showSnackbarErrorAction",
INotificationsError.privateKeyEditing,
);
handleError(error);
}
}
};
defineExpose({ keyLocal, isValid, name, update, edit, handleError, setPrivateKey });
</script>
4 changes: 2 additions & 2 deletions ui/src/components/PrivateKeys/PrivateKeyList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
<td class="text-center" data-test="privateKey-name">
{{ privateKey.name }}
</td>
<td class="text-center" data-test="privateKey-fingerpint">
<td class="text-center" data-test="privateKey-fingerprint">
{{ convertToFingerprint(privateKey.data) }}
</td>
<td class="text-center">
Expand Down Expand Up @@ -53,7 +53,7 @@
</td>
</tr>
</tbody>
<div v-else sm="12" class="text-start mt-2 text-medium-emphasis">
<div v-else sm="12" class="text-start mt-2 text-medium-emphasis" data-test="no-private-key-warning">
<span>No data avaliable</span>
</div>
</v-table>
Expand Down
9 changes: 9 additions & 0 deletions ui/src/store/modules/private_key.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,17 @@ export const privateKey: Module<PrivateKeyState, State> = {
},

edit: async (context, privateKey) => {
// @ts-expect-error
const privateKeys = JSON.parse(localStorage.getItem("privateKeys")) || [];
const existingKey = privateKeys.find((pk: IPrivateKey) => pk.id === privateKey.id);

if (existingKey && existingKey.data === privateKey.data && existingKey.name === privateKey.name) {
throw new Error();
}

context.commit("editPrivateKey", privateKey);
},


remove: async (context, id) => {
// @ts-expect-error
Expand Down
55 changes: 0 additions & 55 deletions ui/tests/components/PrivateKeys/PrivateKeyAdd.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,12 @@ import { createVuetify } from "vuetify";
import { DOMWrapper, flushPromises, mount, VueWrapper } from "@vue/test-utils";
import { beforeEach, describe, expect, it, vi } from "vitest";
import MockAdapter from "axios-mock-adapter";
import { nextTick } from "vue";
import PrivateKeyAdd from "@/components/PrivateKeys/PrivateKeyAdd.vue";
import { namespacesApi, usersApi } from "@/api/http";
import { store, key } from "@/store";
import { router } from "@/router";
import { envVariables } from "@/envVariables";
import { SnackbarPlugin } from "@/plugins/snackbar";
import { INotificationsSuccess } from "@/interfaces/INotifications";

type PrivateKeyAddWrapper = VueWrapper<InstanceType<typeof PrivateKeyAdd>>;

Expand Down Expand Up @@ -64,59 +62,6 @@ describe("Setting Private Keys", () => {

const session = true;

const privateKeys = [{
name: "test",
data: `-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAACFwAAAAdzc2gtcn
NhAAAAAwEAAQAAAgEAneJ7kCYsKAwdSMgu37VNdtBu3Syr8S0kEnSaIjnYizKY/6BU6wC0
zH9JsiuCAcC0Qc2m9jNAV/udlDO7tbra3WxXcKKxyPIQ0TOyvE8N1mR6IU8D6atyN7FM1b
uatb95IB22qztLtMRHWoGb50NCbAIVv7wuwBtegYYDcyjT6v8YEBQvHkl01zpudOlIiFqE
y1Wd+W4l48cTfbfc0iK84nakK6vi/lRWkliKF4t3L4s3NaoLJZ1ibDd1/yLzVnIvLpwM9k
CZn4jvPp6fTFbFvfN2KvxEXDN18vqNkJlZh2lgKSS9ZJuHp5LZaUiBYcTiovo3LaV2q+yp
NT61VbzzSy7+cnmGl5lpRuikrg6MeSwawpo+6sdSYvBdgxh/cDtKIPputkm6kMp/iizepW
SzrPlAkCji7bP9v+q+sZLN0oe1zOm7rWX9qqqq3PBaHNCm26gXiHYsIXb2ntNC19K4PULt
ZFg6EUkEgFlka4o2keFLAarY0Ogx7KX4I6gnnuEc8yZOdCrs3gsBuaNIAMoxKbwLIXdU7Y
8vqFcGqc0R2ahKoFOmohMW/hySVDUVplmFj1Wq19Bpnc0LtWqRXeuQG92XOMMSQyxXx0c8
rD8llhBoiIC2w1G58RZZOLRYNXE6/rN0UafN9BQypqRu6PmCzQmG+5U7qz4GZ7zQv8vyKI
UAAAdI80sWO/NLFjsAAAAHc3NoLXJzYQAAAgEAneJ7kCYsKAwdSMgu37VNdtBu3Syr8S0k
EnSaIjnYizKY/6BU6wC0zH9JsiuCAcC0Qc2m9jNAV/udlDO7tbra3WxXcKKxyPIQ0TOyvE
8N1mR6IU8D6atyN7FM1buatb95IB22qztLtMRHWoGb50NCbAIVv7wuwBtegYYDcyjT6v8Y
EBQvHkl01zpudOlIiFqEy1Wd+W4l48cTfbfc0iK84nakK6vi/lRWkliKF4t3L4s3NaoLJZ
1ibDd1/yLzVnIvLpwM9kCZn4jvPp6fTFbFvfN2KvxEXDN18vqNkJlZh2lgKSS9ZJuHp5LZ
aUiBYcTiovo3LaV2q+ypNT61VbzzSy7+cnmGl5lpRuikrg6MeSwawpo+6sdSYvBdgxh/cD
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
-----END OPENSSH PRIVATE KEY-----`,
}];

beforeEach(async () => {
const el = document.createElement("div");
document.body.appendChild(el);
Expand Down
126 changes: 126 additions & 0 deletions ui/tests/components/PrivateKeys/PrivateKeyDelete.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
import { createVuetify } from "vuetify";
import { DOMWrapper, flushPromises, mount, VueWrapper } from "@vue/test-utils";
import { beforeEach, describe, expect, it, vi } from "vitest";
import MockAdapter from "axios-mock-adapter";
import PrivateKeyDelete from "@/components/PrivateKeys/PrivateKeyDelete.vue";
import { namespacesApi, usersApi } from "@/api/http";
import { store, key } from "@/store";
import { router } from "@/router";
import { envVariables } from "@/envVariables";
import { SnackbarPlugin } from "@/plugins/snackbar";

const node = document.createElement("div");
node.setAttribute("id", "app");
document.body.appendChild(node);

type PrivateKeyDeleteWrapper = VueWrapper<InstanceType<typeof PrivateKeyDelete>>;

describe("Private Key Delete", () => {
let wrapper: PrivateKeyDeleteWrapper;

const vuetify = createVuetify();

let mockNamespace: MockAdapter;

let mockUser: MockAdapter;

const members = [
{
id: "xxxxxxxx",
username: "test",
role: "owner",
},
];

const namespaceData = {
name: "test",
owner: "test",
tenant_id: "fake-tenant-data",
members,
settings: {
session_record: true,
connection_announcement: "",
},
max_devices: 3,
devices_count: 3,
created_at: "",
};

const authData = {
status: "success",
token: "",
user: "test",
name: "test",
tenant: "fake-tenant-data",
email: "test@test.com",
id: "xxxxxxxx",
role: "owner",
mfa: {
enable: false,
validate: false,
},
};

const session = true;

beforeEach(async () => {
const el = document.createElement("div");
document.body.appendChild(el);
vi.useFakeTimers();
localStorage.setItem("tenant", "fake-tenant-data");
envVariables.isCloud = true;

mockNamespace = new MockAdapter(namespacesApi.getAxios());
mockUser = new MockAdapter(usersApi.getAxios());

mockNamespace.onGet("http://localhost:3000/api/namespaces/fake-tenant-data").reply(200, namespaceData);
mockUser.onGet("http://localhost:3000/api/users/security").reply(200, session);
mockUser.onGet("http://localhost:3000/api/auth/user").reply(200, authData);

wrapper = mount(PrivateKeyDelete, {
global: {
plugins: [[store, key], vuetify, router, SnackbarPlugin],
config: {
errorHandler: () => { /* ignore global error handler */ },
},
},
});
store.commit("auth/authSuccess", authData);
store.commit("auth/changeData", authData);
store.commit("namespaces/setNamespace", namespaceData);
store.commit("security/setSecurity", session);
});

it("Is a Vue instance", () => {
expect(wrapper.vm).toBeTruthy();
});

it("Renders the component", () => {
expect(wrapper.html()).toMatchSnapshot();
});

it("Data is defined", () => {
expect(wrapper.vm.$data).toBeDefined();
});

it("Renders components", async () => {
expect(wrapper.find('[data-test="privatekey-delete-btn"]').exists()).toBe(true);
expect(wrapper.find('[data-test="privatekey-delete-btn-title"]').exists()).toBe(true);
await wrapper.findComponent('[data-test="privatekey-delete-btn"]').trigger("click");
const dialog = new DOMWrapper(document.body);
await flushPromises();
expect(dialog.find('[data-test="privatekey-dialog-title"]').exists()).toBe(true);
expect(dialog.find('[data-test="privatekey-dialog-text"]').exists()).toBe(true);
expect(dialog.find('[data-test="privatekey-close-btn"]').exists()).toBe(true);
expect(dialog.find('[data-test="privatekey-remove-btn"]').exists()).toBe(true);
});

it("Checks if the remove function updates the store on success", async () => {
const storeSpy = vi.spyOn(store, "dispatch");
await wrapper.setProps({ id: 1 });
await wrapper.findComponent('[data-test="privatekey-delete-btn"]').trigger("click");
await flushPromises();
await wrapper.findComponent('[data-test="privatekey-remove-btn"]').trigger("click");
expect(storeSpy).toHaveBeenCalledWith("privateKey/remove", 1);
});
});
Loading

0 comments on commit 8cd7502

Please sign in to comment.