Skip to content

Commit 128438d

Browse files
YaleChen299angelsl
andcommitted
Namespace game assets (#792)
* update assets with course * formatting * update assets model test * Fix tests Co-authored-by: angelsl <angelsl@in04.sg>
1 parent 63fd150 commit 128438d

17 files changed

+157
-111
lines changed

config/test.exs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ config :cadet,
7575
lambda_name: "dummy"
7676
],
7777
uploader: [
78-
assets_bucket: "source-academy-assets",
78+
assets_bucket: "test-sa-assets",
7979
sourcecasts_bucket: "test-cadet-sourcecasts"
8080
],
8181
remote_execution: [

lib/cadet/assets/assets.ex

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,18 @@ defmodule Cadet.Assets.Assets do
99
if(Mix.env() == :test, do: ["testFolder"], else: [])
1010
@accepted_file_types ~w(.jpg .jpeg .gif .png .wav .mp3 .txt)
1111

12-
def upload_to_s3(upload_params, folder_name, file_name) do
12+
def upload_to_s3(upload_params, course_id, folder_name, file_name) do
1313
file_type = Path.extname(file_name)
1414

1515
with :ok <- validate_file_name(file_name),
1616
:ok <- validate_folder_name(folder_name),
1717
:ok <- validate_file_type(file_type) do
18-
if object_exists?(folder_name, file_name) do
18+
if object_exists?(course_id, folder_name, file_name) do
1919
{:error, {:bad_request, "File already exists"}}
2020
else
2121
file = upload_params.path
2222

23-
s3_path = "#{folder_name}/#{file_name}"
23+
s3_path = "#{course_id}/#{folder_name}/#{file_name}"
2424

2525
file
2626
|> Upload.stream_file()
@@ -32,11 +32,11 @@ defmodule Cadet.Assets.Assets do
3232
end
3333
end
3434

35-
def list_assets(folder_name) do
35+
def list_assets(course_id, folder_name) do
3636
case validate_folder_name(folder_name) do
3737
:ok ->
3838
bucket()
39-
|> S3.list_objects(prefix: folder_name <> "/")
39+
|> S3.list_objects(prefix: "#{course_id}/" <> folder_name <> "/")
4040
|> ExAws.stream!()
4141
|> Enum.map(fn file -> file.key end)
4242

@@ -45,12 +45,12 @@ defmodule Cadet.Assets.Assets do
4545
end
4646
end
4747

48-
def delete_object(folder_name, file_name) do
48+
def delete_object(course_id, folder_name, file_name) do
4949
with :ok <- validate_file_name(file_name),
5050
:ok <- validate_folder_name(folder_name) do
51-
if object_exists?(folder_name, file_name) do
51+
if object_exists?(course_id, folder_name, file_name) do
5252
bucket()
53-
|> S3.delete_object("#{folder_name}/#{file_name}")
53+
|> S3.delete_object("#{course_id}/#{folder_name}/#{file_name}")
5454
|> ExAws.request!()
5555

5656
:ok
@@ -60,9 +60,10 @@ defmodule Cadet.Assets.Assets do
6060
end
6161
end
6262

63-
@spec object_exists?(binary, binary) :: boolean()
64-
def object_exists?(folder_name, file_name) do
65-
response = bucket() |> S3.head_object("#{folder_name}/#{file_name}") |> ExAws.request()
63+
@spec object_exists?(integer(), binary, binary) :: boolean()
64+
def object_exists?(course_id, folder_name, file_name) do
65+
response =
66+
bucket() |> S3.head_object("#{course_id}/#{folder_name}/#{file_name}") |> ExAws.request()
6667

6768
case response do
6869
{:error, _error} -> false

lib/cadet_web/admin_controllers/admin_assets_controller.ex

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,20 @@ defmodule CadetWeb.AdminAssetsController do
55
alias Cadet.Assets.Assets
66

77
def index(conn, _params = %{"foldername" => foldername}) do
8-
case Assets.list_assets(foldername) do
8+
course_reg = conn.assigns.course_reg
9+
10+
case Assets.list_assets(course_reg.course_id, foldername) do
911
{:error, {status, message}} -> conn |> put_status(status) |> text(message)
1012
assets -> render(conn, "index.json", assets: assets)
1113
end
1214
end
1315

1416
@spec delete(Plug.Conn.t(), map) :: Plug.Conn.t()
1517
def delete(conn, _params = %{"foldername" => foldername, "filename" => filename}) do
18+
course_reg = conn.assigns.course_reg
1619
filename = Enum.join(filename, "/")
1720

18-
case Assets.delete_object(foldername, filename) do
21+
case Assets.delete_object(course_reg.course_id, foldername, filename) do
1922
{:error, {status, message}} -> conn |> put_status(status) |> text(message)
2023
_ -> conn |> put_status(204) |> text('')
2124
end
@@ -26,9 +29,10 @@ defmodule CadetWeb.AdminAssetsController do
2629
"filename" => filename,
2730
"foldername" => foldername
2831
}) do
32+
course_reg = conn.assigns.course_reg
2933
filename = Enum.join(filename, "/")
3034

