2017-09-29 2 views
0

Ich baue eine Datei-Upload-JSON-API mit Lumen und versuchen, PHPPunkt API-Tests schreiben.Lumen 5.5 JSON API-Datei-Upload-Test bricht mit UploadedFile

Das Problem, das ich allerdings habe ist, dass, sobald ich versuche, einen Datei-Upload mit einem realen Bild wie ["file" => new UploadedFile(TestUtils::tempPath('test.jpg'), 'test.jpg', "image\jpeg", 100, null, true)] aufgebaut zu simulieren und über $this->json('POST', '/chunk', $data); Senden wir nichts mit der hochgeladenen Datei tun können, weil es eine ist Array und ich bekomme den Fehler Call to a member function move() on array in ...

Seltsamerweise, wenn ich UploadedFile::fake()->image('test.jpg') verwende es Mangels meine Anfrage und die anderen Daten, die ich damit sende ist nicht in der Steuerung.

Wenn ich das Dateiobjekt in meinem Controller dd, zeigt es ein "Array (0) {}". Ich denke, es hat etwas mit der Übertragung über JSON ('POST') zu tun, da Unit-Tests, die ein UploadedFileObject verwenden, direkt erfolgreich ausgeführt werden.

Wenn ich die gesamte Anfrage dd, es zeigt:

["request"]=> 
    object(Symfony\Component\HttpFoundation\ParameterBag)#52 (1) { 
    ["parameters":protected]=> 
    array(5) { 
     ["chunkType"]=> 
     string(4) "flow" 
     ["flowIdentifier"]=> 
     string(13) "Testing123Bnu" 
     ["flowChunkNumber"]=> 
     int(1) 
     ["flowTotalChunks"]=> 
     int(2) 
     ["file"]=> 
     array(0) { 
     } 
    } 
    } 

... 

["files"]=> 
object(Symfony\Component\HttpFoundation\FileBag)#71 (1) { 
    ["parameters":protected]=> 
    array(0) { 
    } 
    } 

... 

["content":protected]=> string(103) "{(otherData..), "file":{}}" 

Ich habe keine Ahnung, wie dies zu umgehen oder einen Datei-Upload in dieser Situation testen und haben stundenlang gesucht. Der Symfony-Testmodus im UploadedFile-Konstruktor hat keine Auswirkungen.

Hier ist mein Test:

public function testChunkUpload_FlowChunk() 
    {  
     $data = [ (otherData) 
        "file"    => new UploadedFile(TestUtils::tempPath('test.jpg'), 'test.jpg', "image\jpeg", 100, null, true) 
        //UploadedFile::fake()->image('test.jpg') 
       ]; 

     $this->assertFileExists(TestUtils::tempPath('test.jpg')); 

     $this->json('POST', '/chunk', $data); 

     $this->assertEquals(200, $this->response->status()); 
     $this->assertEquals('application/json', $this->response->headers->get('Content-Type')); 
    } 

Und hier ist die entsprechende Methode in meinem Controller:

public function receiveChunk(Request $request){ 
    if (! $request->has('chunkType')) { 
     return response()->json(["Invalid Chunk Type"], 400); 
    } 
    $data = $this->chunkNormalizer->normalizeInput($request->all()); 
    $chunk = $this->chunkFactory->createChunk( (otherData) 
               $data['fileHandle']); 

    $this->fileAssembler->processChunk($chunk); 

    return response()->json(["Success"], 200);  
} 

Und der Fehler tritt in processChunk:

public function processChunk(FileChunk $chunk){ 
    ... 
    $chunkName = "..." . ".chunk"; 

    $fileHandle = $chunk->getFileHandle(); 
    $fileHandle->move($this->assemblePath, $chunkName); 
} 

Alle möglichen Ideen sehr geschätzt werden!

Antwort

0

EDIT: Seltsamerweise wird in den Laravel-Dokumenten die "json" -Methode anstelle von "call" verwendet. Könnte das ein Fehler sein? Oder nur ein Lumen-Inkompatibilitätsproblem? (Laravel Docs)

Ich habe herausgefunden, wie man den Test zum Laufen bringt. Meine Annahmen darüber, wie die Datei über die JS-Anbieterbibliothek hochgeladen wird, waren falsch. Tatsächlich werden die Datei-Chunks mit einem XmlHttpRequest "multipart/formdata" und NICHT als JSON hochgeladen.

Ich verstand den Fehler (JSON-Codierung), aber nicht die Quelle. Nach dem Verständnis, dass ein XmlHttpRequest verwendet wird, war die Fehlerbehebung einfach.

Arbeitstest:

public function testChunkUpload_FlowChunk() 
{  
    $data = [ (otherData) 
       "file"    => new UploadedFile(TestUtils::tempPath('test.jpg'), 'test.jpg', "image\jpeg", 100, null, true) 
       //UploadedFile::fake()->image('test.jpg') 
      ]; 

    $this->assertFileExists(TestUtils::tempPath('test.jpg')); 

    $this->call('POST', '/chunk', $data); 

    $this->assertEquals(200, $this->response->status()); 
    $this->assertEquals('application/json', $this->response->headers->get('Content-Type')); 
} 

Ich bin immer noch nicht sicher, warum UploadedFile mit :: fälschen() -> Bild ("xyz.jpg") hatte einen anderen Effekt, jetzt der Test mit beiden Verfahren läuft.