Skip to content

Commit

Permalink
Test: upload attachments test cases & bug fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
satrun77 committed Apr 1, 2015
1 parent 50ad082 commit 93eb9ba
Show file tree
Hide file tree
Showing 11 changed files with 301 additions and 13 deletions.
1 change: 1 addition & 0 deletions .env.testing
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ APP_TIMEZONE=Pacific/Auckland
DB_DEFAULT=sqlite
MAIL_ADDRESS=[email protected]
MAIL_NAME=test
APP_UPLOAD_DIR=testing
4 changes: 2 additions & 2 deletions app/Http/Controllers/Project/IssueController.php
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ public function getDisplayAttachment(Project $project, Issue $issue, Attachment
$issue->setRelation('project', $project);
$attachment->setRelation('issue', $issue);

$path = 'uploads/' . $issue->project_id . '/' . $attachment->upload_token . '/' . $attachment->filename;
$path = config('tinyissue.uploads_dir') . '/' . $issue->project_id . '/' . $attachment->upload_token . '/' . $attachment->filename;
$storage = \Storage::disk('local');
$length = $storage->size($path);
$time = $storage->lastModified($path);
Expand Down Expand Up @@ -353,7 +353,7 @@ public function getDownloadAttachment(Project $project, Issue $issue, Attachment
$issue->setRelation('project', $project);
$attachment->setRelation('issue', $issue);

$path = config('filesystems.disks.local.root') . '/uploads/' . $this->issue->project_id . '/' . $this->upload_token . '/' . $attachment->filename;
$path = config('filesystems.disks.local.root') . '/' . config('tinyissue.uploads_dir') . '/' . $issue->project_id . '/' . $attachment->upload_token . '/' . $attachment->filename;

return response()->download($path, $attachment->filename);
}
Expand Down
4 changes: 3 additions & 1 deletion app/Model/Project/Issue.php
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,9 @@ public function project()
*/
public function attachments()
{
return $this->hasMany('Tinyissue\Model\Project\Issue\Attachment', 'issue_id')->where('comment_id', '=', 0);
return $this->hasMany('Tinyissue\Model\Project\Issue\Attachment', 'issue_id')
->where('comment_id', '=', 0)
->orWhere('comment_id', '=', null);
}

/**
Expand Down
22 changes: 14 additions & 8 deletions app/Model/Project/Issue/Attachment.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ public function user()
{
return $this->belongsTo('Tinyissue\Model\User', 'uploaded_by');
}

/**
* An attachment can belong to a comment (inverse relationship of Comments::attachments).
*
Expand All @@ -82,7 +83,7 @@ public function comment()
*/
public function upload(array $input, Project $project, User $user)
{
$relativePath = '/uploads/' . $project->id . '/' . $input['upload_token'];
$relativePath = '/' . config('tinyissue.uploads_dir') . '/' . $project->id . '/' . $input['upload_token'];
\Storage::disk('local')->makeDirectory($relativePath, 0777, true);
$path = config('filesystems.disks.local.root') . $relativePath;

Expand Down Expand Up @@ -115,7 +116,7 @@ public function remove(array $input, Project $project, User $user)
->where('filename', '=', $input['filename'])
->delete();

$path = config('filesystems.disks.local.root') . '/uploads/' . $project->id . '/' . $input['upload_token'];
$path = config('filesystems.disks.local.root') . '/' . config('tinyissue.uploads_dir') . '/' . $project->id . '/' . $input['upload_token'];
$this->deleteFile($path, $input['filename']);
}

Expand All @@ -127,7 +128,7 @@ public function remove(array $input, Project $project, User $user)
*/
public function deleteFile($path, $filename)
{
@unlink($path.'/'.$filename);
@unlink($path . '/' . $filename);
@rmdir($path);
}

Expand All @@ -139,9 +140,14 @@ public function deleteFile($path, $filename)
public function isImage()
{
return in_array($this->fileextension, [
'jpg', 'jpeg', 'JPG', 'JPEG',
'png', 'PNG',
'gif', 'GIF',
'jpg',
'jpeg',
'JPG',
'JPEG',
'png',
'PNG',
'gif',
'GIF',
]);
}

Expand All @@ -152,7 +158,7 @@ public function isImage()
*/
public function download()
{
return \URL::to('project/'.$this->issue->project_id.'/issue/'.$this->issue_id.'/download/'.$this->id);
return \URL::to('project/' . $this->issue->project_id . '/issue/' . $this->issue_id . '/download/' . $this->id);
}

/**
Expand All @@ -162,6 +168,6 @@ public function download()
*/
public function display()
{
return \URL::to('project/'.$this->issue->project_id.'/issue/'.$this->issue_id.'/display/'.$this->id);
return \URL::to('project/' . $this->issue->project_id . '/issue/' . $this->issue_id . '/display/' . $this->id);
}
}
2 changes: 1 addition & 1 deletion app/Model/Project/Issue/Comment.php
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ public function deleteComment()
$this->activity()->delete();

foreach ($this->attachments as $attachment) {
$path = config('filesystems.disks.local.root') . '/uploads/' . $this->project_id . '/' . $attachment->upload_token;
$path = config('filesystems.disks.local.root') . '/' . config('tinyissue.uploads_dir') . '/' . $this->project_id . '/' . $attachment->upload_token;
$attachment->deleteFile($path, $attachment->filename);
$attachment->delete();
}
Expand Down
1 change: 1 addition & 0 deletions app/Providers/ConfigServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ public function register()
config([
'tinyissue.release_date' => '4-11-2013',
'tinyissue.version' => '1.3.1',
'tinyissue.uploads_dir' => env('APP_UPLOAD_DIR', 'uploads'),
]);
}
}
1 change: 1 addition & 0 deletions tests/_data/upload1.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
upload1
1 change: 1 addition & 0 deletions tests/_data/upload2.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
upload2
92 changes: 92 additions & 0 deletions tests/_support/FunctionalHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,13 @@

// here you can define custom actions
// all public methods declared in helper class will be available in $I
use Codeception\Configuration;
use Codeception\Exception\ElementNotFound;
use Codeception\Module;
use Codeception\TestCase;
use Illuminate\Support\Facades\Hash;
use Symfony\Component\DomCrawler\Crawler;
use Symfony\Component\DomCrawler\Form;
use Tinyissue\Model;

class FunctionalHelper extends \Codeception\Module
Expand Down Expand Up @@ -227,4 +233,90 @@ protected function debugResponse()
$this->debugSection('Cookies', $module->client->getInternalRequest()->getCookies());
$this->debugSection('Headers', $module->client->getInternalResponse()->getHeaders());
}

public function submitFormWithFileToUri($selector, $uri, array $files, array $params = [])
{
$form = $this->matchForm($selector);

// Upload files
foreach ($files as $fieldName => $fileNames) {
$this->uploadFileWithForm($form, $uri, $fieldName, $fileNames);
}

// Make sure upload token is same as upload files request
$params['upload_token'] = $form->get('upload_token')->getValue();
$form->setValues($params);

$this->debugSection('Uri', $form->getUri());
$this->debugSection($form->getMethod(), $form->getValues());

// Save Form request
$module = $this->getModule('Laravel5');
$module->client->request($form->getMethod(), $form->getUri(), $form->getPhpValues(), []);
$this->debugResponse();
}

/**
* @param string $selector
*
* @return Form
*/
protected function matchForm($selector)
{
$form = $this->match($selector)->form();

if (!$form instanceof Form) {
throw new ElementNotFound($selector, 'Form');
}

return $form;
}

/**
* @param string $selector
*
* @return Crawler
*/
protected function match($selector)
{
return $this->getModule('Laravel5')->client->getCrawler()->filter($selector);
}

public function uploadFileWithForm($selectorOrForm, $uri, $fieldName, $fileNames)
{
// find form
if (!$selectorOrForm instanceof Form) {
$form = $this->matchForm($selectorOrForm);
} else {
$form = $selectorOrForm;
}

// Make sure fileNames is array
if (!is_array($fileNames)) {
$fileNames = [$fileNames];
}

/** @var $file \Symfony\Component\DomCrawler\Field\FileFormField */
$file = $form->get($fieldName);

// Upload files
foreach ($fileNames as $fileName) {
$filePath = Configuration::dataDir() . $fileName;
if (!is_readable($filePath)) {
$this->fail("file $filePath not found in Codeception data path. Only files stored in data path accepted");
}

// Attach file to form file
$file->upload($filePath);

$this->debugSection('Uri', $uri);
$this->debugSection($form->getMethod(), $form->getValues());
$this->debugSection('Files', $form->getPhpFiles());

// Upload files request
$module = $this->getModule('Laravel5');
$module->client->request($form->getMethod(), $uri, $form->getPhpValues(), $form->getPhpFiles());
$this->debugResponse();
}
}
}
162 changes: 162 additions & 0 deletions tests/functional/CrudAttachmentCest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
<?php