31-
case Assets.upload_to_s3(upload_params, foldername, filename) do
35+
case Assets.upload_to_s3(upload_params, course_reg.course_id, foldername, filename) do
3236
{:error, {status, message}} -> conn |> put_status(status) |> text(message)
3337
resp -> render(conn, "show.json", resp: resp)
3438
end

test/cadet/assets/assets_test.exs

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,31 +7,38 @@ defmodule Cadet.Assets.AssetsTest do
77
describe "Manage assets" do
88
test "accessible folder" do
99
use_cassette "aws/model_list_assets#1" do
10-
assert Assets.list_assets("testFolder") === [
11-
"testFolder/",
12-
"testFolder/test.png",
13-
"testFolder/test2.png"
10+
assert Assets.list_assets(1, "testFolder") === [
11+
"1/testFolder/",
12+
"1/testFolder/test.png",
13+
"1/testFolder/test2.png"
1414
]
1515
end
1616
end
1717

18+
test "access another course with 0 folder" do
19+
use_cassette "aws/model_list_assets#2" do
20+
assert Assets.list_assets(2, "testFolder") === []
21+
end
22+
end
23+
1824
test "delete nonexistent file" do
1925
use_cassette "aws/model_delete_asset#1" do
20-
assert Assets.delete_object("testFolder", "test4.png") ===
26+
assert Assets.delete_object(1, "testFolder", "test4.png") ===
2127
{:error, {:not_found, "File not found"}}
2228
end
2329
end
2430

2531
test "delete ok file" do
2632
use_cassette "aws/model_delete_asset#2" do
27-
assert Assets.delete_object("testFolder", "test.png") === :ok
33+
assert Assets.delete_object(1, "testFolder", "test.png") === :ok
2834
end
2935
end
3036

3137
test "upload existing file" do
3238
use_cassette "aws/model_upload_asset#1" do
3339
assert Assets.upload_to_s3(
3440
build_upload("test/fixtures/upload.png"),
41+
1,
3542
"testFolder",
3643
"test2.png"
3744
) ===
@@ -43,15 +50,18 @@ defmodule Cadet.Assets.AssetsTest do
4350
use_cassette "aws/model_upload_asset#2" do
4451
assert Assets.upload_to_s3(
4552
build_upload("test/fixtures/upload.png"),
53+
1,
4654
"testFolder",
4755
"test1.png"
4856
) ===
49-
"https://source-academy-assets.s3.amazonaws.com/testFolder/test1.png"
57+
"https://#{bucket()}.s3.amazonaws.com/1/testFolder/test1.png"
5058
end
5159
end
5260
end
5361

5462
defp build_upload(path, content_type \\ "image\png") do
5563
%Plug.Upload{path: path, filename: Path.basename(path), content_type: content_type}
5664
end
65+
66+
defp bucket, do: :cadet |> Application.fetch_env!(:uploader) |> Keyword.get(:assets_bucket)
5767
end

test/cadet_web/admin_controllers/admin_assets_controller_test.exs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ defmodule CadetWeb.AdminAssetsControllerTest do
9494
end
9595

9696
describe "ok request" do
97-
@tag authenticate: :staff
97+
@tag authenticate: :staff, course_id: 117
9898
test "index file", %{conn: conn} do
9999
course_id = conn.assigns.course_id
100100

@@ -106,7 +106,7 @@ defmodule CadetWeb.AdminAssetsControllerTest do
106106
end
107107
end
108108

109-
@tag authenticate: :staff
109+
@tag authenticate: :staff, course_id: 117
110110
test "delete file", %{conn: conn} do
111111
course_id = conn.assigns.course_id
112112

@@ -117,7 +117,7 @@ defmodule CadetWeb.AdminAssetsControllerTest do
117117
end
118118
end
119119

120-
@tag authenticate: :staff
120+
@tag authenticate: :staff, course_id: 117
121121
test "upload file", %{conn: conn} do
122122
course_id = conn.assigns.course_id
123123

@@ -128,7 +128,7 @@ defmodule CadetWeb.AdminAssetsControllerTest do
128128
})
129129

130130
assert json_response(conn, 200) ===
131-
"https://source-academy-assets.s3.amazonaws.com/testFolder/test.png"
131+
"https://#{bucket()}.s3.amazonaws.com/#{course_id}/testFolder/test.png"
132132
end
133133
end
134134
end
@@ -169,7 +169,7 @@ defmodule CadetWeb.AdminAssetsControllerTest do
169169
end
170170

171171
describe "nested filename request" do
172-
@tag authenticate: :staff
172+
@tag authenticate: :staff, course_id: 117
173173
test "delete file", %{conn: conn} do
174174
course_id = conn.assigns.course_id
175175

@@ -180,7 +180,7 @@ defmodule CadetWeb.AdminAssetsControllerTest do
180180
end
181181
end
182182

183-
@tag authenticate: :staff
183+
@tag authenticate: :staff, course_id: 117
184184
test "upload file", %{conn: conn} do
185185
course_id = conn.assigns.course_id
186186

@@ -191,7 +191,7 @@ defmodule CadetWeb.AdminAssetsControllerTest do
191191
})
192192

193193
assert json_response(conn, 200) ===
194-
"https://source-academy-assets.s3.amazonaws.com/testFolder/nestedFolder/test.png"
194+
"https://#{bucket()}.s3.amazonaws.com/#{course_id}/testFolder/nestedFolder/test.png"
195195
end
196196
end
197197
end
@@ -202,4 +202,6 @@ defmodule CadetWeb.AdminAssetsControllerTest do
202202
defp build_upload(path, content_type \\ "image/png") do
203203
%Plug.Upload{path: path, filename: Path.basename(path), content_type: content_type}
204204
end
205+
206+
defp bucket, do: :cadet |> Application.fetch_env!(:uploader) |> Keyword.get(:assets_bucket)
205207
end

test/fixtures/vcr_cassettes/aws/controller_delete_asset#1.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
"recv_timeout": 660000
1616
},
1717
"request_body": "",
18-
"url": "https://s3.ap-southeast-1.amazonaws.com/source-academy-assets/testFolder/test2.png"
18+
"url": "https://s3.ap-southeast-1.amazonaws.com/test-sa-assets/117/testFolder/test2.png"
1919
},
2020
"response": {
2121
"binary": false,
@@ -49,7 +49,7 @@
4949
"recv_timeout": 660000
5050
},
5151
"request_body": "",
52-
"url": "https://s3.ap-southeast-1.amazonaws.com/source-academy-assets/testFolder/test2.png"
52+
"url": "https://s3.ap-southeast-1.amazonaws.com/test-sa-assets/117/testFolder/test2.png"
5353
},
5454
"response": {
5555
"binary": false,
@@ -62,4 +62,4 @@
6262
"type": "ok"
6363
}
6464
}
65-
]
65+
]

test/fixtures/vcr_cassettes/aws/controller_delete_asset#2.json

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"headers": {
66
"Authorization": "***",
77
"host": "s3.ap-southeast-1.amazonaws.com",
8-
"x-amz-date": "20200704T190420Z",
8+
"x-amz-date": "20200704T190423Z",
99
"content-length": "0",
1010
"x-amz-content-sha256": "***"
1111
},
@@ -15,14 +15,14 @@
1515
"recv_timeout": 660000
1616
},
1717
"request_body": "",
18-
"url": "https://s3.ap-southeast-1.amazonaws.com/source-academy-assets/testFolder/nestedFolder/test2.png"
18+
"url": "https://s3.ap-southeast-1.amazonaws.com/test-sa-assets/117/testFolder/nestedFolder/test2.png"
1919
},
2020
"response": {
2121
"binary": false,
2222
"body": null,
2323
"headers": {
24-
"Date": "Sat, 04 Jul 2020 19:04:21 GMT",
25-
"Last-Modified": "Sat, 04 Jul 2020 19:03:31 GMT",
24+
"Date": "Sat, 04 Jul 2020 19:04:24 GMT",
25+
"Last-Modified": "Sat, 04 Jul 2020 18:58:52 GMT",
2626
"ETag": "\"3104001edec38fadeb925b9dbddab198\"",
2727
"Accept-Ranges": "bytes",
2828
"Content-Type": "image/png",
@@ -39,7 +39,7 @@
3939
"headers": {
4040
"Authorization": "***",
4141
"host": "s3.ap-southeast-1.amazonaws.com",
42-
"x-amz-date": "20200704T190421Z",
42+
"x-amz-date": "20200704T190423Z",
4343
"content-length": "0",
4444
"x-amz-content-sha256": "***"
4545
},
@@ -49,17 +49,17 @@
4949
"recv_timeout": 660000
5050
},
5151
"request_body": "",
52-
"url": "https://s3.ap-southeast-1.amazonaws.com/source-academy-assets/testFolder/nestedFolder/test2.png"
52+
"url": "https://s3.ap-southeast-1.amazonaws.com/test-sa-assets/117/testFolder/nestedFolder/test2.png"
5353
},
5454
"response": {
5555
"binary": false,
5656
"body": "",
5757
"headers": {
58-
"Date": "Sat, 04 Jul 2020 19:04:22 GMT",
58+
"Date": "Sat, 04 Jul 2020 19:04:24 GMT",
5959
"Server": "AmazonS3"
6060
},
6161
"status_code": 204,
6262
"type": "ok"
6363
}
6464
}
65-
]
65+
]

