Skip to content
Snippets Groups Projects
Commit 39de9951 authored by Petar Hristov's avatar Petar Hristov :speech_balloon:
Browse files

Fix: Minor fixes from internal testing

parent 1012700b
No related branches found
No related tags found
2 merge requests!260Dev,!258Fix: Minor fixes from internal testing
Showing
with 212 additions and 135 deletions
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
}, },
"cSpell.words": [ "cSpell.words": [
"Coscine", "Coscine",
"Orcid",
"pinia", "pinia",
"RWTH", "RWTH",
"vite", "vite",
......
...@@ -11,9 +11,9 @@ ...@@ -11,9 +11,9 @@
{{ `${messageType}${$t("banner.separator")}` }} {{ `${messageType}${$t("banner.separator")}` }}
</span> </span>
{{ messageBody }} {{ messageBody }}
<span v-if="maintenance.url"> <span v-if="maintenance.href">
{{ $t("banner.maintenance.linkText") }} {{ $t("banner.maintenance.linkText") }}
<a :href="maintenance.url" target="_blank" <a :href="maintenance.href" target="_blank"
>{{ $t("banner.maintenance.moreInformation") }} >{{ $t("banner.maintenance.moreInformation") }}
</a> </a>
</span> </span>
......
...@@ -18,19 +18,20 @@ import useUserStore from "@/modules/user/store"; ...@@ -18,19 +18,20 @@ import useUserStore from "@/modules/user/store";
import { loadingCounterEventHandler } from "@/plugins/loadingCounter"; import { loadingCounterEventHandler } from "@/plugins/loadingCounter";
import { defineComponent } from "vue"; import { defineComponent } from "vue";
import type { StoreDefinition } from "pinia";
export default defineComponent({ export default defineComponent({
setup() { setup() {
const mainStore = useMainStore(); const mainStore = useMainStore();
loadingCounterEventHandler(useAdminStore); loadingCounterEventHandler(useAdminStore as unknown as StoreDefinition);
loadingCounterEventHandler(useErrorStore); loadingCounterEventHandler(useErrorStore as unknown as StoreDefinition);
loadingCounterEventHandler(useLoginStore); loadingCounterEventHandler(useLoginStore as unknown as StoreDefinition);
loadingCounterEventHandler(usePidStore); loadingCounterEventHandler(usePidStore as unknown as StoreDefinition);
loadingCounterEventHandler(useProjectStore); loadingCounterEventHandler(useProjectStore as unknown as StoreDefinition);
loadingCounterEventHandler(useResourceStore); loadingCounterEventHandler(useResourceStore as unknown as StoreDefinition);
loadingCounterEventHandler(useSearchStore); loadingCounterEventHandler(useSearchStore as unknown as StoreDefinition);
loadingCounterEventHandler(useUserStore); loadingCounterEventHandler(useUserStore as unknown as StoreDefinition);
return { mainStore }; return { mainStore };
}, },
......
import type { import type {
FileDto, FileTreeDto,
MetadataDto, MetadataTreeDto,
TreeDataType, TreeDataType,
} from "@coscine/api-client/dist/types/Coscine.Api"; } from "@coscine/api-client/dist/types/Coscine.Api";
export const getMetadataTreeResponse: MetadataDto[] = [ export const getMetadataTreeResponse: MetadataTreeDto[] = [
{ {
version: "1693212042", version: "1693212042",
availableVersions: ["1693212042"], availableVersions: ["1693212042"],
definition: definition: {
content:
'@base <https://purl.org/coscine/resources/4103cbea-ffa3-40a5-9e5c-b99cc16f0007/folder_1/folder_2/A.txt/@type=metadata&version=1693212042>.\r\n\r\n@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>.\r\n@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>.\r\n@prefix xsd: <http://www.w3.org/2001/XMLSchema#>.\r\n@prefix ns2: <http://purl.org/dc/terms/>.\r\n\r\n_:b8477997 ns2:created "2023-08-15"^^xsd:date;\r\n ns2:creator "Petar Hristov";\r\n ns2:title "Title inside Form Generator";\r\n a <https://purl.org/coscine/ap/base/>.\r\n', '@base <https://purl.org/coscine/resources/4103cbea-ffa3-40a5-9e5c-b99cc16f0007/folder_1/folder_2/A.txt/@type=metadata&version=1693212042>.\r\n\r\n@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>.\r\n@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>.\r\n@prefix xsd: <http://www.w3.org/2001/XMLSchema#>.\r\n@prefix ns2: <http://purl.org/dc/terms/>.\r\n\r\n_:b8477997 ns2:created "2023-08-15"^^xsd:date;\r\n ns2:creator "Petar Hristov";\r\n ns2:title "Title inside Form Generator";\r\n a <https://purl.org/coscine/ap/base/>.\r\n',
format: "text/turtle", type: "text/turtle",
},
path: "folder_1/folder_2/A.txt", path: "folder_1/folder_2/A.txt",
type: "Leaf" as TreeDataType.Leaf, type: "Leaf" as TreeDataType.Leaf,
}, },
{ {
version: "1692777419", version: "1692777419",
availableVersions: ["1692777419"], availableVersions: ["1692777419"],
definition: definition: {
content:
'@base <https://purl.org/coscine/resources/4103cbea-ffa3-40a5-9e5c-b99cc16f0007/file_1.txt/@type=metadata&version=1692777419>.\r\n\r\n@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>.\r\n@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>.\r\n@prefix xsd: <http://www.w3.org/2001/XMLSchema#>.\r\n@prefix ns2: <http://purl.org/dc/terms/>.\r\n\r\n_:b8425359 ns2:created "2023-08-18"^^xsd:date;\r\n ns2:creator "Petar Hristov";\r\n ns2:title "file_1";\r\n a <https://purl.org/coscine/ap/base/>.\r\n', '@base <https://purl.org/coscine/resources/4103cbea-ffa3-40a5-9e5c-b99cc16f0007/file_1.txt/@type=metadata&version=1692777419>.\r\n\r\n@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>.\r\n@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>.\r\n@prefix xsd: <http://www.w3.org/2001/XMLSchema#>.\r\n@prefix ns2: <http://purl.org/dc/terms/>.\r\n\r\n_:b8425359 ns2:created "2023-08-18"^^xsd:date;\r\n ns2:creator "Petar Hristov";\r\n ns2:title "file_1";\r\n a <https://purl.org/coscine/ap/base/>.\r\n',
format: "text/turtle", type: "text/turtle",
},
path: "file_1.txt", path: "file_1.txt",
type: "Leaf" as TreeDataType.Leaf, type: "Leaf" as TreeDataType.Leaf,
}, },
...@@ -32,25 +36,29 @@ export const getMetadataTreeResponse: MetadataDto[] = [ ...@@ -32,25 +36,29 @@ export const getMetadataTreeResponse: MetadataDto[] = [
"1692341031", "1692341031",
"1692779210", "1692779210",
], ],
definition: definition: {
content:
'@base <https://purl.org/coscine/resources/4103cbea-ffa3-40a5-9e5c-b99cc16f0007/file_0.txt/@type=metadata&version=1692779210>.\r\n\r\n@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>.\r\n@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>.\r\n@prefix xsd: <http://www.w3.org/2001/XMLSchema#>.\r\n@prefix ns2: <http://purl.org/dc/terms/>.\r\n\r\n_:b8425361 ns2:created "2023-08-18"^^xsd:date;\r\n ns2:creator "Petar Hristov";\r\n ns2:title "Revised";\r\n a <https://purl.org/coscine/ap/base/>.\r\n', '@base <https://purl.org/coscine/resources/4103cbea-ffa3-40a5-9e5c-b99cc16f0007/file_0.txt/@type=metadata&version=1692779210>.\r\n\r\n@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>.\r\n@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>.\r\n@prefix xsd: <http://www.w3.org/2001/XMLSchema#>.\r\n@prefix ns2: <http://purl.org/dc/terms/>.\r\n\r\n_:b8425361 ns2:created "2023-08-18"^^xsd:date;\r\n ns2:creator "Petar Hristov";\r\n ns2:title "Revised";\r\n a <https://purl.org/coscine/ap/base/>.\r\n',
format: "text/turtle", type: "text/turtle",
},
path: "file_0.txt", path: "file_0.txt",
type: "Leaf" as TreeDataType.Leaf, type: "Leaf" as TreeDataType.Leaf,
}, },
{ {
version: "1693209938", version: "1693209938",
availableVersions: ["1693209938"], availableVersions: ["1693209938"],
definition: definition: {
content:
'@base <https://purl.org/coscine/resources/4103cbea-ffa3-40a5-9e5c-b99cc16f0007/my_folder/file_of_folder.txt/@type=metadata&version=1693209938>.\r\n\r\n@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>.\r\n@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>.\r\n@prefix xsd: <http://www.w3.org/2001/XMLSchema#>.\r\n@prefix ns2: <http://purl.org/dc/terms/>.\r\n\r\n_:b8477996 ns2:created "2023-08-15"^^xsd:date;\r\n ns2:creator "Petar Hristov";\r\n ns2:title "From Insomnia";\r\n a <https://purl.org/coscine/ap/base/>.\r\n', '@base <https://purl.org/coscine/resources/4103cbea-ffa3-40a5-9e5c-b99cc16f0007/my_folder/file_of_folder.txt/@type=metadata&version=1693209938>.\r\n\r\n@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>.\r\n@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>.\r\n@prefix xsd: <http://www.w3.org/2001/XMLSchema#>.\r\n@prefix ns2: <http://purl.org/dc/terms/>.\r\n\r\n_:b8477996 ns2:created "2023-08-15"^^xsd:date;\r\n ns2:creator "Petar Hristov";\r\n ns2:title "From Insomnia";\r\n a <https://purl.org/coscine/ap/base/>.\r\n',
format: "text/turtle", type: "text/turtle",
},
path: "my_folder/file_of_folder.txt", path: "my_folder/file_of_folder.txt",
type: "Leaf" as TreeDataType.Leaf, type: "Leaf" as TreeDataType.Leaf,
}, },
]; ];
export const getFileTreeResponse: FileDto[] = [ export const getFileTreeResponse: FileTreeDto[] = [
{ {
parentDirectory: "", directory: "",
name: "folder_1", name: "folder_1",
size: 0, size: 0,
creationDate: "2023-09-01T16:57:48.2525218+02:00", creationDate: "2023-09-01T16:57:48.2525218+02:00",
...@@ -59,7 +67,7 @@ export const getFileTreeResponse: FileDto[] = [ ...@@ -59,7 +67,7 @@ export const getFileTreeResponse: FileDto[] = [
type: "Tree" as TreeDataType.Tree, type: "Tree" as TreeDataType.Tree,
}, },
{ {
parentDirectory: "", directory: "",
name: "my_folder", name: "my_folder",
size: 0, size: 0,
creationDate: "2023-09-01T16:57:48.2525245+02:00", creationDate: "2023-09-01T16:57:48.2525245+02:00",
...@@ -68,7 +76,7 @@ export const getFileTreeResponse: FileDto[] = [ ...@@ -68,7 +76,7 @@ export const getFileTreeResponse: FileDto[] = [
type: "Tree" as TreeDataType.Tree, type: "Tree" as TreeDataType.Tree,
}, },
{ {
parentDirectory: "", directory: "",
name: "file_0.txt", name: "file_0.txt",
extension: "txt", extension: "txt",
size: 2513352, size: 2513352,
......
...@@ -2,9 +2,8 @@ import { type LoginState } from "@/modules/login/types"; ...@@ -2,9 +2,8 @@ import { type LoginState } from "@/modules/login/types";
import { useLocalStorage } from "@vueuse/core"; import { useLocalStorage } from "@vueuse/core";
export const testLoginState: LoginState = { export const testLoginState: LoginState = {
currentTosVersion: "1", currentTosVersion: { version: "1", isCurrent: true },
expiredSession: false, expiredSession: false,
tosAccepted: { version: ["1"] },
loginStoredData: useLocalStorage("coscine.login.storedData", ""), loginStoredData: useLocalStorage("coscine.login.storedData", ""),
loginUrls: { loginUrls: {
orcidUrl: "http://example.org", orcidUrl: "http://example.org",
......
import { userMapper, PublicUserDto2ProjectRoleUserDto } from "@/mapping/user";
import { import {
type VisitedProjectDto, type VisitedProjectDto,
type ProjectState, type ProjectState,
} from "@/modules/project/types"; } from "@/modules/project/types";
import type { RoleDto } from "@coscine/api-client/dist/types/Coscine.Api"; import type { RoleDto } from "@coscine/api-client/dist/types/Coscine.Api";
import { testDiscipline, testOrganization, getTestUser } from "./testUser"; import {
testDiscipline,
testOrganizationFromShibboleth,
getTestShibbolethUser,
} from "./testUser";
export const testOwnerRole: RoleDto = { export const testOwnerRole: RoleDto = {
id: "ownerRole", id: "ownerRole",
...@@ -26,13 +29,13 @@ export const testSlug = "testProject"; ...@@ -26,13 +29,13 @@ export const testSlug = "testProject";
export const testProject: VisitedProjectDto = { export const testProject: VisitedProjectDto = {
id: "987654321", id: "987654321",
displayName: "Test Project", displayName: "Test Project",
projectName: "Test Project Full", name: "Test Project Full",
description: "Test Project Description", description: "Test Project Description",
principleInvestigators: "Test PI", principleInvestigators: "Test PI",
startDate: "2023-01-01", startDate: "2023-01-01",
endDate: "2033-01-01", endDate: "2033-01-01",
disciplines: [testDiscipline], disciplines: [testDiscipline],
organizations: [testOrganization], organizations: [testOrganizationFromShibboleth],
visibility: { id: "1234", displayName: "Project Members" }, visibility: { id: "1234", displayName: "Project Members" },
slug: testSlug, slug: testSlug,
invitations: [], invitations: [],
...@@ -45,13 +48,13 @@ export const testProject: VisitedProjectDto = { ...@@ -45,13 +48,13 @@ export const testProject: VisitedProjectDto = {
], ],
roles: [ roles: [
{ {
projectId: "987654321", project: { id: "987654321" },
role: testOwnerRole, role: testOwnerRole,
user: userMapper.map(PublicUserDto2ProjectRoleUserDto, getTestUser()), user: getTestShibbolethUser(),
}, },
], // TODO: Beware the object types! ], // TODO: Beware the object types!
subProjects: [], subProjects: [],
creator: getTestUser().id, creator: { id: getTestShibbolethUser().id },
}; };
export const testProjectState: ProjectState = { export const testProjectState: ProjectState = {
...@@ -59,7 +62,7 @@ export const testProjectState: ProjectState = { ...@@ -59,7 +62,7 @@ export const testProjectState: ProjectState = {
currentSlug: testSlug, currentSlug: testSlug,
disciplines: [testDiscipline], disciplines: [testDiscipline],
licenses: [{ id: "452545", displayName: "TestLicense" }], licenses: [{ id: "452545", displayName: "TestLicense" }],
organizations: [testOrganization], organizations: [testOrganizationFromShibboleth],
roles: [testOwnerRole, testMemberRole, testGuestRole], roles: [testOwnerRole, testMemberRole, testGuestRole],
topLevelProjects: [testProject], topLevelProjects: [testProject],
visibilities: [ visibilities: [
......
...@@ -8,7 +8,7 @@ import { ...@@ -8,7 +8,7 @@ import {
baseApplicationProfileFormat, baseApplicationProfileFormat,
} from "./metadata/applicationProfile"; } from "./metadata/applicationProfile";
import { radarFixedValues } from "./metadata/fixedValues"; import { radarFixedValues } from "./metadata/fixedValues";
import { testDiscipline, getTestUser } from "./testUser"; import { testDiscipline, getTestShibbolethUser } from "./testUser";
import type { import type {
ResourceTypeInformationDto, ResourceTypeInformationDto,
ResourceTypeStatus, ResourceTypeStatus,
...@@ -50,9 +50,9 @@ export const getTestResource: () => Promise<VisitedResourceObject> = ...@@ -50,9 +50,9 @@ export const getTestResource: () => Promise<VisitedResourceObject> =
apUrl apUrl
); );
const resourceObject: VisitedResourceObject = { const resourceObject: VisitedResourceObject = {
applicationProfile: apUrl, applicationProfile: { uri: apUrl },
archived: false, archived: false,
creator: getTestUser().id, creator: getTestShibbolethUser().id,
dateCreated: null, dateCreated: null,
description: "TestResource", description: "TestResource",
disciplines: [testDiscipline], disciplines: [testDiscipline],
...@@ -64,13 +64,13 @@ export const getTestResource: () => Promise<VisitedResourceObject> = ...@@ -64,13 +64,13 @@ export const getTestResource: () => Promise<VisitedResourceObject> =
license: {}, license: {},
pid: "21.11102/eeb8d803-46a1-49ba-a47c-81cd4f49cd65", pid: "21.11102/eeb8d803-46a1-49ba-a47c-81cd4f49cd65",
rawApplicationProfile: ap, rawApplicationProfile: ap,
resourceName: "TestResource", name: "TestResource",
storedColumns: null, storedColumns: null,
type: { type: {
specificType: testResourceType.specificType, specificType: testResourceType.specificType ?? undefined,
id: testResourceType.id, id: testResourceType.id,
options: { options: {
gitLabOptions: {}, gitLab: {},
}, },
}, },
usageRights: "", usageRights: "",
......
...@@ -2,48 +2,112 @@ import { type UserState } from "@/modules/user/types"; ...@@ -2,48 +2,112 @@ import { type UserState } from "@/modules/user/types";
import type { import type {
DisciplineDto, DisciplineDto,
UserDto, UserDto,
UserInstituteDto,
UserOrganizationDto, UserOrganizationDto,
} from "@coscine/api-client/dist/types/Coscine.Api/api"; } from "@coscine/api-client/dist/types/Coscine.Api/api";
export const testOrganization: UserOrganizationDto = { export const testOrganizationFromShibboleth: UserOrganizationDto = {
name: "TestOrg", displayName: "Test SSO Organization",
readOnly: true, readOnly: true, // Shibboleth organizations are always read-only
rorUri: "example.com", uri: "example.com",
}; };
export const testInstitute: UserOrganizationDto = { export const testInstituteFromShibboleth: UserInstituteDto = {
name: "TestInstitute", displayName: "Test SSO Institute",
readOnly: true, readOnly: true, // Shibboleth institutes are always read-only
rorUri: "example.com#institute", uri: "example.com#institute",
}; };
export const testOrganizationFromOrcid: UserOrganizationDto = {
displayName: "Test ORCiD Organization",
readOnly: true, // ORCiD organizations are never read-only
uri: "example.com",
};
export const testInstituteFromOrcid: UserInstituteDto = {
displayName: "Test ORCiD Institute",
readOnly: true, // ORCiD institutes are never read-only
uri: "example.com#institute",
};
export const testDiscipline: DisciplineDto = { export const testDiscipline: DisciplineDto = {
id: "1", id: "1",
displayNameDe: "Test", displayNameDe: "Test",
displayNameEn: "Test", displayNameEn: "Test",
url: "example.com", uri: "example.com",
}; };
export const testLanguage = { id: "1", displayName: "en" }; export const testLanguage = { id: "1", displayName: "en" };
export const getTestUser: () => UserDto = () => { /**
* Generates a mock Shibboleth user data object for testing purposes.
*
* @returns {UserDto} A mock Shibboleth user data object.
*/
export const getTestShibbolethUser: () => UserDto = () => {
return { return {
id: "d302cb44-c934-4b54-a581-9765cab96fca", id: "d302cb44-c934-4b54-a581-9765cab96fca",
lastName: "Coscine", givenName: "Coscine",
firstName: "Example", familyName: "Example",
displayName: "Coscine Example", displayName: "Coscine Example",
email: "example@example.com", emails: [
{ email: "example@university.com", isConfirmed: true, isPrimary: true },
],
disciplines: [testDiscipline], disciplines: [testDiscipline],
language: testLanguage, language: testLanguage,
organizations: [testOrganization], organizations: [testOrganizationFromShibboleth],
institutes: [testInstitute], institutes: [testInstituteFromShibboleth],
};
};
/**
* Generates a mock ORCID user data object for testing purposes.
*
* @returns {UserDto} A mock ORCID user data object.
*/
export const getTestOrcidUser: () => UserDto = () => {
return {
id: "d302cb44-c934-4b54-a581-9765cab96fca",
givenName: "Coscine",
familyName: "Example",
displayName: "Coscine Example",
emails: [
{ email: "example@orcid.com", isConfirmed: true, isPrimary: true },
],
disciplines: [testDiscipline],
language: testLanguage,
organizations: [testOrganizationFromOrcid],
institutes: [testInstituteFromOrcid],
};
};
export const getTestShibbolethUserState: () => UserState = () => {
return {
userProfile: {
disciplines: [testDiscipline],
languages: [testLanguage, { id: "2", displayName: "de" }],
organizations: [testOrganizationFromShibboleth],
institutes: [testInstituteFromShibboleth],
titles: [
{
id: "1",
displayName: "Prof.",
},
{
id: "2",
displayName: "Dr.",
},
],
tokens: null,
},
user: getTestShibbolethUser(),
}; };
}; };
export const getTestUserState: () => UserState = () => { export const getTestOrcidUserState: () => UserState = () => {
return { return {
userProfile: { userProfile: {
disciplines: [testDiscipline], disciplines: [testDiscipline],
languages: [testLanguage, { id: "2", displayName: "de" }], languages: [testLanguage, { id: "2", displayName: "de" }],
organizations: [testOrganization], organizations: [testOrganizationFromShibboleth],
institutes: [testInstitute], institutes: [testInstituteFromShibboleth],
titles: [ titles: [
{ {
id: "1", id: "1",
...@@ -56,6 +120,6 @@ export const getTestUserState: () => UserState = () => { ...@@ -56,6 +120,6 @@ export const getTestUserState: () => UserState = () => {
], ],
tokens: null, tokens: null,
}, },
user: getTestUser(), user: getTestOrcidUser(),
}; };
}; };
...@@ -24,6 +24,7 @@ export const OrganizationDto2OrganizationForProjectManipulationDto = ...@@ -24,6 +24,7 @@ export const OrganizationDto2OrganizationForProjectManipulationDto =
const configuration = new MapperConfiguration((cfg) => { const configuration = new MapperConfiguration((cfg) => {
cfg.createAutoMap(ProjectDto2ProjectForUpdateDto, { cfg.createAutoMap(ProjectDto2ProjectForUpdateDto, {
name: (opt) => opt.mapFrom((e) => e.name ?? ""),
disciplines: (opt) => disciplines: (opt) =>
opt.mapFromUsing( opt.mapFromUsing(
(e) => e.disciplines, (e) => e.disciplines,
...@@ -45,7 +46,9 @@ const configuration = new MapperConfiguration((cfg) => { ...@@ -45,7 +46,9 @@ const configuration = new MapperConfiguration((cfg) => {
.createAutoMap(VisibilityDto2VisibilityForProjectManipulationDto, {}) .createAutoMap(VisibilityDto2VisibilityForProjectManipulationDto, {})
.forSourceMember("displayName", (opt) => opt.ignore()); .forSourceMember("displayName", (opt) => opt.ignore());
cfg.createAutoMap(DisciplineDto2DisciplineForProjectManipulationDto, {}); cfg.createAutoMap(DisciplineDto2DisciplineForProjectManipulationDto, {});
cfg.createAutoMap(OrganizationDto2OrganizationForProjectManipulationDto, {}); cfg.createAutoMap(OrganizationDto2OrganizationForProjectManipulationDto, {
uri: (opt) => opt.mapFrom((e) => e.uri ?? ""),
});
}); });
export const projectMapper = configuration.createMapper(); export const projectMapper = configuration.createMapper();
...@@ -70,6 +70,8 @@ export const ResourceTypeInformationDto2ResourceTypeOptionsForCreationDto = ...@@ -70,6 +70,8 @@ export const ResourceTypeInformationDto2ResourceTypeOptionsForCreationDto =
const configuration = new MapperConfiguration((cfg) => { const configuration = new MapperConfiguration((cfg) => {
cfg.createAutoMap(ResourceDto2ResourceForUpdateDto, { cfg.createAutoMap(ResourceDto2ResourceForUpdateDto, {
name: (opt) => opt.mapFrom((e) => e.name ?? ""),
usageNote: (opt) => opt.mapFrom((e) => e.usageRights),
license: (opt) => license: (opt) =>
opt.mapFromUsing( opt.mapFromUsing(
(e) => e.license, (e) => e.license,
...@@ -98,31 +100,31 @@ const configuration = new MapperConfiguration((cfg) => { ...@@ -98,31 +100,31 @@ const configuration = new MapperConfiguration((cfg) => {
gitlabResourceTypeOptions: (opt) => gitlabResourceTypeOptions: (opt) =>
opt opt
.mapFromUsing( .mapFromUsing(
(e) => e.gitLabOptions, (e) => e.gitLab,
GitLabOptionsDto2GitlabResourceTypeOptionsForUpdateDto GitLabOptionsDto2GitlabResourceTypeOptionsForUpdateDto
) )
.condition((con) => con.gitLabOptions !== undefined), .condition((con) => con.gitLab !== undefined),
rdsResourceTypeOptions: (opt) => rdsResourceTypeOptions: (opt) =>
opt opt
.mapFromUsing( .mapFromUsing(
(e) => e.rdsOptions, (e) => e.rds,
RdsOptionsDto2RdsResourceTypeOptionsForManipulationDto RdsOptionsDto2RdsResourceTypeOptionsForManipulationDto
) )
.condition((con) => con.rdsOptions !== undefined), .condition((con) => con.rds !== undefined),
rdsS3ResourceTypeOptions: (opt) => rdsS3ResourceTypeOptions: (opt) =>
opt opt
.mapFromUsing( .mapFromUsing(
(e) => e.rdsS3Options, (e) => e.rdsS3,
RdsS3OptionsDto2RdsS3ResourceTypeOptionsForManipulationDto RdsS3OptionsDto2RdsS3ResourceTypeOptionsForManipulationDto
) )
.condition((con) => con.rdsS3Options !== undefined), .condition((con) => con.rdsS3 !== undefined),
rdsS3WormResourceTypeOptions: (opt) => rdsS3WormResourceTypeOptions: (opt) =>
opt opt
.mapFromUsing( .mapFromUsing(
(e) => e.rdsS3WormOptions, (e) => e.rdsS3Worm,
RdsS3WormOptionsDto2RdsS3WormResourceTypeOptionsForManipulationDto RdsS3WormOptionsDto2RdsS3WormResourceTypeOptionsForManipulationDto
) )
.condition((con) => con.rdsS3WormOptions !== undefined), .condition((con) => con.rdsS3Worm !== undefined),
}); });
cfg.createMap(ResourceTypeInformationDto2ResourceTypeOptionsForCreationDto, { cfg.createMap(ResourceTypeInformationDto2ResourceTypeOptionsForCreationDto, {
linkedResourceTypeOptions: (opt) => linkedResourceTypeOptions: (opt) =>
...@@ -176,20 +178,20 @@ const configuration = new MapperConfiguration((cfg) => { ...@@ -176,20 +178,20 @@ const configuration = new MapperConfiguration((cfg) => {
}); });
cfg.createAutoMap(GitLabOptionsDto2GitlabResourceTypeOptionsForUpdateDto, {}); cfg.createAutoMap(GitLabOptionsDto2GitlabResourceTypeOptionsForUpdateDto, {});
cfg.createAutoMap(RdsOptionsDto2RdsResourceTypeOptionsForManipulationDto, { cfg.createAutoMap(RdsOptionsDto2RdsResourceTypeOptionsForManipulationDto, {
size: (opt) => quota: (opt) =>
opt.mapFromUsing((e) => e.size, QuotaDto2QuotaForManipulationDto), opt.mapFromUsing((e) => e.size, QuotaDto2QuotaForManipulationDto),
}); });
cfg.createAutoMap( cfg.createAutoMap(
RdsS3OptionsDto2RdsS3ResourceTypeOptionsForManipulationDto, RdsS3OptionsDto2RdsS3ResourceTypeOptionsForManipulationDto,
{ {
size: (opt) => quota: (opt) =>
opt.mapFromUsing((e) => e.size, QuotaDto2QuotaForManipulationDto), opt.mapFromUsing((e) => e.size, QuotaDto2QuotaForManipulationDto),
} }
); );
cfg.createAutoMap( cfg.createAutoMap(
RdsS3WormOptionsDto2RdsS3WormResourceTypeOptionsForManipulationDto, RdsS3WormOptionsDto2RdsS3WormResourceTypeOptionsForManipulationDto,
{ {
size: (opt) => quota: (opt) =>
opt.mapFromUsing((e) => e.size, QuotaDto2QuotaForManipulationDto), opt.mapFromUsing((e) => e.size, QuotaDto2QuotaForManipulationDto),
} }
); );
......
...@@ -3,7 +3,7 @@ import { v4 as uuidv4 } from "uuid"; ...@@ -3,7 +3,7 @@ import { v4 as uuidv4 } from "uuid";
import type { import type {
TreeDataType, TreeDataType,
FileDto, FileTreeDto,
} from "@coscine/api-client/dist/types/Coscine.Api"; } from "@coscine/api-client/dist/types/Coscine.Api";
import type { import type {
FileInformation, FileInformation,
...@@ -11,12 +11,12 @@ import type { ...@@ -11,12 +11,12 @@ import type {
} from "@/modules/resource/types"; } from "@/modules/resource/types";
export const TreeDto2FileInformation = new MappingPair< export const TreeDto2FileInformation = new MappingPair<
FileDto, FileTreeDto,
FileInformation FileInformation
>(); >();
export const TreeDto2FolderInformation = new MappingPair< export const TreeDto2FolderInformation = new MappingPair<
FileDto, FileTreeDto,
FolderInformation FolderInformation
>(); >();
...@@ -24,7 +24,7 @@ const configuration = new MapperConfiguration((cfg) => { ...@@ -24,7 +24,7 @@ const configuration = new MapperConfiguration((cfg) => {
cfg.createMap(TreeDto2FileInformation, { cfg.createMap(TreeDto2FileInformation, {
id: (opt) => opt.mapFrom((_) => uuidv4()), id: (opt) => opt.mapFrom((_) => uuidv4()),
name: (opt) => opt.mapFrom((dto) => dto.name ?? ""), name: (opt) => opt.mapFrom((dto) => dto.name ?? ""),
parentDirectory: (opt) => opt.mapFrom((dto) => dto.parentDirectory ?? ""), parentDirectory: (opt) => opt.mapFrom((dto) => dto.directory ?? ""),
path: (opt) => opt.mapFrom((dto) => dto.path ?? ""), path: (opt) => opt.mapFrom((dto) => dto.path ?? ""),
type: (opt) => opt.mapFrom((_) => "Leaf" as TreeDataType.Leaf), type: (opt) => opt.mapFrom((_) => "Leaf" as TreeDataType.Leaf),
isFolder: (opt) => opt.mapFrom((_) => false), isFolder: (opt) => opt.mapFrom((_) => false),
...@@ -38,7 +38,7 @@ const configuration = new MapperConfiguration((cfg) => { ...@@ -38,7 +38,7 @@ const configuration = new MapperConfiguration((cfg) => {
cfg.createMap(TreeDto2FolderInformation, { cfg.createMap(TreeDto2FolderInformation, {
id: (opt) => opt.mapFrom((_) => uuidv4()), id: (opt) => opt.mapFrom((_) => uuidv4()),
name: (opt) => opt.mapFrom((dto) => dto.name ?? ""), name: (opt) => opt.mapFrom((dto) => dto.name ?? ""),
parentDirectory: (opt) => opt.mapFrom((dto) => dto.parentDirectory ?? ""), parentDirectory: (opt) => opt.mapFrom((dto) => dto.directory ?? ""),
path: (opt) => opt.mapFrom((dto) => dto.path ?? ""), path: (opt) => opt.mapFrom((dto) => dto.path ?? ""),
type: (opt) => opt.mapFrom((_) => "Tree" as TreeDataType.Tree), type: (opt) => opt.mapFrom((_) => "Tree" as TreeDataType.Tree),
isFolder: (opt) => opt.mapFrom((_) => true), isFolder: (opt) => opt.mapFrom((_) => true),
......
...@@ -5,18 +5,12 @@ import type { ...@@ -5,18 +5,12 @@ import type {
DisciplineForUserManipulationDto, DisciplineForUserManipulationDto,
LanguageDto, LanguageDto,
LanguageForUserManipulationDto, LanguageForUserManipulationDto,
ProjectRoleUserDto,
PublicUserDto,
TitleDto, TitleDto,
TitleForUserManipulationDto, TitleForUserManipulationDto,
UserDto, UserDto,
UserForUpdateDto, UserForUpdateDto,
} from "@coscine/api-client/dist/types/Coscine.Api"; } from "@coscine/api-client/dist/types/Coscine.Api";
export const PublicUserDto2ProjectRoleUserDto = new MappingPair<
PublicUserDto,
ProjectRoleUserDto
>();
export const UserDto2UserForUpdateDto = new MappingPair< export const UserDto2UserForUpdateDto = new MappingPair<
UserDto, UserDto,
UserForUpdateDto UserForUpdateDto
...@@ -35,16 +29,11 @@ export const LanguageDto2LanguageForUserManipulationDto = new MappingPair< ...@@ -35,16 +29,11 @@ export const LanguageDto2LanguageForUserManipulationDto = new MappingPair<
>(); >();
const configuration = new MapperConfiguration((cfg) => { const configuration = new MapperConfiguration((cfg) => {
cfg.createAutoMap(PublicUserDto2ProjectRoleUserDto, {
emailAddress: (opt) => opt.mapFrom((u) => u.email),
userId: (opt) => opt.mapFrom((u) => u.id),
firstName: (opt) => opt.mapFrom((u) => u.firstName),
lastName: (opt) => opt.mapFrom((u) => u.lastName),
});
cfg.createMap(UserDto2UserForUpdateDto, { cfg.createMap(UserDto2UserForUpdateDto, {
firstName: (opt) => opt.auto(), givenName: (opt) => opt.mapFrom((dto) => dto.givenName ?? ""),
lastName: (opt) => opt.auto(), familyName: (opt) => opt.mapFrom((dto) => dto.familyName ?? ""),
email: (opt) => opt.auto(), email: (opt) =>
opt.mapFrom((dto) => dto.emails?.find((e) => e.isPrimary)?.email ?? ""),
title: (opt) => title: (opt) =>
opt opt
.condition((dto) => undefined !== dto.title) .condition((dto) => undefined !== dto.title)
...@@ -61,11 +50,11 @@ const configuration = new MapperConfiguration((cfg) => { ...@@ -61,11 +50,11 @@ const configuration = new MapperConfiguration((cfg) => {
), ),
institute: (opt) => institute: (opt) =>
opt.mapFrom((dto) => opt.mapFrom((dto) =>
dto.institutes?.length ? dto.institutes[0].name : "" dto.institutes?.length ? dto.institutes[0].displayName : ""
), ),
organization: (opt) => organization: (opt) =>
opt.mapFrom((dto) => opt.mapFrom((dto) =>
dto.organizations?.length ? dto.organizations[0].name : null dto.organizations?.length ? dto.organizations[0].displayName : null
), ),
}); });
cfg.createAutoMap(TitleDto2TitleForUserManipulationDto, {}); cfg.createAutoMap(TitleDto2TitleForUserManipulationDto, {});
......
...@@ -8,10 +8,11 @@ import type { DFNAAIData, DFNAAIInstitution, LoginState } from "./types"; ...@@ -8,10 +8,11 @@ import type { DFNAAIData, DFNAAIInstitution, LoginState } from "./types";
import useMainStore from "@/store/index"; import useMainStore from "@/store/index";
import useNotificationStore from "@/store/notification"; import useNotificationStore from "@/store/notification";
import { useLocalStorage } from "@vueuse/core"; import { useLocalStorage } from "@vueuse/core";
import { AccountApi, ToSApi, UserApi } from "@coscine/api-client"; import { AccountApi, SelfApi, TosApi } from "@coscine/api-client";
import type { AxiosError } from "axios"; import type { AxiosError } from "axios";
import axios from "axios"; import axios from "axios";
import type { LoginUrls } from "@coscine/api-client/dist/types/Coscine.Api.STS"; import type { LoginUrls } from "@coscine/api-client/dist/types/Coscine.Api.STS";
import { UserTermsOfServiceAcceptDto } from "@coscine/api-client/dist/types/Coscine.Api";
/* /*
Store variable name is "this.<id>Store" Store variable name is "this.<id>Store"
...@@ -145,7 +146,7 @@ export const useLoginStore = defineStore({ ...@@ -145,7 +146,7 @@ export const useLoginStore = defineStore({
async retrieveCurrentTosVersion() { async retrieveCurrentTosVersion() {
const notificationStore = useNotificationStore(); const notificationStore = useNotificationStore();
try { try {
const apiResponse = await ToSApi.getToS(); const apiResponse = await TosApi.getTos();
this.currentTosVersion = apiResponse.data.data; this.currentTosVersion = apiResponse.data.data;
} catch (error) { } catch (error) {
// Handle other Status Codes // Handle other Status Codes
...@@ -171,7 +172,15 @@ export const useLoginStore = defineStore({ ...@@ -171,7 +172,15 @@ export const useLoginStore = defineStore({
async acceptToS(): Promise<boolean> { async acceptToS(): Promise<boolean> {
const notificationStore = useNotificationStore(); const notificationStore = useNotificationStore();
try { try {
await UserApi.acceptCurrentToS(); // Retrieve the current TOS version if missing
if (!this.currentTosVersion?.version) {
await this.retrieveCurrentTosVersion();
}
// Build the DTO and send it
const userTermsOfServiceAcceptDto: UserTermsOfServiceAcceptDto = {
version: this.currentTosVersion?.version ?? "",
};
await SelfApi.acceptCurrentTos(userTermsOfServiceAcceptDto);
return true; return true;
} catch (error) { } catch (error) {
// Handle other Status Codes // Handle other Status Codes
......
...@@ -149,7 +149,7 @@ import usePidStore from "../store"; ...@@ -149,7 +149,7 @@ import usePidStore from "../store";
import useNotificationStore from "@/store/notification"; import useNotificationStore from "@/store/notification";
import { useVuelidate, type ValidationArgs } from "@vuelidate/core"; import { useVuelidate, type ValidationArgs } from "@vuelidate/core";
import { email, maxLength, required } from "@vuelidate/validators"; import { email, maxLength, required } from "@vuelidate/validators";
import type { PidEnquiryDto } from "@coscine/api-client/dist/types/Coscine.Api/api"; import type { PidRequestDto } from "@coscine/api-client/dist/types/Coscine.Api/api";
export default defineComponent({ export default defineComponent({
setup() { setup() {
...@@ -168,7 +168,7 @@ export default defineComponent({ ...@@ -168,7 +168,7 @@ export default defineComponent({
email: "", email: "",
message: "", message: "",
sendConfirmationEmail: true, sendConfirmationEmail: true,
} as PidEnquiryDto, } as PidRequestDto,
isLoading: false, isLoading: false,
isPidValid: null as boolean | null, isPidValid: null as boolean | null,
}; };
...@@ -190,7 +190,7 @@ export default defineComponent({ ...@@ -190,7 +190,7 @@ export default defineComponent({
email: { email, required }, email: { email, required },
message: { required, maxLength: maxLength(5000) }, message: { required, maxLength: maxLength(5000) },
sendConfirmationEmail: { required }, sendConfirmationEmail: { required },
} as ValidationArgs<PidEnquiryDto>, } as ValidationArgs<PidRequestDto>,
}; };
}, },
......
...@@ -5,7 +5,7 @@ import useNotificationStore from "@/store/notification"; ...@@ -5,7 +5,7 @@ import useNotificationStore from "@/store/notification";
import { PidApi } from "@coscine/api-client"; import { PidApi } from "@coscine/api-client";
import { AxiosError } from "axios"; import { AxiosError } from "axios";
import { StatusCodes } from "http-status-codes"; import { StatusCodes } from "http-status-codes";
import type { PidEnquiryDto } from "@coscine/api-client/dist/types/Coscine.Api/api"; import type { PidRequestDto } from "@coscine/api-client/dist/types/Coscine.Api/api";
/* /*
Store variable name is "this.<id>Store" Store variable name is "this.<id>Store"
...@@ -64,20 +64,20 @@ export const usePidStore = defineStore({ ...@@ -64,20 +64,20 @@ export const usePidStore = defineStore({
* Contacts the PID owner using the provided PID prefix, ID, and PID enquiry data. * Contacts the PID owner using the provided PID prefix, ID, and PID enquiry data.
* @param {string} prefix - The PID prefix value. * @param {string} prefix - The PID prefix value.
* @param {string} id - The ID value. * @param {string} id - The ID value.
* @param {PidEnquiryDto} pidEnquiryDto - The PID enquiry data. * @param {PidRequestDto} pidRequestDto - The PID request data.
* @returns {Promise<boolean | null>} A promise that resolves to a boolean indicating whether the contact operation was successful, or null if there was an error. * @returns {Promise<boolean | null>} A promise that resolves to a boolean indicating whether the contact operation was successful, or null if there was an error.
*/ */
async contactPidOwner( async contactPidOwner(
prefix: string, prefix: string,
id: string, id: string,
pidEnquiryDto: PidEnquiryDto pidRequestDto: PidRequestDto
): Promise<boolean | null> { ): Promise<boolean | null> {
const notificationStore = useNotificationStore(); const notificationStore = useNotificationStore();
try { try {
const apiResponse = await PidApi.sendEmailToOwner( const apiResponse = await PidApi.sendRequestToOwner(
prefix, prefix,
id, id,
pidEnquiryDto pidRequestDto
); );
// Note: Beware that only 204 (No Content) is considered a success in this implementation. // Note: Beware that only 204 (No Content) is considered a success in this implementation.
return apiResponse.status === StatusCodes.NO_CONTENT ? true : false; return apiResponse.status === StatusCodes.NO_CONTENT ? true : false;
......
...@@ -45,8 +45,8 @@ export default { ...@@ -45,8 +45,8 @@ export default {
"Sie können eine Einladung an diese E-Mail Adresse senden", "Sie können eine Einladung an diese E-Mail Adresse senden",
alreadyGotRole: "(bereits Mitglied)", alreadyGotRole: "(bereits Mitglied)",
selectRolePlaceholder: "Rolle auswählen", selectRolePlaceholder: "Rolle auswählen",
firstName: "Vorname", givenName: "Vorname",
lastName: "Nachname", familyName: "Nachname",
email: "E-Mail", email: "E-Mail",
actions: "Aktionen", actions: "Aktionen",
status: "Status", status: "Status",
......
...@@ -42,8 +42,8 @@ export default { ...@@ -42,8 +42,8 @@ export default {
searchEmailInvite: "You may send an invitation to this email address", searchEmailInvite: "You may send an invitation to this email address",
alreadyGotRole: "(Already added)", alreadyGotRole: "(Already added)",
selectRolePlaceholder: "Select Role", selectRolePlaceholder: "Select Role",
firstName: "First Name", givenName: "Given Name",
lastName: "Last Name", familyName: "Family Name",
email: "Email", email: "Email",
actions: "Actions", actions: "Actions",
status: "Status", status: "Status",
......
...@@ -21,7 +21,7 @@ import type Vue from "vue"; ...@@ -21,7 +21,7 @@ import type Vue from "vue";
/* Import of relevant mockup data */ /* Import of relevant mockup data */
import { testProjectState } from "@/data/mockup/testProject"; import { testProjectState } from "@/data/mockup/testProject";
import { getTestUserState } from "@/data/mockup/testUser"; import { getTestShibbolethUserState } from "@/data/mockup/testUser";
/* Create a local Vue instance */ /* Create a local Vue instance */
const localVue = createLocalVue(); const localVue = createLocalVue();
...@@ -31,7 +31,7 @@ describe("ConfigurationMetadata.vue", () => { ...@@ -31,7 +31,7 @@ describe("ConfigurationMetadata.vue", () => {
/* Describe Pre-initialization steps */ /* Describe Pre-initialization steps */
/* Description of the test */ /* Description of the test */
test("should enable buttons and update project name", async () => { test("Should enable buttons and update project name", async () => {
/* Test Pre-initialization steps */ /* Test Pre-initialization steps */
/* Mount the Component */ /* Mount the Component */
...@@ -40,7 +40,7 @@ describe("ConfigurationMetadata.vue", () => { ...@@ -40,7 +40,7 @@ describe("ConfigurationMetadata.vue", () => {
createSpy: vitest.fn, createSpy: vitest.fn,
initialState: { initialState: {
project: testProjectState, project: testProjectState,
user: getTestUserState(), user: getTestShibbolethUserState(),
}, },
}), }),
i18n, i18n,
...@@ -48,31 +48,29 @@ describe("ConfigurationMetadata.vue", () => { ...@@ -48,31 +48,29 @@ describe("ConfigurationMetadata.vue", () => {
}); });
// Check initial state of buttons // Check initial state of buttons
expect(wrapper.get("#DeleteProjectBtn").attributes()["disabled"]).not.toBe( expect(
"disabled" (wrapper.get("#DeleteProjectBtn").element as HTMLButtonElement).disabled
); // Delete button - active ).toBeFalsy(); // Delete button - active
expect(wrapper.get("#SubmitProjectBtn").attributes()["disabled"]).toBe( expect(
"disabled" (wrapper.get("#SubmitProjectBtn").element as HTMLButtonElement).disabled
); // Submit button - disabled ).toBeTruthy(); // Submit button - disabled
await wrapper.vm.$nextTick(); await wrapper.vm.$nextTick();
// Find element (Project Name) // Find element (Project Name)
const element = wrapper.get("#ProjectName"); const element = wrapper.get("#ProjectName");
expect(element.exists()).toBe(true); expect(element.exists()).toBeTruthy();
// Change value of element // Change value of element
await element.setValue("New Test Project"); await element.setValue("New Test Project");
expect(wrapper.vm.$data.projectForUpdate.projectName).toBe( expect(wrapper.vm.$data.projectForUpdate.name).toBe("New Test Project");
"New Test Project"
);
// Buttons should be enabled // Buttons should be enabled
expect(wrapper.get("#DeleteProjectBtn").attributes()["disabled"]).not.toBe( expect(
"disabled" (wrapper.get("#DeleteProjectBtn").element as HTMLButtonElement).disabled
); // Delete button - active ).toBeFalsy(); // Delete button - active
expect(wrapper.get("#SubmitProjectBtn").attributes()["disabled"]).not.toBe( expect(
"disabled" (wrapper.get("#SubmitProjectBtn").element as HTMLButtonElement).disabled
); // Submit button - active ).toBeFalsy(); // Submit button - active
}); });
}); });
...@@ -121,7 +121,7 @@ export default defineComponent({ ...@@ -121,7 +121,7 @@ export default defineComponent({
startDate: "", startDate: "",
endDate: "", endDate: "",
keywords: [] as string[], keywords: [] as string[],
projectName: "", name: "",
principleInvestigators: "", principleInvestigators: "",
grantId: "", grantId: "",
slug: "", slug: "",
......
...@@ -103,7 +103,7 @@ export default defineComponent({ ...@@ -103,7 +103,7 @@ export default defineComponent({
startDate: moment(new Date()).format("YYYY-MM-DD"), startDate: moment(new Date()).format("YYYY-MM-DD"),
endDate: moment(new Date()).format("YYYY-MM-DD"), endDate: moment(new Date()).format("YYYY-MM-DD"),
keywords: [] as string[], keywords: [] as string[],
projectName: "", name: "",
principleInvestigators: "", principleInvestigators: "",
grantId: "", grantId: "",
disciplines: [], disciplines: [],
...@@ -126,7 +126,7 @@ export default defineComponent({ ...@@ -126,7 +126,7 @@ export default defineComponent({
const memberships = this.userStore.user?.organizations; const memberships = this.userStore.user?.organizations;
if (memberships) { if (memberships) {
return memberships.some( return memberships.some(
(membership) => membership.rorUri === "https://ror.org/04xfq0f34" (membership) => membership.uri === "https://ror.org/04xfq0f34"
); );
} }
return false; return false;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment