after audit
This commit is contained in:
parent
e8e20637e6
commit
a5165dc3ba
80 changed files with 8489 additions and 7302 deletions
|
|
@ -0,0 +1,139 @@
|
|||
// @vitest-environment happy-dom
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { mount } from "@vue/test-utils";
|
||||
import PublicationTableRow from "./PublicationTableRow.vue";
|
||||
import type { PublicationItem } from "@/features/publications";
|
||||
|
||||
function buildItem(overrides: Partial<PublicationItem> = {}): PublicationItem {
|
||||
return {
|
||||
publication_id: 1,
|
||||
scholar_profile_id: 10,
|
||||
title: "Test Publication",
|
||||
year: 2025,
|
||||
citation_count: 42,
|
||||
pub_url: "https://example.com/pub",
|
||||
pdf_url: null,
|
||||
pdf_status: null,
|
||||
is_read: false,
|
||||
is_favorite: false,
|
||||
is_new_in_latest_run: true,
|
||||
scholar_label: "Dr. Test",
|
||||
first_seen_at: "2025-01-15T00:00:00Z",
|
||||
display_identifier: null,
|
||||
...overrides,
|
||||
} as PublicationItem;
|
||||
}
|
||||
|
||||
const defaultProps = {
|
||||
item: buildItem(),
|
||||
itemKey: "pub-1",
|
||||
selected: false,
|
||||
favoriteUpdating: false,
|
||||
retrying: false,
|
||||
canRetry: false,
|
||||
};
|
||||
|
||||
describe("PublicationTableRow", () => {
|
||||
it("renders the publication title", () => {
|
||||
const wrapper = mount(PublicationTableRow, { props: defaultProps });
|
||||
expect(wrapper.text()).toContain("Test Publication");
|
||||
});
|
||||
|
||||
it("renders scholar label", () => {
|
||||
const wrapper = mount(PublicationTableRow, { props: defaultProps });
|
||||
expect(wrapper.text()).toContain("Dr. Test");
|
||||
});
|
||||
|
||||
it("renders year and citation count", () => {
|
||||
const wrapper = mount(PublicationTableRow, { props: defaultProps });
|
||||
expect(wrapper.text()).toContain("2025");
|
||||
expect(wrapper.text()).toContain("42");
|
||||
});
|
||||
|
||||
it("shows New badge when is_new_in_latest_run is true", () => {
|
||||
const wrapper = mount(PublicationTableRow, { props: defaultProps });
|
||||
expect(wrapper.text()).toContain("New");
|
||||
});
|
||||
|
||||
it("shows Seen badge when is_new_in_latest_run is false", () => {
|
||||
const wrapper = mount(PublicationTableRow, {
|
||||
props: { ...defaultProps, item: buildItem({ is_new_in_latest_run: false }) },
|
||||
});
|
||||
expect(wrapper.text()).toContain("Seen");
|
||||
});
|
||||
|
||||
it("shows Unread badge for unread items", () => {
|
||||
const wrapper = mount(PublicationTableRow, { props: defaultProps });
|
||||
expect(wrapper.text()).toContain("Unread");
|
||||
});
|
||||
|
||||
it("shows Read badge for read items", () => {
|
||||
const wrapper = mount(PublicationTableRow, {
|
||||
props: { ...defaultProps, item: buildItem({ is_read: true }) },
|
||||
});
|
||||
expect(wrapper.text()).toContain("Read");
|
||||
});
|
||||
|
||||
it("disables checkbox when item is read", () => {
|
||||
const wrapper = mount(PublicationTableRow, {
|
||||
props: { ...defaultProps, item: buildItem({ is_read: true }) },
|
||||
});
|
||||
const checkbox = wrapper.find('input[type="checkbox"]');
|
||||
expect((checkbox.element as HTMLInputElement).disabled).toBe(true);
|
||||
});
|
||||
|
||||
it("emits toggle-selection when checkbox is changed", async () => {
|
||||
const wrapper = mount(PublicationTableRow, { props: defaultProps });
|
||||
await wrapper.find('input[type="checkbox"]').trigger("change");
|
||||
expect(wrapper.emitted("toggle-selection")).toHaveLength(1);
|
||||
});
|
||||
|
||||
it("emits toggle-favorite when star button is clicked", async () => {
|
||||
const wrapper = mount(PublicationTableRow, { props: defaultProps });
|
||||
await wrapper.find(".favorite-star-button").trigger("click");
|
||||
expect(wrapper.emitted("toggle-favorite")).toHaveLength(1);
|
||||
});
|
||||
|
||||
it("shows filled star when item is favorite", () => {
|
||||
const wrapper = mount(PublicationTableRow, {
|
||||
props: { ...defaultProps, item: buildItem({ is_favorite: true }) },
|
||||
});
|
||||
expect(wrapper.find(".favorite-star-on").exists()).toBe(true);
|
||||
expect(wrapper.text()).toContain("★");
|
||||
});
|
||||
|
||||
it("shows empty star when item is not favorite", () => {
|
||||
const wrapper = mount(PublicationTableRow, { props: defaultProps });
|
||||
expect(wrapper.find(".favorite-star-off").exists()).toBe(true);
|
||||
expect(wrapper.text()).toContain("☆");
|
||||
});
|
||||
|
||||
it("shows Available link when pdf_url is set", () => {
|
||||
const wrapper = mount(PublicationTableRow, {
|
||||
props: { ...defaultProps, item: buildItem({ pdf_url: "https://example.com/paper.pdf" }) },
|
||||
});
|
||||
expect(wrapper.text()).toContain("Available");
|
||||
});
|
||||
|
||||
it("shows retry button when canRetry is true and no pdf_url", () => {
|
||||
const wrapper = mount(PublicationTableRow, {
|
||||
props: { ...defaultProps, canRetry: true },
|
||||
});
|
||||
expect(wrapper.text()).toContain("Missing (Retry)");
|
||||
});
|
||||
|
||||
it("emits retry-pdf when retry button is clicked", async () => {
|
||||
const wrapper = mount(PublicationTableRow, {
|
||||
props: { ...defaultProps, canRetry: true },
|
||||
});
|
||||
await wrapper.find(".pdf-retry-button").trigger("click");
|
||||
expect(wrapper.emitted("retry-pdf")).toHaveLength(1);
|
||||
});
|
||||
|
||||
it("shows Retrying... label when retrying", () => {
|
||||
const wrapper = mount(PublicationTableRow, {
|
||||
props: { ...defaultProps, canRetry: true, retrying: true },
|
||||
});
|
||||
expect(wrapper.text()).toContain("Retrying...");
|
||||
});
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue