Skip to content
This repository was archived by the owner on Nov 5, 2023. It is now read-only.

Commit ac53106

Browse files
release: v0.12.0 (#39)
* build: Update nginx config (#31) * feat: Share file (#32) * feat: List shared files (#33) * refactor: Create files contexts wrapper Centralize contexts providers in one file to avoid calling all the providers from the main file. * feat: Get files shared with the user * fix(ui): Align go back button to the left * test: Add test to ensure users can view shared folders and files * fix: Allow to upload content into shared folders (#36) * refactor: Rename files reducer and hook * refactor: Rename files context * refactor: Replace useSharedFiles with an unique useFiles hook * refactor: Move dialogs to files layout * refactor: Update files state name and dispatcher name * refactor: Use files context in the shared files view * test: Update tests to list shared files * feat: Logout (#38) * feat: Logout * test: Add test to ensure users can logout --------- Co-authored-by: Miguel Mateo Mendoza Rojas <115849391+MiguelMRojas@users.noreply.github.com>
1 parent ec07661 commit ac53106

32 files changed

+616
-219
lines changed

CHANGELOG.md

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,45 @@
1-
# [0.9.0](https://github.com/PedroChaparro/alternative-frontend-react/compare/v0.8.0...v0.9.0) (2023-10-21)
1+
# [0.12.0](https://github.com/PedroChaparro/alternative-frontend-react/compare/v0.11.1...v0.12.0) (2023-10-24)
22

33

44
### Features
55

6-
* Download file ([#28](https://github.com/PedroChaparro/alternative-frontend-react/issues/28)) ([b55be6c](https://github.com/PedroChaparro/alternative-frontend-react/commit/b55be6cec070a0e50d94c5062eab408d9d9c0e31))
6+
* Logout ([#38](https://github.com/PedroChaparro/alternative-frontend-react/issues/38)) ([da28481](https://github.com/PedroChaparro/alternative-frontend-react/commit/da2848173338776dd0fc64f12b18aa53f73f80b5))
77

88

99

10-
# [0.8.0](https://github.com/PedroChaparro/alternative-frontend-react/compare/v0.7.0...v0.8.0) (2023-10-21)
10+
## [0.11.1](https://github.com/PedroChaparro/alternative-frontend-react/compare/v0.11.0...v0.11.1) (2023-10-24)
1111

1212

13-
### Features
13+
### Bug Fixes
1414

15-
* Access management dialog ([#27](https://github.com/PedroChaparro/alternative-frontend-react/issues/27)) ([24e4048](https://github.com/PedroChaparro/alternative-frontend-react/commit/24e40482f1c44e21ab25a52a758b1acf8cf7ef37))
15+
* Allow to upload content into shared folders ([#36](https://github.com/PedroChaparro/alternative-frontend-react/issues/36)) ([9edeb38](https://github.com/PedroChaparro/alternative-frontend-react/commit/9edeb380d5d23a89f856eeb34f63df4e8ba8e023))
1616

1717

1818

19-
# [0.7.0](https://github.com/PedroChaparro/alternative-frontend-react/compare/v0.6.1...v0.7.0) (2023-10-20)
19+
# [0.11.0](https://github.com/PedroChaparro/alternative-frontend-react/compare/v0.10.0...v0.11.0) (2023-10-24)
2020

2121

2222
### Features
2323

24-
* Create folder ([#24](https://github.com/PedroChaparro/alternative-frontend-react/issues/24)) ([54dc7c1](https://github.com/PedroChaparro/alternative-frontend-react/commit/54dc7c15c36fa3b19bad68caed62a6c45e8ccb54))
24+
* List shared files ([#33](https://github.com/PedroChaparro/alternative-frontend-react/issues/33)) ([b19c51f](https://github.com/PedroChaparro/alternative-frontend-react/commit/b19c51f733526ecefe01806ea6112aadeb275532))
2525

2626

2727

28-
## [0.6.1](https://github.com/PedroChaparro/alternative-frontend-react/compare/v0.6.0...v0.6.1) (2023-10-20)
28+
# [0.10.0](https://github.com/PedroChaparro/alternative-frontend-react/compare/v0.9.0...v0.10.0) (2023-10-23)
2929

3030

31-
### Bug Fixes
31+
### Features
3232

33-
* Go back button in folders navigation ([#23](https://github.com/PedroChaparro/alternative-frontend-react/issues/23)) ([07edb44](https://github.com/PedroChaparro/alternative-frontend-react/commit/07edb442b2524bd739bf7f0d6ea13f536b1a62b9))
33+
* Share file ([#32](https://github.com/PedroChaparro/alternative-frontend-react/issues/32)) ([e91567a](https://github.com/PedroChaparro/alternative-frontend-react/commit/e91567a7a741e1bc9894753ad40e518d559bef20))
3434

3535

3636

37-
# [0.6.0](https://github.com/PedroChaparro/alternative-frontend-react/compare/v0.5.0...v0.6.0) (2023-10-20)
37+
# [0.9.0](https://github.com/PedroChaparro/alternative-frontend-react/compare/v0.8.0...v0.9.0) (2023-10-21)
3838

3939

4040
### Features
4141

42-
* Move files ([#21](https://github.com/PedroChaparro/alternative-frontend-react/issues/21)) ([3a470e9](https://github.com/PedroChaparro/alternative-frontend-react/commit/3a470e97df16f038658bb2e13019c2adda4a5e0a))
42+
* Download file ([#28](https://github.com/PedroChaparro/alternative-frontend-react/issues/28)) ([b55be6c](https://github.com/PedroChaparro/alternative-frontend-react/commit/b55be6cec070a0e50d94c5062eab408d9d9c0e31))
4343

4444

4545

e2e/auth/login.spec.tsx

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,17 @@ test.describe.serial("Users can login", () => {
3232
await page.getByRole("button", { name: "Submit", exact: true }).click();
3333
await expect(page.getByText("Invalid credentials")).toBeVisible();
3434
});
35+
36+
test("Logout", async ({ page }) => {
37+
// Login
38+
await page.goto("/login");
39+
await page.getByLabel("Username").fill(username);
40+
await page.getByLabel("Password", { exact: true }).fill(password);
41+
await page.getByRole("button", { name: "Submit", exact: true }).click();
42+
await page.waitForURL(/\/files$/);
43+
44+
// Click logout
45+
await page.getByRole("link", { name: "Logout", exact: true }).click();
46+
await page.waitForURL(/\/login$/);
47+
});
3548
});

e2e/files/share-files.spec.tsx

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
import { faker } from "@faker-js/faker";
2+
import { expect, test } from "@playwright/test";
3+
import path from "path";
4+
import { fileURLToPath } from "url";
5+
6+
const __filename = fileURLToPath(import.meta.url);
7+
const __dirname = path.dirname(__filename);
8+
9+
test.describe.serial("Users can share files", () => {
10+
const username = faker.internet.userName();
11+
const password = faker.internet.password({ length: 8 });
12+
const usernameShare = faker.internet.userName();
13+
const passwordShare = faker.internet.password({ length: 8 });
14+
15+
const sharedFolder = faker.system.commonFileName();
16+
17+
test("Register file owner", async ({ page }) => {
18+
await page.goto("/register");
19+
20+
await page.getByLabel("Username").fill(username);
21+
await page.getByLabel("Password", { exact: true }).fill(password);
22+
await page.getByLabel("Confirm Password", { exact: true }).fill(password);
23+
await page.getByRole("button", { name: "Submit", exact: true }).click();
24+
25+
await expect(page.getByText("Account created successfully")).toBeVisible();
26+
await page.waitForURL(/\/files$/);
27+
});
28+
29+
test("Register another user", async ({ page }) => {
30+
await page.goto("/register");
31+
32+
await page.getByLabel("Username").fill(usernameShare);
33+
await page.getByLabel("Password", { exact: true }).fill(passwordShare);
34+
await page
35+
.getByLabel("Confirm Password", { exact: true })
36+
.fill(passwordShare);
37+
await page.getByRole("button", { name: "Submit", exact: true }).click();
38+
39+
await expect(page.getByText("Account created successfully")).toBeVisible();
40+
await page.waitForURL(/\/files$/);
41+
});
42+
43+
test("Upload a file to share", async ({ page }) => {
44+
// Login with the registered user
45+
await page.goto("/login");
46+
await page.getByLabel("Username").fill(username);
47+
await page.getByLabel("Password", { exact: true }).fill(password);
48+
await page.getByRole("button", { name: "Submit", exact: true }).click();
49+
await page.waitForURL(/\/files$/);
50+
51+
// Create a folder
52+
await page.getByRole("button", { name: "Create folder" }).click();
53+
await expect(page.getByRole("dialog")).toBeVisible();
54+
await page.getByLabel("Name").fill(sharedFolder);
55+
await page.getByRole("button", { name: "Create", exact: true }).click();
56+
57+
// Move to the folder
58+
const folderCard = page.getByRole("button", {
59+
name: `${sharedFolder} card`
60+
});
61+
await expect(folderCard).toBeVisible();
62+
await folderCard.click();
63+
64+
// Open the upload modal
65+
await page.getByRole("button", { name: "Upload file" }).click();
66+
await expect(page.getByRole("dialog")).toBeVisible();
67+
68+
// Upload a file
69+
const filesInput = page.getByLabel("Choose files to upload", {
70+
exact: true
71+
});
72+
await filesInput.setInputFiles(path.join(__dirname, "data/in/yellow.jpg"));
73+
await page.getByRole("button", { name: "Upload", exact: true }).click();
74+
75+
// Assert file is shown
76+
await expect(page.getByText("yellow.jpg")).toBeVisible();
77+
});
78+
79+
test("Share the folder with the other user", async ({ page }) => {
80+
// Login with the registered user
81+
await page.goto("/login");
82+
await page.getByLabel("Username").fill(username);
83+
await page.getByLabel("Password", { exact: true }).fill(password);
84+
await page.getByRole("button", { name: "Submit", exact: true }).click();
85+
await page.waitForURL(/\/files$/);
86+
87+
// Open the folder dropdown
88+
const folderCard = page.getByRole("button", {
89+
name: `${sharedFolder} card`
90+
});
91+
await expect(folderCard).toBeVisible();
92+
await folderCard.getByLabel(`More options for ${sharedFolder}`).click();
93+
94+
// Select the "Manage access" option
95+
const shareButton = page.getByRole("menuitem", {
96+
name: "Manage access",
97+
exact: true
98+
});
99+
await expect(shareButton).toBeVisible();
100+
await shareButton.click();
101+
102+
// Assert modal is open
103+
await expect(page.getByRole("dialog")).toBeVisible();
104+
await expect(page.getByText("Manage access")).toBeVisible();
105+
106+
// Share file
107+
await page.getByLabel("Share with", { exact: true }).fill(usernameShare);
108+
await page.getByRole("button", { name: "Share", exact: true }).click();
109+
110+
// Assert an alert is shown
111+
await expect(
112+
page.getByText("The file has been shared successfully")
113+
).toBeVisible();
114+
115+
// Assert the form is reset
116+
await expect(page.getByLabel("Share with", { exact: true })).toHaveValue(
117+
""
118+
);
119+
120+
// Assert the username appears in the list
121+
const userRow = page.getByText(new RegExp(usernameShare, "i"));
122+
await expect(userRow).toBeVisible();
123+
});
124+
125+
test("The other user can see the shared file", async ({ page }) => {
126+
// Login with the other user
127+
await page.goto("/login");
128+
await page.getByLabel("Username").fill(usernameShare);
129+
await page.getByLabel("Password", { exact: true }).fill(passwordShare);
130+
await page.getByRole("button", { name: "Submit", exact: true }).click();
131+
await expect(page.getByText("No files found here... 🤷")).toBeVisible();
132+
133+
// Move to the shared files view
134+
await page.getByRole("button", { name: "Shared with me" }).click();
135+
await page.waitForURL(/\/shared-with-me$/);
136+
137+
// Assert the shared folder is shown
138+
const folderCard = page.getByRole("button", {
139+
name: `${sharedFolder} card`
140+
});
141+
await expect(folderCard).toBeVisible();
142+
143+
// Open the folder
144+
await folderCard.click();
145+
146+
// Assert the shared file is shown
147+
await expect(page.getByText("yellow.jpg")).toBeVisible();
148+
});
149+
});

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "unofficial-frontend-react",
33
"private": true,
4-
"version": "0.9.0",
4+
"version": "0.12.0",
55
"type": "module",
66
"scripts": {
77
"dev": "vite",

src/components/file-card/Dropdown.tsx

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -75,18 +75,22 @@ export const DropDown = ({ file }: { file: File }) => {
7575
}
7676
};
7777

78+
const options = getMenuOptions();
79+
7880
return (
79-
<DropdownMenu>
80-
<DropdownMenuTrigger asChild>
81-
<Button
82-
variant={"ghost"}
83-
className="absolute right-2 top-2 p-2"
84-
aria-label={`More options for ${file.name}`}
85-
>
86-
<MoreVertical />
87-
</Button>
88-
</DropdownMenuTrigger>
89-
{getMenuOptions()}
90-
</DropdownMenu>
81+
options && (
82+
<DropdownMenu>
83+
<DropdownMenuTrigger asChild>
84+
<Button
85+
variant={"ghost"}
86+
className="absolute right-2 top-2 p-2"
87+
aria-label={`More options for ${file.name}`}
88+
>
89+
<MoreVertical />
90+
</Button>
91+
</DropdownMenuTrigger>
92+
{getMenuOptions()}
93+
</DropdownMenu>
94+
)
9195
);
9296
};

src/components/file-card/FileCard.tsx

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import { PARAMETERS } from "@/config/parameters";
22
import {
33
AuthContext,
4+
FilesContext,
45
FilesDialogsContext,
5-
FoldersNavigationContext,
6-
UserFilesContext
6+
FoldersNavigationContext
77
} from "@/context/index";
8-
import { UserFilesActionTypes } from "@/hooks/user-files/UserFilesReducer";
8+
import { FilesActionType } from "@/hooks/user-files/filesReducer";
99
import { downloadBlob } from "@/lib/utils";
1010
import { downloadFileService } from "@/services/files/download-file.service";
1111
import { getFileByUUIDService } from "@/services/files/get-file-by-uuid.service";
@@ -45,7 +45,7 @@ export const FileCard = ({ file }: { file: File }) => {
4545

4646
const { pushToHistory } = useContext(FoldersNavigationContext);
4747

48-
const { userFilesDispatcher } = useContext(UserFilesContext);
48+
const { filesDispatcher } = useContext(FilesContext);
4949
const { dialogsOpenState } = useContext(FilesDialogsContext);
5050

5151
const downloadFile = async () => {
@@ -89,8 +89,8 @@ export const FileCard = ({ file }: { file: File }) => {
8989
return false;
9090
}
9191

92-
userFilesDispatcher({
93-
type: UserFilesActionTypes.MARK_FILE_AS_READY,
92+
filesDispatcher({
93+
type: FilesActionType.MARK_FILE_AS_READY,
9494
payload: res.file
9595
});
9696

@@ -103,8 +103,8 @@ export const FileCard = ({ file }: { file: File }) => {
103103
toast.error("Max ready checks reached");
104104

105105
// Remove file from the UI
106-
userFilesDispatcher({
107-
type: UserFilesActionTypes.REMOVE_FILE,
106+
filesDispatcher({
107+
type: FilesActionType.REMOVE_FILE,
108108
payload: file
109109
});
110110

src/components/files-grid/FilesGrid.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ export const FilesGrid = ({
4242

4343
if (!areLoading && files.length === 0) {
4444
return (
45-
<div className="flex flex-col space-y-4">
45+
<div className="flex w-full flex-col space-y-4 text-center">
4646
{canGoBack && (
4747
<Button className="w-max" onClick={goBack}>
4848
<ArrowLeft className="mr-2" />
@@ -55,7 +55,7 @@ export const FilesGrid = ({
5555
}
5656

5757
return (
58-
<div className="space-y-4">
58+
<div className="w-full space-y-4">
5959
{canGoBack && (
6060
<Button className="w-max" onClick={goBack}>
6161
<ArrowLeft className="mr-2" />

src/context/UserFilesContext.tsx

Lines changed: 0 additions & 34 deletions
This file was deleted.

0 commit comments

Comments
 (0)