|
3 | 3 | namespace MongoDB\Tests\GridFS;
|
4 | 4 |
|
5 | 5 | use MongoDB\BSON\Binary;
|
| 6 | +use MongoDB\BSON\ObjectId; |
| 7 | +use MongoDB\Collection; |
| 8 | +use MongoDB\Driver\ReadConcern; |
| 9 | +use MongoDB\Driver\ReadPreference; |
| 10 | +use MongoDB\Driver\WriteConcern; |
6 | 11 | use MongoDB\Exception\InvalidArgumentException;
|
7 | 12 | use MongoDB\GridFS\Bucket;
|
| 13 | +use MongoDB\GridFS\CollectionWrapper; |
8 | 14 | use MongoDB\GridFS\Exception\CorruptFileException;
|
9 | 15 | use MongoDB\GridFS\Exception\FileNotFoundException;
|
10 | 16 | use MongoDB\GridFS\Exception\StreamException;
|
11 | 17 | use MongoDB\Model\BSONDocument;
|
12 | 18 | use MongoDB\Model\IndexInfo;
|
13 | 19 | use MongoDB\Operation\ListIndexes;
|
| 20 | +use MongoDB\Tests\Fixtures\Codec\TestDocumentCodec; |
14 | 21 | use MongoDB\Tests\Fixtures\Codec\TestFileCodec;
|
15 | 22 | use MongoDB\Tests\Fixtures\Document\TestFile;
|
| 23 | +use ReflectionMethod; |
16 | 24 | use stdClass;
|
17 | 25 |
|
18 | 26 | use function array_merge;
|
|
43 | 51 | */
|
44 | 52 | class BucketFunctionalTest extends FunctionalTestCase
|
45 | 53 | {
|
| 54 | + /** @doesNotPerformAssertions */ |
| 55 | + public function testValidConstructorOptions(): void |
| 56 | + { |
| 57 | + new Bucket($this->manager, $this->getDatabaseName(), [ |
| 58 | + 'bucketName' => 'test', |
| 59 | + 'chunkSizeBytes' => 8192, |
| 60 | + 'readConcern' => new ReadConcern(ReadConcern::LOCAL), |
| 61 | + 'readPreference' => new ReadPreference(ReadPreference::PRIMARY), |
| 62 | + 'writeConcern' => new WriteConcern(WriteConcern::MAJORITY, 1000), |
| 63 | + 'disableMD5' => true, |
| 64 | + ]); |
| 65 | + } |
| 66 | + |
| 67 | + /** @dataProvider provideInvalidConstructorOptions */ |
| 68 | + public function testConstructorOptionTypeChecks(array $options): void |
| 69 | + { |
| 70 | + $this->expectException(InvalidArgumentException::class); |
| 71 | + new Bucket($this->manager, $this->getDatabaseName(), $options); |
| 72 | + } |
| 73 | + |
| 74 | + public static function provideInvalidConstructorOptions() |
| 75 | + { |
| 76 | + return self::createOptionDataProvider([ |
| 77 | + 'bucketName' => self::getInvalidStringValues(true), |
| 78 | + 'chunkSizeBytes' => self::getInvalidIntegerValues(true), |
| 79 | + 'codec' => self::getInvalidDocumentCodecValues(), |
| 80 | + 'disableMD5' => self::getInvalidBooleanValues(true), |
| 81 | + 'readConcern' => self::getInvalidReadConcernValues(), |
| 82 | + 'readPreference' => self::getInvalidReadPreferenceValues(), |
| 83 | + 'typeMap' => self::getInvalidArrayValues(), |
| 84 | + 'writeConcern' => self::getInvalidWriteConcernValues(), |
| 85 | + ]); |
| 86 | + } |
| 87 | + |
| 88 | + public function testConstructorShouldRequireChunkSizeBytesOptionToBePositive(): void |
| 89 | + { |
| 90 | + $this->expectException(InvalidArgumentException::class); |
| 91 | + $this->expectExceptionMessage('Expected "chunkSizeBytes" option to be >= 1, 0 given'); |
| 92 | + new Bucket($this->manager, $this->getDatabaseName(), ['chunkSizeBytes' => 0]); |
| 93 | + } |
| 94 | + |
| 95 | + public function testConstructorWithCodecAndTypeMapOptions(): void |
| 96 | + { |
| 97 | + $options = [ |
| 98 | + 'codec' => new TestDocumentCodec(), |
| 99 | + 'typeMap' => ['root' => 'array', 'document' => 'array'], |
| 100 | + ]; |
| 101 | + |
| 102 | + $this->expectExceptionObject(InvalidArgumentException::cannotCombineCodecAndTypeMap()); |
| 103 | + new Bucket($this->manager, $this->getDatabaseName(), $options); |
| 104 | + } |
| 105 | + |
46 | 106 | /** @dataProvider provideInputDataAndExpectedChunks */
|
47 | 107 | public function testDelete($input, $expectedChunks): void
|
48 | 108 | {
|
@@ -147,6 +207,13 @@ public function testDownloadToStream($input): void
|
147 | 207 | $this->assertStreamContents($input, $destination);
|
148 | 208 | }
|
149 | 209 |
|
| 210 | + /** @dataProvider provideInvalidStreamValues */ |
| 211 | + public function testDownloadToStreamShouldRequireDestinationStream($destination): void |
| 212 | + { |
| 213 | + $this->expectException(InvalidArgumentException::class); |
| 214 | + $this->bucket->downloadToStream('id', $destination); |
| 215 | + } |
| 216 | + |
150 | 217 | public static function provideInvalidStreamValues(): array
|
151 | 218 | {
|
152 | 219 | return self::wrapValuesForDataProvider(self::getInvalidStreamValues());
|
@@ -193,6 +260,13 @@ public function testDownloadToStreamByName(): void
|
193 | 260 | $this->assertStreamContents('baz', $destination);
|
194 | 261 | }
|
195 | 262 |
|
| 263 | + /** @dataProvider provideInvalidStreamValues */ |
| 264 | + public function testDownloadToStreamByNameShouldRequireDestinationStream($destination): void |
| 265 | + { |
| 266 | + $this->expectException(InvalidArgumentException::class); |
| 267 | + $this->bucket->downloadToStreamByName('filename', $destination); |
| 268 | + } |
| 269 | + |
196 | 270 | /** @dataProvider provideNonexistentFilenameAndRevision */
|
197 | 271 | public function testDownloadToStreamByNameShouldRequireFilenameAndRevisionToExist($filename, $revision): void
|
198 | 272 | {
|
@@ -378,6 +452,43 @@ public function testFindOneResetsInheritedBucketCodec(): void
|
378 | 452 | $this->assertSame(6, $fileDocument->length);
|
379 | 453 | }
|
380 | 454 |
|
| 455 | + public function testGetBucketNameWithCustomValue(): void |
| 456 | + { |
| 457 | + $bucket = new Bucket($this->manager, $this->getDatabaseName(), ['bucketName' => 'custom_fs']); |
| 458 | + |
| 459 | + $this->assertEquals('custom_fs', $bucket->getBucketName()); |
| 460 | + } |
| 461 | + |
| 462 | + public function testGetBucketNameWithDefaultValue(): void |
| 463 | + { |
| 464 | + $this->assertEquals('fs', $this->bucket->getBucketName()); |
| 465 | + } |
| 466 | + |
| 467 | + public function testGetChunksCollection(): void |
| 468 | + { |
| 469 | + $chunksCollection = $this->bucket->getChunksCollection(); |
| 470 | + |
| 471 | + $this->assertInstanceOf(Collection::class, $chunksCollection); |
| 472 | + $this->assertEquals('fs.chunks', $chunksCollection->getCollectionName()); |
| 473 | + } |
| 474 | + |
| 475 | + public function testGetChunkSizeBytesWithCustomValue(): void |
| 476 | + { |
| 477 | + $bucket = new Bucket($this->manager, $this->getDatabaseName(), ['chunkSizeBytes' => 8192]); |
| 478 | + |
| 479 | + $this->assertEquals(8192, $bucket->getChunkSizeBytes()); |
| 480 | + } |
| 481 | + |
| 482 | + public function testGetChunkSizeBytesWithDefaultValue(): void |
| 483 | + { |
| 484 | + $this->assertEquals(261120, $this->bucket->getChunkSizeBytes()); |
| 485 | + } |
| 486 | + |
| 487 | + public function testGetDatabaseName(): void |
| 488 | + { |
| 489 | + $this->assertEquals($this->getDatabaseName(), $this->bucket->getDatabaseName()); |
| 490 | + } |
| 491 | + |
381 | 492 | public function testGetFileDocumentForStreamUsesTypeMap(): void
|
382 | 493 | {
|
383 | 494 | $metadata = ['foo' => 'bar'];
|
@@ -469,6 +580,21 @@ public function testGetFileIdForStreamWithWritableStream(): void
|
469 | 580 | $this->assertEquals(1, $this->bucket->getFileIdForStream($stream));
|
470 | 581 | }
|
471 | 582 |
|
| 583 | + /** @dataProvider provideInvalidGridFSStreamValues */ |
| 584 | + public function testGetFileIdForStreamShouldRequireGridFSStreamResource($stream): void |
| 585 | + { |
| 586 | + $this->expectException(InvalidArgumentException::class); |
| 587 | + $this->bucket->getFileIdForStream($stream); |
| 588 | + } |
| 589 | + |
| 590 | + public function testGetFilesCollection(): void |
| 591 | + { |
| 592 | + $filesCollection = $this->bucket->getFilesCollection(); |
| 593 | + |
| 594 | + $this->assertInstanceOf(Collection::class, $filesCollection); |
| 595 | + $this->assertEquals('fs.files', $filesCollection->getCollectionName()); |
| 596 | + } |
| 597 | + |
472 | 598 | /** @dataProvider provideInputDataAndExpectedChunks */
|
473 | 599 | public function testOpenDownloadStream($input): void
|
474 | 600 | {
|
@@ -815,6 +941,42 @@ public function testDanglingOpenWritableStreamWithGlobalStreamWrapperAlias(): vo
|
815 | 941 | $this->assertSame(14, $fileDocument->length);
|
816 | 942 | }
|
817 | 943 |
|
| 944 | + public function testResolveStreamContextForRead(): void |
| 945 | + { |
| 946 | + $stream = $this->bucket->openUploadStream('filename'); |
| 947 | + fwrite($stream, 'foobar'); |
| 948 | + fclose($stream); |
| 949 | + |
| 950 | + $method = new ReflectionMethod($this->bucket, 'resolveStreamContext'); |
| 951 | + $method->setAccessible(true); |
| 952 | + |
| 953 | + $context = $method->invokeArgs($this->bucket, ['gridfs://bucket/filename', 'rb', []]); |
| 954 | + |
| 955 | + $this->assertIsArray($context); |
| 956 | + $this->assertArrayHasKey('collectionWrapper', $context); |
| 957 | + $this->assertInstanceOf(CollectionWrapper::class, $context['collectionWrapper']); |
| 958 | + $this->assertArrayHasKey('file', $context); |
| 959 | + $this->assertIsObject($context['file']); |
| 960 | + $this->assertInstanceOf(ObjectId::class, $context['file']->_id); |
| 961 | + $this->assertSame('filename', $context['file']->filename); |
| 962 | + } |
| 963 | + |
| 964 | + public function testResolveStreamContextForWrite(): void |
| 965 | + { |
| 966 | + $method = new ReflectionMethod($this->bucket, 'resolveStreamContext'); |
| 967 | + $method->setAccessible(true); |
| 968 | + |
| 969 | + $context = $method->invokeArgs($this->bucket, ['gridfs://bucket/filename', 'wb', []]); |
| 970 | + |
| 971 | + $this->assertIsArray($context); |
| 972 | + $this->assertArrayHasKey('collectionWrapper', $context); |
| 973 | + $this->assertInstanceOf(CollectionWrapper::class, $context['collectionWrapper']); |
| 974 | + $this->assertArrayHasKey('filename', $context); |
| 975 | + $this->assertSame('filename', $context['filename']); |
| 976 | + $this->assertArrayHasKey('options', $context); |
| 977 | + $this->assertSame(['chunkSizeBytes' => 261120, 'disableMD5' => false], $context['options']); |
| 978 | + } |
| 979 | + |
818 | 980 | /**
|
819 | 981 | * Asserts that an index with the given name exists for the collection.
|
820 | 982 | *
|
|
0 commit comments