class CrudAttachmentCest
{

public function _before()
{
exec('mkdir ' . config('filesystems.disks.local.root') . '/' . config('tinyissue.uploads_dir'));
}

public function _after()
{
exec('rm -rf ' . config('filesystems.disks.local.root') . '/' . config('tinyissue.uploads_dir'));
}

/**
* @param FunctionalTester $I
*
* @actor FunctionalTester
*
* @return void
*/
public function addIssue(FunctionalTester $I)
{
$title = 'Issue 1';
$body = 'Issue 1 description';
$fileName = 'upload1.txt';

$I->am('Manager User');
$I->wantTo('add new issue to a project with attachment');

$manager = $I->createUser(1, 3);
$I->amLoggedAs($manager);
$project = $I->createProject(1);
$I->amOnAction('Project\IssueController@getNew', ['project' => $project]);
$uri = $I->getApplication()->url->action('Project\IssueController@postUploadAttachment', [
'project' => $project
]);
$I->submitFormWithFileToUri('.form-horizontal', $uri, ['upload' => $fileName], [
'title' => $title,
'body' => $body,
]);
$I->seeResponseCodeIs(200);
$issue = $I->fetchIssueBy('title', $title);
$I->seeCurrentActionIs('Project\IssueController@getIndex', ['project' => $project, 'issue' => $issue]);
$I->amOnAction('Project\IssueController@getIndex', ['project' => $project, 'issue' => $issue]);
$I->seeResponseCodeIs(200);
$I->seeLink($title);
$I->seeLink($fileName);
$I->see($fileName, '.attachments');
$I->see($body, '.content');
$I->seeElement('.attachments a', ['title' => $fileName]);
$attachment = $issue->attachments->first();
$I->amOnAction('Project\IssueController@getDisplayAttachment', [
'project' => $project,
'issue' => $issue,
'attachment' => $attachment
]);
$I->seeResponseCodeIs(200);
}

/**
* @param FunctionalTester $I
*
* @actor FunctionalTester
*
* @return void
*/
public function addIssueComment(FunctionalTester $I)
{
$comment = 'Comment 1';
$fileName1 = 'upload1.txt';
$fileName2 = 'upload2.txt';

$I->am('Manager User');
$I->wantTo('add new comment to a project issue with attachments');

$manager = $I->createUser(1, 3);
$I->amLoggedAs($manager);
$issue = $I->createIssue(1, $manager);
$project = $issue->project;
$I->amOnAction('Project\IssueController@getIndex', ['project' => $project, 'issue' => $issue]);
$I->seeResponseCodeIs(200);

$uri = $I->getApplication()->url->action('Project\IssueController@postUploadAttachment', [
'project' => $project
]);
$I->submitFormWithFileToUri('.new-comment form', $uri, ['upload' => [$fileName1, $fileName2]], [
'comment' => $comment,
]);
$I->seeResponseCodeIs(200);
$I->seeCurrentActionIs('Project\IssueController@getIndex', ['project' => $project, 'issue' => $issue]);
$I->amOnAction('Project\IssueController@getIndex', ['project' => $project, 'issue' => $issue]);
$I->see($comment, '.comment .content');
$I->seeLink($fileName1);
$I->seeLink($fileName2);
$I->see($fileName1, '.attachments');
$I->see($fileName2, '.attachments');
$attachments = $issue->comments->first()->attachments;
foreach ($attachments as $attachment) {
$I->amOnAction('Project\IssueController@getDisplayAttachment', [
'project' => $project,
'issue' => $issue,
'attachment' => $attachment
]);
$I->seeResponseCodeIs(200);
}
}

/**
* @param FunctionalTester $I
*
* @actor FunctionalTester
*
* @return void
*/
public function removeAttachment(FunctionalTester $I)
{
$I->am('Manager User');
$I->wantTo('remove an attachment from a project issue comments');

$fileName = 'upload1.txt';

$manager = $I->createUser(1, 3);
$I->amLoggedAs($manager);
$issue = $I->createIssue(1, $manager);
$project = $issue->project;
$I->amOnAction('Project\IssueController@getIndex', ['project' => $project, 'issue' => $issue]);
$uploadToken = $I->grabValueFrom('//form/input[@name="upload_token"]');
$uri = $I->getApplication()->url->action('Project\IssueController@postUploadAttachment', [
'project' => $project
]);
$I->submitFormWithFileToUri('.new-comment form', $uri, ['upload' => $fileName], [
'comment' => 'Comment 1',
]);
$attachment = $issue->comments->first()->attachments->first();
$I->amOnAction('Project\IssueController@getDownloadAttachment', [
'project' => $project,
'issue' => $issue,
'attachment' => $attachment
]);
$I->seeResponseCodeIs(200);
$I->amOnAction('Project\IssueController@getIndex', ['project' => $project, 'issue' => $issue]);
$I->seeElement('.attachments a', ['title' => $fileName]);
$uri = $I->getApplication()->url->action('Project\IssueController@postRemoveAttachment', [
'project' => $project
]);
$I->sendAjaxPostRequest($uri, [
'_token' => csrf_token(),
'upload_token' => $uploadToken,
'filename' => $fileName
]);
$I->amOnAction('Project\IssueController@getIndex', ['project' => $project, 'issue' => $issue]);
$I->dontSeeElement('.attachments a', ['title' => $fileName]);
$I->amOnAction('Project\IssueController@getDisplayAttachment', [
'project' => $project,
'issue' => $issue,
'attachment' => $attachment
]);
$I->seeResponseCodeIs(404);
}
}
Loading

0 comments on commit 93eb9ba

Please sign in to comment.