Skip to content

Commit 67063d2

Browse files
committed
Edits
1 parent a35285e commit 67063d2

6 files changed

Lines changed: 64 additions & 15 deletions

File tree

app/Http/Controllers/ComputerScienceResourceController.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use Illuminate\Support\Facades\Auth;
1818
use Illuminate\Support\Facades\DB;
1919
use Illuminate\Support\Facades\Log;
20+
use Illuminate\Support\Facades\Storage;
2021
use Inertia\Inertia;
2122
use Throwable;
2223

@@ -127,6 +128,18 @@ public function store(StoreResourceRequest $request)
127128
return response()->json($resource);
128129
} catch (Throwable $e) {
129130
DB::rollBack();
131+
// Attempt to remove the uploaded image if it was stored
132+
if (isset($path) && $path) {
133+
try {
134+
Storage::disk('public')->delete($path);
135+
} catch (Throwable $removeEx) {
136+
Log::warning('Failed to remove image after exception', [
137+
'user_id' => Auth::id(),
138+
'image_path' => $path,
139+
'error' => $removeEx->getMessage(),
140+
]);
141+
}
142+
}
130143
Log::critical('Failed to create resource', [
131144
'error' => $e->getMessage(),
132145
'trace' => $e->getTraceAsString(),

app/Http/Controllers/ResourceEditsController.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,11 @@ public function merge(ResourceEditsService $editsService, ResourceEdits $resourc
122122
}
123123

124124
if (array_key_exists('image_path', $changes)) {
125-
// TODO: Removed code to delete photo, will be handled in a cron job
125+
// TODO: Remove the old photo resource photo, will be handled in a cron job,
126+
//
127+
// photo image_url history can be viewed via activity log.
128+
//
129+
126130
$destPath = null;
127131
if (isset($changes['image_path'])) {
128132
// Copy the new file from 'resource-edits' to 'resource' (do not delete the old one)
@@ -131,7 +135,7 @@ public function merge(ResourceEditsService $editsService, ResourceEdits $resourc
131135
$newFileName = Str::random(40).'.'.$fileExtension;
132136
$destPath = 'resource/'.$newFileName;
133137

134-
Storage::disk('public')->copy($sourcePath, $destPath);
138+
Storage::disk('public')->move($sourcePath, $destPath);
135139
}
136140

137141
// Update image_path in DB

resources/js/Components/Form/TagSelector.vue

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,12 @@ function updateDropdownPosition() {
4747
position: "absolute",
4848
};
4949
}
50+
// Watch selectedTags and update dropdown position when tags change and dropdown is open
51+
watch(selectedTags, () => {
52+
if (showDropdown.value) {
53+
nextTick(updateDropdownPosition);
54+
}
55+
});
5056
5157
watch(showDropdown, (val) => {
5258
if (val) {
@@ -191,14 +197,6 @@ function onKeydown(event) {
191197
searchInput.value?.blur();
192198
return;
193199
}
194-
195-
if (
196-
event.key === "Backspace" &&
197-
!searchQuery.value &&
198-
selectedTags.value.length > 0
199-
) {
200-
removeTag(selectedTags.value[selectedTags.value.length - 1]);
201-
}
202200
}
203201
204202
function onBlur() {

resources/js/Components/Resources/ResourceEdit/ResourceEditsFAQ.vue

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,8 @@ import FrequentlyAskedQuestion from "@/Components/FrequentlyAskedQuestion.vue";
113113
class="border border-gray-300 dark:border-gray-600 px-4 py-2"
114114
>
115115
Since there are no existing votes (positive or negative), the entire community can merge any edits.<th></th>
116-
The reasoning is that someone could've make a typo and needed a quick fix.
116+
The reasoning is that someone could've made a typo and needed a quick fix.<th></th>
117+
Everyone automatically upvotes their own resources. So, you must unvote your newly created resource to reach 0 votes.
117118
</td>
118119
</tr>
119120
<tr>

tests/Feature/ComputerScienceResourceControllerTest.php renamed to tests/Feature/ComputerScienceResourceTest.php

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
use Tests\RequestFactories\ComputerScienceResource\StoreResourceRequestFactory;
1414
use Tests\TestCase;
1515

16-
class ComputerScienceResourceControllerTest extends TestCase
16+
class ComputerScienceResourceTest extends TestCase
1717
{
1818
use RefreshDatabase;
1919

@@ -112,4 +112,34 @@ public function test_cannot_post_resource_with_invalid_fields(string $field, mix
112112
"Failed asserting that a resource with name '{$validData['name']}' was not created in the database. Invalid field: $field"
113113
);
114114
}
115+
116+
public function test_image_is_removed_if_resource_creation_fails()
117+
{
118+
Storage::fake('public');
119+
$this->actingAs($this->user);
120+
121+
// Create valid form data but set an invalid field to force failure
122+
$formData = StoreResourceRequestFactory::new()->create();
123+
$formData['image_file'] = UploadedFile::fake()->image('fail_image.jpg');
124+
$formData['name'] = str_repeat('a', 101); // Invalid name, will fail validation
125+
126+
$response = $this->postJson(route('resources.store'), $formData);
127+
$response->assertStatus(422); // Validation error
128+
129+
// The image should not exist in storage
130+
Storage::disk('public')->assertMissing('resource/' . $formData['image_file']->hashName());
131+
}
132+
133+
public function test_model_removes_image_upon_deletion()
134+
{
135+
$resource = ComputerScienceResource::factory()->create();
136+
137+
$imagePath = $resource->image_path;
138+
139+
Storage::disk('public')->assertExists($imagePath);
140+
141+
$resource->delete();
142+
143+
Storage::disk('public')->assertMissing($imagePath);
144+
}
115145
}

tests/Feature/ResourceEditsTest.php

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -148,13 +148,13 @@ public function test_merged_edit_reflects_changes_on_original_resource(): void
148148
$resource = ComputerScienceResource::factory()->create();
149149
$this->actingAs($this->user);
150150

151-
$mergeAttempts = 10;
151+
$mergeAttempts = 5;
152152

153153
for ($i = 0; $i < $mergeAttempts; $i++) {
154154
$changes = [
155155
'name' => "Resource Name Edited {$i}",
156156
'description' => "Resource Description Changed {$i}",
157-
'image_file' => UploadedFile::fake()->image('resource.jpg'),
157+
'image_file' => UploadedFile::fake()->image("resource_{$i}.jpg"),
158158
'page_url' => "http://{$i}.com",
159159
'difficulty' => fake()->randomElement(config('computerScienceResource.difficulties')),
160160
'platforms' => fake()->randomElements(config('computerScienceResource.platforms'), fake()->numberBetween(1, 3)),
@@ -164,14 +164,17 @@ public function test_merged_edit_reflects_changes_on_original_resource(): void
164164
'general_tags' => ["$i-a", "$i-b", "$i-c"],
165165
];
166166

167-
$this->makeAndApplyResourceEdits($resource->id, $changes);
167+
$edit = $this->createResourceEdit($resource->id, $changes);
168+
$this->approveResourceEdit($edit);
168169

169170
// Refresh and assert
170171
$resource->refresh();
171172

172173
$this->assertEquals($changes['name'], $resource->name);
173174
$this->assertEquals($changes['description'], $resource->description);
175+
174176
Storage::disk('public')->assertExists($resource->image_path);
177+
Storage::disk('public')->assertMissing($edit->image_path);
175178

176179
$this->assertEquals($changes['page_url'], $resource->page_url);
177180
$this->assertEquals($changes['difficulty'], $resource->difficulty);

0 commit comments

Comments
 (0)