Skip to content

Commit

Permalink
Fixes and more profile tests
Browse files Browse the repository at this point in the history
  • Loading branch information
whikloj committed Apr 12, 2024
1 parent c57f1e0 commit 8a435ed
Show file tree
Hide file tree
Showing 11 changed files with 302 additions and 15 deletions.
29 changes: 18 additions & 11 deletions src/Profiles/BagItProfile.php
Original file line number Diff line number Diff line change
Expand Up @@ -347,12 +347,9 @@ private function setBagInfoTags(array $bagInfoTags): BagItProfile
if (count(array_diff_key($tagOpts, $expectedKeys)) > 0) {
throw new ProfileException("Invalid tag options for $tagName");
}
if (array_key_exists($tagName, $this->profileBagInfoTags)) {
throw new ProfileException("Duplicate tag $tagName");
}
if (self::matchStrings('BagIt-Profile-Identifier', $tagName)) {
$this->profileWarnings[] = "The tag BagIt-Profile-Identifier is always required, but SHOULD NOT be
listed under Bag-Info in the Profile.";
$this->profileWarnings[] = "The tag BagIt-Profile-Identifier is always required, but SHOULD NOT be " .
"listed under Bag-Info in the Profile.";
} else {
$profileTag = ProfileTags::fromJson($tagName, $tagOpts);
$this->profileBagInfoTags[BagUtils::trimLower($tagName)] = $profileTag;
Expand Down Expand Up @@ -442,7 +439,7 @@ public function isRequireFetchTxt(): bool
private function setRequireFetchTxt(?bool $requireFetchTxt): BagItProfile
{
if ($requireFetchTxt === true && $this->allowFetchTxt === false) {
throw new ProfileException("Require-Fetch.txt cannot be true if Allow-Fetch.txt is false");
throw new ProfileException("Allow-Fetch.txt cannot be false if Require-Fetch.txt is true");
}
$this->requireFetchTxt = $requireFetchTxt ?? false;
return $this;
Expand Down Expand Up @@ -887,16 +884,17 @@ public function validateBag(Bag $bag): bool
$errors[] = "Profile requires fetch.txt but the bag does not have one";
}
if ($this->isDataEmpty()) {
$manifests = $bag->getPayloadManifests()[0];
$manifests = current($bag->getPayloadManifests());
$hashes = $manifests->getHashes();
if (count($hashes) > 1) {
$errors[] = "Profile requires /data directory to be empty or contain a single 0 byte file but it" .
"contains " . count($hashes) . " files";
" contains " . count($hashes) . " files";
} elseif (count($hashes) == 1) {
$file = reset($hashes);
if (stat($file)['size'] > 0) {
$file = array_key_first($hashes);
$absolute = $bag->makeAbsolute($file);
if (stat($absolute)['size'] > 0) {
$errors[] = "Profile requires /data directory to be empty or contain a single 0 byte file but it" .
"contains a single file of size " . stat($file)['size'];
" contains a single file of size " . stat($absolute)['size'];
}
}
}
Expand Down Expand Up @@ -1008,4 +1006,13 @@ public function validateBag(Bag $bag): bool
}
return true;
}

/**
* Get the list of warnings generated during the validation of the profile.
* @return array The list of warnings.
*/
public function getWarnings(): array
{
return $this->profileWarnings;
}
}
2 changes: 1 addition & 1 deletion tests/Profiles/BagItProfileBarTest.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace Profiles;
namespace whikloj\BagItTools\Test\Profiles;

use whikloj\BagItTools\Profiles\BagItProfile;
use whikloj\BagItTools\Test\BagItTestFramework;
Expand Down
2 changes: 1 addition & 1 deletion tests/Profiles/BagItProfileFooTest.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace Profiles;
namespace whikloj\BagItTools\Test\Profiles;

use whikloj\BagItTools\Test\Profiles\ProfileTestFramework;

Expand Down
154 changes: 152 additions & 2 deletions tests/Profiles/BagProfileTest.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace Profiles;
namespace whikloj\BagItTools\Test\Profiles;

