Commit aaea4021 authored by Sirieam Marie Hunke's avatar Sirieam Marie Hunke Committed by L. Ellenbeck
Browse files

Fix: Project & Resource settings for guests

parent 88d085f6
Loading
Loading
Loading
Loading
+0 −38
Original line number Original line Diff line number Diff line
@@ -12,35 +12,22 @@ declare module 'vue' {
    BBreadcrumb: typeof import('bootstrap-vue-next')['BBreadcrumb']
    BBreadcrumb: typeof import('bootstrap-vue-next')['BBreadcrumb']
    BBreadcrumbItem: typeof import('bootstrap-vue-next')['BBreadcrumbItem']
    BBreadcrumbItem: typeof import('bootstrap-vue-next')['BBreadcrumbItem']
    BButton: typeof import('bootstrap-vue-next')['BButton']
    BButton: typeof import('bootstrap-vue-next')['BButton']
    BButtonGroup: typeof import('bootstrap-vue-next')['BButtonGroup']
    BCard: typeof import('bootstrap-vue-next')['BCard']
    BCard: typeof import('bootstrap-vue-next')['BCard']
    BCardBody: typeof import('bootstrap-vue-next')['BCardBody']
    BCardBody: typeof import('bootstrap-vue-next')['BCardBody']
    BCardGroup: typeof import('bootstrap-vue-next')['BCardGroup']
    BCardGroup: typeof import('bootstrap-vue-next')['BCardGroup']
    BCardText: typeof import('bootstrap-vue-next')['BCardText']
    BCardText: typeof import('bootstrap-vue-next')['BCardText']
    BCardTitle: typeof import('bootstrap-vue-next')['BCardTitle']
    BCol: typeof import('bootstrap-vue-next')['BCol']
    BCol: typeof import('bootstrap-vue-next')['BCol']
    BCollapse: typeof import('bootstrap-vue-next')['BCollapse']
    BCollapse: typeof import('bootstrap-vue-next')['BCollapse']
    BContainer: typeof import('bootstrap-vue-next')['BContainer']
    BContainer: typeof import('bootstrap-vue-next')['BContainer']
    BDropdown: typeof import('bootstrap-vue-next')['BDropdown']
    BDropdownDivider: typeof import('bootstrap-vue-next')['BDropdownDivider']
    BDropdownDivider: typeof import('bootstrap-vue-next')['BDropdownDivider']
    BDropdownItem: typeof import('bootstrap-vue-next')['BDropdownItem']
    BDropdownItem: typeof import('bootstrap-vue-next')['BDropdownItem']
    BDropdownItemButton: typeof import('bootstrap-vue-next')['BDropdownItemButton']
    BDropdownItemButton: typeof import('bootstrap-vue-next')['BDropdownItemButton']
    BForm: typeof import('bootstrap-vue-next')['BForm']
    BFormCheckbox: typeof import('bootstrap-vue-next')['BFormCheckbox']
    BFormFile: typeof import('bootstrap-vue-next')['BFormFile']
    BFormGroup: typeof import('bootstrap-vue-next')['BFormGroup']
    BFormInput: typeof import('bootstrap-vue-next')['BFormInput']
    BFormInput: typeof import('bootstrap-vue-next')['BFormInput']
    BFormRadioGroup: typeof import('bootstrap-vue-next')['BFormRadioGroup']
    BFormSelect: typeof import('bootstrap-vue-next')['BFormSelect']
    BFormSelect: typeof import('bootstrap-vue-next')['BFormSelect']
    BFormSelectOption: typeof import('bootstrap-vue-next')['BFormSelectOption']
    BFormSelectOption: typeof import('bootstrap-vue-next')['BFormSelectOption']
    BFormText: typeof import('bootstrap-vue-next')['BFormText']
    BFormTextarea: typeof import('bootstrap-vue-next')['BFormTextarea']
    BImg: typeof import('bootstrap-vue-next')['BImg']
    BInputGroup: typeof import('bootstrap-vue-next')['BInputGroup']
    BInputGroup: typeof import('bootstrap-vue-next')['BInputGroup']
    BInputGroupText: typeof import('bootstrap-vue-next')['BInputGroupText']
    BInputGroupText: typeof import('bootstrap-vue-next')['BInputGroupText']
    BLink: typeof import('bootstrap-vue-next')['BLink']
    BLink: typeof import('bootstrap-vue-next')['BLink']
    BListGroup: typeof import('bootstrap-vue-next')['BListGroup']
    BListGroupItem: typeof import('bootstrap-vue-next')['BListGroupItem']
    BModal: typeof import('bootstrap-vue-next')['BModal']
    BModal: typeof import('bootstrap-vue-next')['BModal']
    BNavbar: typeof import('bootstrap-vue-next')['BNavbar']
    BNavbar: typeof import('bootstrap-vue-next')['BNavbar']
    BNavbarBrand: typeof import('bootstrap-vue-next')['BNavbarBrand']
    BNavbarBrand: typeof import('bootstrap-vue-next')['BNavbarBrand']
@@ -50,31 +37,22 @@ declare module 'vue' {
    BNavItem: typeof import('bootstrap-vue-next')['BNavItem']
    BNavItem: typeof import('bootstrap-vue-next')['BNavItem']
    BNavItemDropdown: typeof import('bootstrap-vue-next')['BNavItemDropdown']
    BNavItemDropdown: typeof import('bootstrap-vue-next')['BNavItemDropdown']
    BOverlay: typeof import('bootstrap-vue-next')['BOverlay']
    BOverlay: typeof import('bootstrap-vue-next')['BOverlay']
    BPagination: typeof import('bootstrap-vue-next')['BPagination']
    BPlaceholder: typeof import('bootstrap-vue-next')['BPlaceholder']
    BPlaceholder: typeof import('bootstrap-vue-next')['BPlaceholder']
    BPlaceholderTable: typeof import('bootstrap-vue-next')['BPlaceholderTable']
    BPlaceholderWrapper: typeof import('bootstrap-vue-next')['BPlaceholderWrapper']
    BPopover: typeof import('bootstrap-vue-next')['BPopover']
    BProgress: typeof import('bootstrap-vue-next')['BProgress']
    BProgressBar: typeof import('bootstrap-vue-next')['BProgressBar']
    BreadCrumbs: typeof import('./components/elements/BreadCrumbs.vue')['default']
    BreadCrumbs: typeof import('./components/elements/BreadCrumbs.vue')['default']
    BRow: typeof import('bootstrap-vue-next')['BRow']
    BRow: typeof import('bootstrap-vue-next')['BRow']
    BSpinner: typeof import('bootstrap-vue-next')['BSpinner']
    BSpinner: typeof import('bootstrap-vue-next')['BSpinner']
    BTab: typeof import('bootstrap-vue-next')['BTab']
    BTab: typeof import('bootstrap-vue-next')['BTab']
    BTable: typeof import('bootstrap-vue-next')['BTable']
    BTable: typeof import('bootstrap-vue-next')['BTable']
    BTabs: typeof import('bootstrap-vue-next')['BTabs']
    BTabs: typeof import('bootstrap-vue-next')['BTabs']
    BTh: typeof import('bootstrap-vue-next')['BTh']
    BToast: typeof import('bootstrap-vue-next')['BToast']
    BToast: typeof import('bootstrap-vue-next')['BToast']
    BToastOrchestrator: typeof import('bootstrap-vue-next')['BToastOrchestrator']
    BToastOrchestrator: typeof import('bootstrap-vue-next')['BToastOrchestrator']
    BTooltip: typeof import('bootstrap-vue-next')['BTooltip']
    BTooltip: typeof import('bootstrap-vue-next')['BTooltip']
    BTr: typeof import('bootstrap-vue-next')['BTr']
    CoscineCard: typeof import('./components/coscine/CoscineCard.vue')['default']
    CoscineCard: typeof import('./components/coscine/CoscineCard.vue')['default']
    CoscineFormGroup: typeof import('./components/coscine/CoscineFormGroup.vue')['default']
    CoscineFormGroup: typeof import('./components/coscine/CoscineFormGroup.vue')['default']
    CoscineHeadline: typeof import('./components/coscine/CoscineHeadline.vue')['default']
    CoscineHeadline: typeof import('./components/coscine/CoscineHeadline.vue')['default']
    CoscineModal: typeof import('./components/coscine/CoscineModal.vue')['default']
    CoscineModal: typeof import('./components/coscine/CoscineModal.vue')['default']
    ExpiryToast: typeof import('./components/toasts/ExpiryToast.vue')['default']
    ExpiryToast: typeof import('./components/toasts/ExpiryToast.vue')['default']
    Footer: typeof import('./components/elements/Footer.vue')['default']
    Footer: typeof import('./components/elements/Footer.vue')['default']
    FormGenerator: typeof import('@coscine/form-generator')['default']
    IBiArchive: typeof import('~icons/bi/archive')['default']
    IBiArchive: typeof import('~icons/bi/archive')['default']
    IBiArrowBarLeft: typeof import('~icons/bi/arrow-bar-left')['default']
    IBiArrowBarLeft: typeof import('~icons/bi/arrow-bar-left')['default']
    IBiArrowBarRight: typeof import('~icons/bi/arrow-bar-right')['default']
    IBiArrowBarRight: typeof import('~icons/bi/arrow-bar-right')['default']
@@ -82,32 +60,16 @@ declare module 'vue' {
    IBiCheck2: typeof import('~icons/bi/check2')['default']
    IBiCheck2: typeof import('~icons/bi/check2')['default']
    IBiCircleFill: typeof import('~icons/bi/circle-fill')['default']
    IBiCircleFill: typeof import('~icons/bi/circle-fill')['default']
    IBiCircleHalf: typeof import('~icons/bi/circle-half')['default']
    IBiCircleHalf: typeof import('~icons/bi/circle-half')['default']
    IBiClipboard: typeof import('~icons/bi/clipboard')['default']
    IBiFileEarmark: typeof import('~icons/bi/file-earmark')['default']
    IBiFileEarmarkPlus: typeof import('~icons/bi/file-earmark-plus')['default']
    IBiFolder: typeof import('~icons/bi/folder')['default']
    IBiFolder2Open: typeof import('~icons/bi/folder2-open')['default']
    IBiFolder2Open: typeof import('~icons/bi/folder2-open')['default']
    IBiFullscreen: typeof import('~icons/bi/fullscreen')['default']
    IBiFullscreenExit: typeof import('~icons/bi/fullscreen-exit')['default']
    IBiFunnel: typeof import('~icons/bi/funnel')['default']
    IBiGear: typeof import('~icons/bi/gear')['default']
    IBiGlobe2: typeof import('~icons/bi/globe2')['default']
    IBiGlobe2: typeof import('~icons/bi/globe2')['default']
    IBiHouse: typeof import('~icons/bi/house')['default']
    IBiHouse: typeof import('~icons/bi/house')['default']
    IBiHouseFill: typeof import('~icons/bi/house-fill')['default']
    IBiHouseFill: typeof import('~icons/bi/house-fill')['default']
    IBiInfoCircle: typeof import('~icons/bi/info-circle')['default']
    IBiLink45deg: typeof import('~icons/bi/link45deg')['default']
    IBiMoonStarsFill: typeof import('~icons/bi/moon-stars-fill')['default']
    IBiMoonStarsFill: typeof import('~icons/bi/moon-stars-fill')['default']
    IBiPencilFill: typeof import('~icons/bi/pencil-fill')['default']
    IBiPencilFill: typeof import('~icons/bi/pencil-fill')['default']
    IBiPeopleFill: typeof import('~icons/bi/people-fill')['default']
    IBiPerson: typeof import('~icons/bi/person')['default']
    IBiPerson: typeof import('~icons/bi/person')['default']
    IBiPlus: typeof import('~icons/bi/plus')['default']
    IBiPlusCircleFill: typeof import('~icons/bi/plus-circle-fill')['default']
    IBiPlusCircleFill: typeof import('~icons/bi/plus-circle-fill')['default']
    IBiSearch: typeof import('~icons/bi/search')['default']
    IBiSearch: typeof import('~icons/bi/search')['default']
    IBiShieldLockFill: typeof import('~icons/bi/shield-lock-fill')['default']
    IBiSortDown: typeof import('~icons/bi/sort-down')['default']
    IBiSortUp: typeof import('~icons/bi/sort-up')['default']
    IBiSunFill: typeof import('~icons/bi/sun-fill')['default']
    IBiSunFill: typeof import('~icons/bi/sun-fill')['default']
    IBiThreeDotsVertical: typeof import('~icons/bi/three-dots-vertical')['default']
    LoadingIndicator: typeof import('./components/elements/LoadingIndicator.vue')['default']
    LoadingIndicator: typeof import('./components/elements/LoadingIndicator.vue')['default']
    LoadingSpinner: typeof import('./components/coscine/LoadingSpinner.vue')['default']
    LoadingSpinner: typeof import('./components/coscine/LoadingSpinner.vue')['default']
    Maintenance: typeof import('./components/banner/Maintenance.vue')['default']
    Maintenance: typeof import('./components/banner/Maintenance.vue')['default']
+1 −6
Original line number Original line Diff line number Diff line
@@ -213,12 +213,7 @@ export default defineComponent({
      return [];
      return [];
    },
    },
    settingsMenu(): Array<SidebarItem> {
    settingsMenu(): Array<SidebarItem> {
      if (
      if (this.project && this.project.slug) {
        this.project &&
        this.project.slug &&
        this.currentUserRole &&
        this.currentUserRole.displayName === "Owner"
      ) {
        return [
        return [
          {
          {
            title: this.$t("sidebar.settings").toString(),
            title: this.$t("sidebar.settings").toString(),
+93 −0
Original line number Original line Diff line number Diff line
@@ -101,6 +101,80 @@ export const testProject: VisitedProjectDto = {
  creator: { id: getTestShibbolethUser().id },
  creator: { id: getTestShibbolethUser().id },
};
};


export const testProjectGuest: VisitedProjectDto = {
  id: "987654321",
  displayName: "Test Project",
  name: "Test Project Full",
  description: "Test Project Description",
  principleInvestigators: "Test PI",
  startDate: "2023-01-01",
  endDate: "2033-01-01",
  disciplines: [testDiscipline],
  organizations: [testOrganizationFromShibboleth],
  visibility: { id: "1234", displayName: "Project Members" },
  slug: testSlug,
  invitations: [],
  quotas: [
    {
      allocated: {
        value: 24,
        unit: "https://qudt.org/vocab/unit/GibiBYTE",
      },
      maximum: {
        value: 30,
        unit: "https://qudt.org/vocab/unit/GibiBYTE",
      },
      projectId: "987654321",
      resourceQuotas: [
        {
          resource: {
            id: "eeb8d803-46a1-49ba-a47c-81cd4f49cd65",
          },
          reserved: {
            value: 24,
            unit: "https://qudt.org/vocab/unit/GibiBYTE",
          },
          used: {
            value: 3.6323323523,
            unit: "https://qudt.org/vocab/unit/GibiBYTE",
          },
          usedPercentage: 15.134718134,
        },
      ],
      totalReserved: {
        value: 24,
        unit: "https://qudt.org/vocab/unit/GibiBYTE",
      },
      totalUsed: {
        value: 3.6323323523,
        unit: "https://qudt.org/vocab/unit/GibiBYTE",
      },
      resourceType: {
        id: testResourceType.id,
      },
    },
  ],
  resources: [
    {
      id: "eeb8d803-46a1-49ba-a47c-81cd4f49cd65",
      displayName: "Archived Test Resource",
      type: {
        id: "123497",
      },
      archived: true,
    },
  ],
  roles: [
    {
      project: { id: "987654321" },
      role: testGuestRole,
      user: getTestShibbolethUser(),
    },
  ], // TODO: Beware the object types!
  subProjects: [],
  creator: { id: getTestShibbolethUser().id },
};

export const testProjectState: ProjectState = {
export const testProjectState: ProjectState = {
  allProjects: [testProject],
  allProjects: [testProject],
  currentSlug: testSlug,
  currentSlug: testSlug,
@@ -120,3 +194,22 @@ export const testProjectState: ProjectState = {
    testProject: testProject,
    testProject: testProject,
  },
  },
};
};
export const testProjectStateGuest: ProjectState = {
  allProjects: [testProjectGuest],
  currentSlug: testSlug,
  disciplines: [testDiscipline],
  licenses: [{ id: "452545", displayName: "TestLicense" }],
  organizations: [testOrganizationFromShibboleth],
  publicationAdvisoryServices: null,
  organizationsComplete: true,
  organizationsFilter: "",
  roles: [testGuestRole],
  topLevelProjects: [testProjectGuest],
  visibilities: [
    { id: "1234", displayName: "Project Members" },
    { id: "123234324", displayName: "Public" },
  ],
  visitedProjects: {
    testProject: testProjectGuest,
  },
};
+35 −2
Original line number Original line Diff line number Diff line
@@ -16,7 +16,10 @@ i18n.global.availableLocales.forEach((locale) => {
import ConfigurationMetadata from "./ConfigurationMetadata.vue";
import ConfigurationMetadata from "./ConfigurationMetadata.vue";


/* Import of relevant mockup data */
/* Import of relevant mockup data */
import { testProjectState } from "@/data/mockup/testProject";
import {
  testProjectState,
  testProjectStateGuest,
} from "@/data/mockup/testProject";
import { getTestShibbolethUserState } from "@/data/mockup/testUser";
import { getTestShibbolethUserState } from "@/data/mockup/testUser";


describe("ConfigurationMetadata.vue", () => {
describe("ConfigurationMetadata.vue", () => {
@@ -36,7 +39,6 @@ describe("ConfigurationMetadata.vue", () => {
        },
        },
      }),
      }),
    });
    });

    // Check initial state of buttons
    // Check initial state of buttons
    expect(
    expect(
      (wrapper.get("#DeleteProjectBtn").element as HTMLButtonElement).disabled,
      (wrapper.get("#DeleteProjectBtn").element as HTMLButtonElement).disabled,
@@ -63,4 +65,35 @@ describe("ConfigurationMetadata.vue", () => {
      (wrapper.get("#SubmitProjectBtn").element as HTMLButtonElement).disabled,
      (wrapper.get("#SubmitProjectBtn").element as HTMLButtonElement).disabled,
    ).toBeFalsy(); // Submit button - active
    ).toBeFalsy(); // Submit button - active
  });
  });

  test("Should be read only for guests", async () => {
    /* Mount the Component */
    const wrapper = mount(ConfigurationMetadata, {
      pinia: createTestingPinia({
        createSpy: vitest.fn,
        initialState: {
          project: testProjectStateGuest,
          user: getTestShibbolethUserState(),
        },
      }),
    });
    await wrapper.vm.$nextTick();

    // Find element (ProjectName)
    const projectName = wrapper.find("#ProjectName");
    expect(projectName.exists()).toBeTruthy();
    // Change value of element
    await projectName.setValue("New Test Project");
    expect(wrapper.vm.projectForUpdate.displayName).toBe("Test Project");
    await wrapper.vm.$nextTick();
    // Find element (Description)
    const description = wrapper.find("#Description");
    expect(description.exists()).toBeTruthy();
    await wrapper.vm.$nextTick();
    // Change value of element
    await description.setValue("New Test Project for Guests");
    expect(wrapper.vm.projectForUpdate.description).toBe(
      "Test Project Description",
    );
  });
});
});
+1 −1
Original line number Original line Diff line number Diff line
@@ -184,7 +184,7 @@ export default defineComponent({
        name: "resource-settings",
        name: "resource-settings",
        params: { guid: resource.id, slug: this.project?.slug },
        params: { guid: resource.id, slug: this.project?.slug },
      } as RouteLocationRaw;
      } as RouteLocationRaw;
      return this.isGuest ? null : route;
      return route;
    },
    },
    openCreateProject(to: RouteLocationRaw) {
    openCreateProject(to: RouteLocationRaw) {
      if (!this.isGuest) {
      if (!this.isGuest) {
Loading