Skip to content

Removed code related to DOB and privateProfile.ttl #526

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Nov 17, 2023
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
45 changes: 2 additions & 43 deletions src/components/Profile/ProfileComponent.jsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,9 @@
// React Imports
import React, { useContext, useEffect, useState } from 'react';
// Other Library Imports
import dayjs from 'dayjs';
// Custom Hook Imports
import { useSession } from '@hooks';
// Material UI Imports
import Box from '@mui/material/Box';
import FormControl from '@mui/material/FormControl';
import Typography from '@mui/material/Typography';
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
import { DatePicker } from '@mui/x-date-pickers/DatePicker';
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
import useMediaQuery from '@mui/material/useMediaQuery';
import { useTheme } from '@mui/material/styles';
// Context Imports
Expand Down Expand Up @@ -40,18 +33,14 @@ const ProfileComponent = ({ contactProfile }) => {
const [profileName, setProfileName] = useState(profileData?.profileInfo?.profileName);
const [nickname, setNickname] = useState(profileData?.profileInfo?.nickname);

// Private Profile Data
const [dateOfBirth, setDateOfBirth] = useState(profileData?.privateProfileData?.dateOfBirth);

const [edit, setEdit] = useState(false);

const loadProfileData = async () => {
const profileDataSolid = await fetchProfileInfo(session, session.info.webId);
const profileDataSolid = await fetchProfileInfo(session.info.webId);
setProfileData(profileDataSolid);

setProfileName(profileDataSolid.profileInfo?.profileName);
setNickname(profileDataSolid.profileInfo?.nickname);
setDateOfBirth(profileDataSolid.privateProfileInfo?.dateOfBirth);
};

const handleCancelEdit = () => {
Expand All @@ -71,11 +60,7 @@ const ProfileComponent = ({ contactProfile }) => {
nickname
};

const inputValuesPrivate = {
dateOfBirth
};

await updateProfileInfo(session, profileData, inputValues, inputValuesPrivate);
await updateProfileInfo(session, profileData, inputValues);

loadProfileData();
setEdit(false);
Expand All @@ -85,15 +70,6 @@ const ProfileComponent = ({ contactProfile }) => {
loadProfileData();
}, []);

const renderDateOfBirth = () => {
if (contactProfile) {
return contactProfile.dateOfBirth
? dayjs(contactProfile.dateOfBirth).format('MM/DD/YYYY')
: 'No value set';
}
return dateOfBirth ? dayjs(dateOfBirth).format('MM/DD/YYYY') : 'No value set';
};

const theme = useTheme();
const isSmallScreen = useMediaQuery(theme.breakpoints.down('sm'));

Expand Down Expand Up @@ -140,23 +116,6 @@ const ProfileComponent = ({ contactProfile }) => {
setInputValue={setNickname}
edit={edit}
/>
<Box sx={{ display: 'flex', gap: '10px' }}>
<Typography>Date of Birth: </Typography>
{edit ? (
<FormControl>
<LocalizationProvider dateAdapter={AdapterDayjs}>
<DatePicker
format="MM/DD/YYYY"
value={dayjs(dateOfBirth)}
onChange={(newDateOfBirth) => setDateOfBirth(newDateOfBirth)}
disableFuture
/>
</LocalizationProvider>
</FormControl>
) : (
renderDateOfBirth()
)}
</Box>
</Box>
{!contactProfile && (
<ProfileEditButtonGroup
Expand Down
2 changes: 1 addition & 1 deletion src/components/Profile/ProfileImageField.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ const ProfileImageField = ({ loadProfileData, contactProfile }) => {
} else {
await uploadProfileImage(session, profileData, event.target.files[0]);

const updatedProfileData = await fetchProfileInfo(session, session.info.webId);
const updatedProfileData = await fetchProfileInfo(session.info.webId);
localStorage.setItem('profileImage', updatedProfileData.profileInfo.profileImage);
setProfileImg(updatedProfileData.profileInfo.profileImage);

Expand Down
8 changes: 3 additions & 5 deletions src/contexts/SignedInUserContext.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ import {
fetchProfileInfo,
updateProfileInfo,
uploadProfileImage,
removeProfileImage,
generatePrivateProfileTTL
removeProfileImage
} from '../model-helpers';

/**
Expand Down Expand Up @@ -58,15 +57,14 @@ export const SignedInUserContextProvider = ({ children }) => {
let fetchedPodUrl = (await getPodUrlAll(webId, { fetch: session.fetch }))[0];
fetchedPodUrl = fetchedPodUrl || webId.split('profile')[0];
setPodUrl(fetchedPodUrl);
const fetchedProfileData = await fetchProfileInfo(session, webId);
const fetchedProfileData = await fetchProfileInfo(webId);
if (fetchedProfileData.profileInfo.profileImage) {
localStorage.setItem('profileImage', fetchedProfileData.profileInfo.profileImage);
}
setProfileData(fetchedProfileData);
await Promise.all([
createPASSContainer(session, fetchedPodUrl, 'Documents'),
createPASSContainer(session, fetchedPodUrl, 'Profile'),
generatePrivateProfileTTL(session, fetchedPodUrl)
createPASSContainer(session, fetchedPodUrl, 'Profile')
]);
} finally {
setLoadingUserInfo(false);
Expand Down
101 changes: 5 additions & 96 deletions src/model-helpers/Profile.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,14 @@
import {
buildThing,
createAcl,
createSolidDataset,
createThing,
deleteFile,
getDate,
getFile,
getSolidDataset,
getSourceUrl,
getStringNoLocale,
getThing,
getUrl,
getWebIdDataset,
removeStringNoLocale,
removeDate,
removeUrl,
saveAclFor,
saveFileInContainer,
Expand All @@ -32,50 +27,24 @@ import { saveSourceUrlToThing, setupAcl } from '../utils';
* card
*
* @function fetchProfileInfo
* @param {Session} session - Solid's Session Object {@link Session}
* @param {URL} webId - WebId of user
* @returns {Promise<object>} Object - The object containing the information related
* to the person on their profile card, the profile dataset, and the profile Thing
*/
export const fetchProfileInfo = async (session, webId) => {
export const fetchProfileInfo = async (webId) => {
const profileDataset = await getWebIdDataset(webId);
const profileThing = getThing(profileDataset, webId);

const profileName = getStringNoLocale(profileThing, RDF_PREDICATES.profileName);
const nickname = getStringNoLocale(profileThing, RDF_PREDICATES.nickname);
const profileImage = getUrl(profileThing, RDF_PREDICATES.profileImg);

let privateProfileDataset;
let privateProfileThing;
let dateOfBirth;

try {
privateProfileDataset = await getSolidDataset(
`${webId.split('profile')[0]}PASS/Profile/privateProfile.ttl`,
{ fetch: session.fetch }
);

privateProfileThing = getThing(
privateProfileDataset,
`${webId.split('profile')[0]}PASS/Profile/privateProfile.ttl#privateProfile`
);

dateOfBirth = getDate(privateProfileThing, RDF_PREDICATES.dateOfBirth);
} catch {
privateProfileThing = null;
dateOfBirth = null;
}

const profileInfo = { profileName, nickname, profileImage };
const privateProfileInfo = { dateOfBirth };

return {
profileDataset,
profileThing,
profileInfo,
privateProfileDataset,
privateProfileThing,
privateProfileInfo
profileInfo
};
};

Expand All @@ -89,14 +58,12 @@ export const fetchProfileInfo = async (session, webId) => {
* to the person on their profile card, the profile dataset, and the profile Thing
* @param {object} inputValues - The inputs for updating profile information
* on their profile card
* @param {object} inputValuesPrivate - The inputs for updating private profile
* information on their private profile information
* @returns {Promise} Promise - Performs action to update profile card on the
* user's profile card
*/
export const updateProfileInfo = async (session, profileData, inputValues, inputValuesPrivate) => {
let { profileDataset, profileThing, privateProfileDataset, privateProfileThing } = profileData;
const { profileInfo, privateProfileInfo } = profileData;
export const updateProfileInfo = async (session, profileData, inputValues) => {
let { profileDataset, profileThing } = profileData;
const { profileInfo } = profileData;

Object.keys(inputValues).forEach((input) => {
switch (inputValues[input]) {
Expand All @@ -117,37 +84,8 @@ export const updateProfileInfo = async (session, profileData, inputValues, input
}
});

Object.keys(inputValuesPrivate).forEach((input) => {
if (input === 'dateOfBirth') {
switch (inputValuesPrivate[input]) {
case null:
privateProfileThing = removeDate(
privateProfileThing,
RDF_PREDICATES[input],
privateProfileInfo[input]
);
break;
default:
if (inputValuesPrivate[input].$d === undefined) {
return;
}
privateProfileThing = buildThing(privateProfileThing)
.setDate(RDF_PREDICATES[input], inputValuesPrivate[input].$d)
.build();
break;
}
}
});

profileDataset = setThing(profileDataset, profileThing);
await saveSolidDatasetAt(session.info.webId, profileDataset, { fetch: session.fetch });

privateProfileDataset = setThing(privateProfileDataset, privateProfileThing);
await saveSolidDatasetAt(
`${session.info.webId.split('profile')[0]}PASS/Profile/privateProfile.ttl`,
privateProfileDataset,
{ fetch: session.fetch }
);
};

/**
Expand Down Expand Up @@ -219,32 +157,3 @@ export const removeProfileImage = async (session, profileData) => {
await deleteFile(profileImg, { fetch: session.fetch });
}
};

/**
* Function that generates the initial private profile TTL file for user if it
* does not already exist within the user's Pod
*
* @function generatePrivateProfileTTL
* @param {Session} session - Solid's Session Object {@link Session}
* @param {URL} podUrl - Pod URL of user
* @returns {Promise} Promise - Performs action that generates a new privateProfile.ttl
* if it does not exist
*/
export const generatePrivateProfileTTL = async (session, podUrl) => {
const privateProfileUrl = `${podUrl}PASS/Profile/privateProfile.ttl`;

try {
await getSolidDataset(privateProfileUrl, { fetch: session.fetch });
} catch {
const privateProfileThing = buildThing(createThing({ name: 'privateProfile' }))
.addUrl(RDF_PREDICATES.url, `${podUrl}PASS/Profile/privateProfile.ttl`)
.build();

let newPrivateProvileDataset = createSolidDataset();
newPrivateProvileDataset = setThing(newPrivateProvileDataset, privateProfileThing);

await saveSolidDatasetAt(`${podUrl}PASS/Profile/privateProfile.ttl`, newPrivateProvileDataset, {
fetch: session.fetch
});
}
};
2 changes: 1 addition & 1 deletion src/pages/Profile.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ const Profile = () => {

useEffect(() => {
const fetchContactProfile = async () => {
const profileData = await fetchProfileInfo(session, webIdUrl);
const profileData = await fetchProfileInfo(webIdUrl);
setContactProfile({
...contact,
...profileData.profileInfo,
Expand Down
34 changes: 8 additions & 26 deletions test/model-helpers/Profile.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,16 +44,13 @@ describe('fetchProfileInfo', () => {
});
vi.spyOn(solidClient, 'getSolidDataset').mockResolvedValue();

const results = await fetchProfileInfo(session, session.info.webId);
const results = await fetchProfileInfo(session.info.webId);

expect(results).toHaveProperty('profileInfo.profileName');
expect(results).toHaveProperty('profileInfo.nickname');
expect(results).toHaveProperty('profileInfo.profileImage');
expect(results).toHaveProperty('profileDataset');
expect(results).toHaveProperty('profileThing');
expect(results).toHaveProperty('privateProfileInfo.dateOfBirth');
expect(results).toHaveProperty('privateProfileDataset');
expect(results).toHaveProperty('privateProfileThing');
});
});

Expand All @@ -77,20 +74,16 @@ describe('updateProfileInfo', () => {
const mockData = {
profileDataset: mockDataset,
profileThing: mockDatasetThing,
profileInfo: { profileName: 'Alice', nickname: null, profileImage: null },
privateProfileDateset: mockDataset,
privateProfileThing: mockDatasetThing,
privateProfileInfo: { dateOfBirth: null }
profileInfo: { profileName: 'Alice', nickname: null, profileImage: null }
};
const mockInputValues = { profileName: 'Alice', nickname: null };
const mockInputValuesPrivate = { dateOfBirth: null };

vi.spyOn(solidClient, 'removeStringNoLocale');
vi.spyOn(solidClient, 'buildThing');
vi.spyOn(solidClient, 'setThing').mockReturnValue();
vi.spyOn(solidClient, 'saveSolidDatasetAt');

await updateProfileInfo(session, mockData, mockInputValues, mockInputValuesPrivate);
await updateProfileInfo(session, mockData, mockInputValues);

expect(solidClient.removeStringNoLocale).not.toBeCalled();
expect(solidClient.buildThing).toBeCalledTimes(1);
Expand All @@ -102,19 +95,15 @@ describe('updateProfileInfo', () => {
const mockData = {
profileDataset: mockDataset,
profileThing: mockDatasetThing,
profileInfo: { profileName: 'Alice', nickname: null, profileImage: null },
privateProfileDateset: mockDataset,
privateProfileThing: mockDatasetThing,
privateProfileInfo: { dateOfBirth: null }
profileInfo: { profileName: 'Alice', nickname: null, profileImage: null }
};
const mockInputValues = { profileName: 'Alice', nickname: 'Al' };
const mockInputValuesPrivate = { dateOfBirth: null };

vi.spyOn(solidClient, 'removeStringNoLocale');
vi.spyOn(solidClient, 'buildThing');
vi.spyOn(solidClient, 'saveSolidDatasetAt');

await updateProfileInfo(session, mockData, mockInputValues, mockInputValuesPrivate);
await updateProfileInfo(session, mockData, mockInputValues);

expect(solidClient.removeStringNoLocale).not.toBeCalled();
expect(solidClient.buildThing).toBeCalledTimes(2);
Expand All @@ -126,19 +115,15 @@ describe('updateProfileInfo', () => {
const mockData = {
profileDataset: mockDataset,
profileThing: mockDatasetThing,
profileInfo: { profileName: 'Alice', nickname: null, profileImage: null },
privateProfileDateset: mockDataset,
privateProfileThing: mockDatasetThing,
privateProfileInfo: { dateOfBirth: null }
profileInfo: { profileName: 'Alice', nickname: null, profileImage: null }
};
const mockInputValues = { profileName: '', nickname: 'Al' };
const mockInputValuesPrivate = { dateOfBirth: null };

vi.spyOn(solidClient, 'removeStringNoLocale');
vi.spyOn(solidClient, 'buildThing');
vi.spyOn(solidClient, 'saveSolidDatasetAt');

await updateProfileInfo(session, mockData, mockInputValues, mockInputValuesPrivate);
await updateProfileInfo(session, mockData, mockInputValues);

expect(solidClient.removeStringNoLocale).toBeCalledTimes(1);
expect(solidClient.buildThing).toBeCalledTimes(1);
Expand Down Expand Up @@ -166,10 +151,7 @@ describe('uploadProfileImage', () => {
const mockData = {
profileDataset: mockDataset,
profileThing: mockDatasetThing,
profileInfo: { profileName: 'Alice', nickname: null, profileImage: null },
privateProfileDateset: mockDataset,
privateProfileThing: mockDatasetThing,
privateProfileInfo: { dateOfBirth: null }
profileInfo: { profileName: 'Alice', nickname: null, profileImage: null }
};
const mockImageData = new Blob(new Array(9).fill(0), { type: 'image/png' });
const mockInputImage = new File([mockImageData], 'image.png', { type: 'image/png' });
Expand Down