use whikloj\BagItTools\Bag;
use whikloj\BagItTools\Exceptions\ProfileException;
Expand All @@ -14,19 +14,169 @@
*/
class BagProfileTest extends BagItTestFramework
{
private static $profiles = self::TEST_RESOURCES . '/profiles';

/**
* Try to validate a bag.
* @group Profiles
* @covers ::validateBag
*/
public function testValidateBag1(): void
{
$profile = BagItProfile::fromJson(file_get_contents(self::TEST_RESOURCES . '/profiles/bagProfileFoo.json'));
$profile = BagItProfile::fromJson(file_get_contents(self::$profiles . "/bagProfileFoo.json"));
$this->assertTrue($profile->isValid());
$this->tmpdir = $this->prepareExtendedTestBag();
$bag = Bag::load($this->tmpdir);
$this->assertTrue($bag->isValid());
$this->expectException(ProfileException::class);
$profile->validateBag($bag);
}

/**
* Try to load a bad profile.
* @group Profiles
* @covers ::setBagInfoTags
*/
public function testInvalidBagInfoTags(): void
{
$this->expectException(ProfileException::class);
$this->expectExceptionMessage("Invalid tag options for Source-Organization");
BagItProfile::fromJson(file_get_contents(self::$profiles . "/test_profiles/invalid_bag_info_tag_options.json"));
}

/**
* Try to load a profile with the BagIt-Profile-Identifier specified in the Bag-Info tags.
* @group Profiles
* @covers ::setBagInfoTags
*/
public function testBagItProfileIdentifierInTags(): void
{
$profile = BagItProfile::fromJson(file_get_contents(
self::$profiles . "/test_profiles/profile_identifier_bag_info_tag.json"
));
$this->assertArrayEquals(
[
"The tag BagIt-Profile-Identifier is always required, but SHOULD NOT be listed under Bag-Info in " .
"the Profile."
],
$profile->getWarnings()
);
}

/**
* @group Profiles
* @covers ::setManifestsAllowed
*/
public function testSetManifestAllowed(): void
{
$profile = BagItProfile::fromJson(file_get_contents(
self::$profiles . "/test_profiles/set_manifest_allowed_valid.json"
));
$this->assertTrue($profile->isValid());
}

/**
* @group Profiles
* @covers ::setManifestsAllowed
*/
public function testSetManifestAllowedInvalid(): void
{
$this->expectException(ProfileException::class);
$this->expectExceptionMessage("Manifests-Allowed must include all entries from Manifests-Required");
BagItProfile::fromJson(file_get_contents(
self::$profiles . "/test_profiles/set_manifest_allowed_invalid.json"
));
}

/**
* @group Profiles
* @covers ::setAllowFetchTxt
*/
public function testAllowFetchInvalid(): void
{
$this->expectException(ProfileException::class);
$this->expectExceptionMessage("Allow-Fetch.txt cannot be false if Require-Fetch.txt is true");
BagItProfile::fromJson(file_get_contents(
self::$profiles . "/test_profiles/allow_fetch_invalid.json"
));
}

/**
* @group Profiles
* @covers ::setRequireFetchTxt
*/
public function testAllowFetchInvalid2(): void
{
$this->expectException(ProfileException::class);
$this->expectExceptionMessage("Allow-Fetch.txt cannot be false if Require-Fetch.txt is true");
BagItProfile::fromJson(file_get_contents(
self::$profiles . "/test_profiles/allow_fetch_invalid_2.json"
));
}

/**
* @group Profiles
* @covers ::setDataEmpty
* @covers ::validateBag
*/
public function testDataEmpty(): void
{
$profile = BagItProfile::fromJson(file_get_contents(
self::$profiles . "/test_profiles/data_empty.json"
));
$this->assertTrue($profile->isValid());
$bag = Bag::create($this->tmpdir);
$bag->update();
// Empty data is valid.
$this->assertTrue($profile->validateBag($bag));

$bag->addFile(self::TEST_RESOURCES . "/text/empty.txt", "empty.txt");
$bag->update();
// A single zero byte file is valid.
$this->assertTrue($profile->validateBag($bag));

$bag->addFile(self::TEST_RESOURCES . "/text/empty.txt", "empty2.txt");
$bag->update();
// Two zero byte files is not valid.
$this->expectException(ProfileException::class);
$this->expectExceptionMessage("Profile requires /data directory to be empty or contain a single 0 " .
"byte file but it contains 2 files");
$profile->validateBag($bag);

$bag->removeFile("empty2.txt");
$bag->removeFile("empty.txt");
$bag->update();
// Empty data directory is valid.
$this->assertTrue($profile->validateBag($bag));

$bag->addFile(self::TEST_RESOURCES . "/images/scenic-landscape.jpg", "scenic-landscape.jpg");
$bag->update();
// A single non-zero byte file is not valid.
$this->assertFalse($profile->validateBag($bag));
}

/**
* @group Profiles
* @covers ::setDataEmpty
* @covers ::validateBag
*/
public function testDataEmpty2(): void
{
$profile = BagItProfile::fromJson(file_get_contents(
self::$profiles . "/test_profiles/data_empty.json"
));
$this->assertTrue($profile->isValid());
$bag = Bag::create($this->tmpdir);
$bag->update();
// Empty data is valid.
$this->assertTrue($profile->validateBag($bag));

$bag->addFile(self::TEST_RESOURCES . "/images/scenic-landscape.jpg", "scenic-landscape.jpg");
$bag->update();
// A single non-zero byte file is not valid.
$this->expectException(ProfileException::class);
$this->expectExceptionMessage("Profile requires /data directory to be empty or contain a single 0 byte " .
"file but it contains a single file of size 398246");
$profile->validateBag($bag);
}
}
16 changes: 16 additions & 0 deletions tests/resources/profiles/test_profiles/allow_fetch_invalid.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"BagIt-Profile-Info":{
"BagIt-Profile-Identifier":"http://somewhere.org/my/profile.json",
"BagIt-Profile-Version": "0.1",
"Source-Organization":"Monsters, Inc.",
"Contact-Name":"Mike Wazowski",
"External-Description":"Profile for testing bad bag info tag options",
"Version":"0.3"
},
"Require-Fetch.txt": true,
"Allow-Fetch.txt": false,
"Serialization": "forbidden",
"Accept-BagIt-Version":[
"1.0"
]
}
16 changes: 16 additions & 0 deletions tests/resources/profiles/test_profiles/allow_fetch_invalid_2.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"BagIt-Profile-Info":{
"BagIt-Profile-Identifier":"http://somewhere.org/my/profile.json",
"BagIt-Profile-Version": "0.1",
"Source-Organization":"Monsters, Inc.",
"Contact-Name":"Mike Wazowski",
"External-Description":"Profile for testing bad bag info tag options",
"Version":"0.3"
},
"Allow-Fetch.txt": false,
"Require-Fetch.txt": true,
"Serialization": "forbidden",
"Accept-BagIt-Version":[
"1.0"
]
}
19 changes: 19 additions & 0 deletions tests/resources/profiles/test_profiles/data_empty.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"BagIt-Profile-Info":{
"BagIt-Profile-Identifier":"http://somewhere.org/my/profile.json",
"BagIt-Profile-Version": "0.1",
"Source-Organization":"Monsters, Inc.",
"Contact-Name":"Mike Wazowski",
"External-Description":"Profile for testing bad bag info tag options",
"Version":"0.3"
},
"Manifests-Allowed": [
"md5",
"sha512"
],
"Data-Empty": true,
"Serialization": "forbidden",
"Accept-BagIt-Version":[
"1.0"
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"BagIt-Profile-Info":{
"BagIt-Profile-Identifier":"http://somewhere.org/my/profile.json",
"BagIt-Profile-Version": "0.1",
"Source-Organization":"Monsters, Inc.",
"Contact-Name":"Mike Wazowski",
"External-Description":"Profile for testing bad bag info tag options",
"Version":"0.3"
},
"Bag-Info":{
"Source-Organization":{
"required":true,
"values":[
"Simon Fraser University",
"York University"
],
"help": "This is the organization that originally created the bag."
}
},
"Serialization": "forbidden",
"Accept-BagIt-Version":[
"1.0"
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"BagIt-Profile-Info":{
"BagIt-Profile-Identifier":"http://somewhere.org/my/profile.json",
"BagIt-Profile-Version": "0.1",
"Source-Organization":"Monsters, Inc.",
"Contact-Name":"Mike Wazowski",
"External-Description":"Profile for testing bad bag info tag options",
"Version":"0.3"
},
"Bag-Info":{
"BagIt-Profile-Identifier":{
"required":true
}
},
"Serialization": "forbidden",
"Accept-BagIt-Version":[
"1.0"
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"BagIt-Profile-Info":{
"BagIt-Profile-Identifier":"http://somewhere.org/my/profile.json",
"BagIt-Profile-Version": "0.1",
"Source-Organization":"Monsters, Inc.",
"Contact-Name":"Mike Wazowski",
"External-Description":"Profile for testing bad bag info tag options",
"Version":"0.3"
},
"Manifests-Required": [
"md5",
"sha512"
],
"Manifests-Allowed": [
"md5",
"sha256"
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"BagIt-Profile-Info":{
"BagIt-Profile-Identifier":"http://somewhere.org/my/profile.json",
"BagIt-Profile-Version": "0.1",
"Source-Organization":"Monsters, Inc.",
"Contact-Name":"Mike Wazowski",
"External-Description":"Profile for testing bad bag info tag options",
"Version":"0.3"
},
"Manifests-Allowed": [
"md5",
"sha256"
],
"Serialization": "forbidden",
"Accept-BagIt-Version":[
"1.0"
]
}

0 comments on commit 8a435ed

Please sign in to comment.