test/fixtures/vcr_cassettes/aws/controller_list_assets#1.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@
1414
"recv_timeout": 660000
1515
},
1616
"request_body": "",
17-
"url": "https://s3.ap-southeast-1.amazonaws.com/source-academy-assets/"
17+
"url": "https://s3.ap-southeast-1.amazonaws.com/test-sa-assets/"
1818
},
1919
"response": {
2020
"binary": false,
21-
"body": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<ListBucketResult xmlns=\"http://s3.amazonaws.com/doc/2006-03-01/\"><Name>source-academy-assets</Name><Prefix>testFolder/</Prefix><Marker></Marker><MaxKeys>1000</MaxKeys><IsTruncated>false</IsTruncated><Contents><Key>testFolder/</Key><LastModified>2020-07-04T18:53:11.000Z</LastModified><ETag>&quot;d41d8cd98f00b204e9800998ecf8427e&quot;</ETag><Size>0</Size><Owner><ID>98bd2bd2de0c976fb511f741fea454cb1026b9e1f9ac9160fd9f51d07e765f19</ID><DisplayName>unixsp+cs1101s</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>testFolder/test.png</Key><LastModified>2020-07-04T19:04:50.000Z</LastModified><ETag>&quot;3104001edec38fadeb925b9dbddab198&quot;</ETag><Size>8035</Size><Owner><ID>98bd2bd2de0c976fb511f741fea454cb1026b9e1f9ac9160fd9f51d07e765f19</ID><DisplayName>unixsp+cs1101s</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>testFolder/test2.png</Key><LastModified>2020-07-04T19:04:50.000Z</LastModified><ETag>&quot;3104001edec38fadeb925b9dbddab198&quot;</ETag><Size>8035</Size><Owner><ID>98bd2bd2de0c976fb511f741fea454cb1026b9e1f9ac9160fd9f51d07e765f19</ID><DisplayName>unixsp+cs1101s</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents></ListBucketResult>",
21+
"body": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<ListBucketResult xmlns=\"http://s3.amazonaws.com/doc/2006-03-01/\"><Name>test-sa-assets</Name><Prefix>117/testFolder/</Prefix><Marker></Marker><MaxKeys>1000</MaxKeys><IsTruncated>false</IsTruncated><Contents><Key>testFolder/</Key><LastModified>2020-07-04T18:53:11.000Z</LastModified><ETag>&quot;d41d8cd98f00b204e9800998ecf8427e&quot;</ETag><Size>0</Size><Owner><ID>98bd2bd2de0c976fb511f741fea454cb1026b9e1f9ac9160fd9f51d07e765f19</ID><DisplayName>unixsp+cs1101s</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>testFolder/test.png</Key><LastModified>2020-07-04T19:04:50.000Z</LastModified><ETag>&quot;3104001edec38fadeb925b9dbddab198&quot;</ETag><Size>8035</Size><Owner><ID>98bd2bd2de0c976fb511f741fea454cb1026b9e1f9ac9160fd9f51d07e765f19</ID><DisplayName>unixsp+cs1101s</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents><Contents><Key>testFolder/test2.png</Key><LastModified>2020-07-04T19:04:50.000Z</LastModified><ETag>&quot;3104001edec38fadeb925b9dbddab198&quot;</ETag><Size>8035</Size><Owner><ID>98bd2bd2de0c976fb511f741fea454cb1026b9e1f9ac9160fd9f51d07e765f19</ID><DisplayName>unixsp+cs1101s</DisplayName></Owner><StorageClass>STANDARD</StorageClass></Contents></ListBucketResult>",
2222
"headers": {
2323
"Date": "Sat, 04 Jul 2020 19:04:57 GMT",
2424
"x-amz-bucket-region": "ap-southeast-1",

0 commit comments

Comments
 (0)