Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions src/components/AdminSupportBanner.vue
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,9 @@ SPDX-License-Identifier: AGPL-3.0-or-later

<div class="profile-fields-admin-support-banner__links">
<a href="https://github.com/LibreCodeCoop/profile_fields" target="_blank" rel="noopener noreferrer nofollow">
{{ t('profile_fields', 'Give Profile Fields a ⭐ on GitHub') }}
</a>
<a href="mailto:contact@librecode.coop">
{{ t('profile_fields', 'Contact us for support or custom development') }}
{{ t('profile_fields', 'Give Profile Fields a {star} on GitHub', {star: '⭐'}) }}
</a>
<a href="mailto:contact@librecode.coop">{{ t('profile_fields', 'Contact us for support or custom development') }}</a>
</div>
</div>
</div>
Expand Down
139 changes: 84 additions & 55 deletions src/tests/components/admin/AdminSupportBanner.spec.ts
Original file line number Diff line number Diff line change
@@ -1,73 +1,102 @@
// SPDX-FileCopyrightText: 2026 LibreCode coop and LibreCode contributors
// SPDX-License-Identifier: AGPL-3.0-or-later

import { afterEach, describe, expect, it, vi } from 'vitest'
import { mount } from '@vue/test-utils'
import { defineComponent, nextTick } from 'vue'
import AdminSupportBanner from '../../../components/AdminSupportBanner.vue'
import { afterEach, describe, expect, it, vi } from "vitest";
import { mount } from "@vue/test-utils";
import { defineComponent, nextTick } from "vue";
import AdminSupportBanner from "../../../components/AdminSupportBanner.vue";

vi.mock('@nextcloud/l10n', () => ({
t: (_app: string, text: string, parameters?: Record<string, string>) => {
if (parameters === undefined) {
return `tr:${text}`
}
vi.mock("@nextcloud/l10n", () => ({
t: (_app: string, text: string, parameters?: Record<string, string>) => {
if (parameters === undefined) {
return `tr:${text}`;
}

return Object.entries(parameters).reduce((translated, [key, value]) => translated.replace(`{${key}}`, value), `tr:${text}`)
},
}))
return Object.entries(parameters).reduce(
(translated, [key, value]) => translated.replace(`{${key}}`, value),
`tr:${text}`,
);
},
}));

vi.mock('@nextcloud/vue', () => ({
NcButton: defineComponent({
name: 'NcButton',
emits: ['click'],
template: '<button type="button" v-bind="$attrs" @click="$emit(\'click\', $event)"><slot /></button>',
}),
NcNoteCard: defineComponent({
name: 'NcNoteCard',
template: '<div><slot /></div>',
}),
}))
vi.mock("@nextcloud/vue", () => ({
NcButton: defineComponent({
name: "NcButton",
emits: ["click"],
template:
'<button type="button" v-bind="$attrs" @click="$emit(\'click\', $event)"><slot /></button>',
}),
NcNoteCard: defineComponent({
name: "NcNoteCard",
template: "<div><slot /></div>",
}),
}));

afterEach(() => {
window.localStorage.clear()
vi.restoreAllMocks()
})
window.localStorage.clear();
vi.restoreAllMocks();
});

describe('AdminSupportBanner', () => {
it('renders translated copy and actions', () => {
const wrapper = mount(AdminSupportBanner)
describe("AdminSupportBanner", () => {
it("renders translated banner copy", () => {
const wrapper = mount(AdminSupportBanner);

expect(wrapper.text()).toContain('tr:Help keep Profile Fields sustainable.')
expect(wrapper.text()).toContain('tr:Sponsor LibreSign')
expect(wrapper.text()).toContain('tr:Maybe later')
expect(wrapper.text()).toContain('tr:Give Profile Fields a star on GitHub')
})
expect(wrapper.text()).toContain(
"tr:Help keep Profile Fields sustainable.",
);
expect(wrapper.text()).toContain(
"tr:Profile Fields is open source under the AGPL license and maintained by the LibreCode team, creators of LibreSign.",
);
expect(wrapper.text()).toContain(
"tr:If your organization depends on it, please help us sustain its development and maintenance.",
);
expect(wrapper.text()).toContain("tr:Sponsor LibreSign");
expect(wrapper.text()).toContain("tr:Maybe later");
expect(wrapper.text()).toContain("tr:Give Profile Fields a ⭐ on GitHub");
expect(wrapper.text()).toContain(
"tr:Contact us for support or custom development",
);
});

it('opens sponsor page when sponsor button is clicked', async() => {
const openSpy = vi.spyOn(window, 'open').mockImplementation(() => null)
const wrapper = mount(AdminSupportBanner)
it("opens sponsor page when sponsor button is clicked", async () => {
const openSpy = vi.spyOn(window, "open").mockImplementation(() => null);
const wrapper = mount(AdminSupportBanner);

await wrapper.get('button').trigger('click')
await wrapper.get("button").trigger("click");

expect(openSpy).toHaveBeenCalledWith('https://github.com/sponsors/LibreCodeCoop', '_blank', 'noopener,noreferrer')
})
expect(openSpy).toHaveBeenCalledWith(
"https://github.com/sponsors/LibreCodeCoop",
"_blank",
"noopener,noreferrer",
);
});

it('hides itself after dismiss and persists state', async() => {
const wrapper = mount(AdminSupportBanner)
it("hides itself after dismiss and persists state", async () => {
const wrapper = mount(AdminSupportBanner);

const buttons = wrapper.findAll('button')
await buttons[1].trigger('click')
const buttons = wrapper.findAll("button");
await buttons[1].trigger("click");

expect(wrapper.find('[data-testid="profile-fields-admin-support-banner"]').exists()).toBe(false)
expect(window.localStorage.getItem('profile_fields_support_banner_dismissed')).toBe('1')
})
expect(
wrapper
.find('[data-testid="profile-fields-admin-support-banner"]')
.exists(),
).toBe(false);
expect(
window.localStorage.getItem("profile_fields_support_banner_dismissed"),
).toBe("1");
});

it('starts hidden when dismissal key is already persisted', () => {
window.localStorage.setItem('profile_fields_support_banner_dismissed', '1')
it("starts hidden when dismissal key is already persisted", () => {
window.localStorage.setItem("profile_fields_support_banner_dismissed", "1");

const wrapper = mount(AdminSupportBanner)
return nextTick().then(() => {
expect(wrapper.find('[data-testid="profile-fields-admin-support-banner"]').exists()).toBe(false)
})
})
})
const wrapper = mount(AdminSupportBanner);
return nextTick().then(() => {
expect(
wrapper
.find('[data-testid="profile-fields-admin-support-banner"]')
.exists(),
).toBe(false);
});
});
});
Loading