Skip to content

Commit

Permalink
Merge pull request #526 from codeforpdx/issue-525/remove-dob-from-pro…
Browse files Browse the repository at this point in the history
…file

Removed code related to DOB and privateProfile.ttl
  • Loading branch information
leekahung authored Nov 17, 2023
2 parents 9b3bac8 + 9596cae commit 65dbf16
Show file tree
Hide file tree
Showing 6 changed files with 20 additions and 172 deletions.
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

0 comments on commit 65dbf16

Please sign in to comment.