Skip to content

Commit

Permalink
Fix #61 (#65)
Browse files Browse the repository at this point in the history
  • Loading branch information
bstopp authored Aug 8, 2024
1 parent 182f7cd commit 2696893
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 35 deletions.
6 changes: 5 additions & 1 deletion src/storage/object/copy.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export const copyFile = async (client, daCtx, sourceKey, details, isRename) => {
Version: crypto.randomUUID(),
Timestamp: `${Date.now()}`,
Users: JSON.stringify(daCtx.users),
Path: details.destination,
Path: Key,
};
input.MetadataDirective = 'REPLACE';
}
Expand All @@ -57,6 +57,10 @@ export const copyFile = async (client, daCtx, sourceKey, details, isRename) => {
};

export default async function copyObject(env, daCtx, details, isRename) {
if (details.source === details.destination) {
return { body: '', status: 409 };
}

const config = getS3Config(env);
const client = new S3Client(config);
const input = buildInput(daCtx.org, details.source);
Expand Down
90 changes: 56 additions & 34 deletions test/storage/object/copy.test.js
Original file line number Diff line number Diff line change
@@ -1,67 +1,89 @@
import assert from 'assert';
import esmock from 'esmock';
import { copyFile } from '../../../src/storage/object/copy.js';

/*
* Copyright 2024 Adobe. All rights reserved.
* This file is licensed to you under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License. You may obtain a copy
* of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under
* the License is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
* OF ANY KIND, either express or implied. See the License for the specific language
* governing permissions and limitations under the License.
*/
import assert from 'node:assert';
import { CopyObjectCommand, ListObjectsV2Command, S3Client } from '@aws-sdk/client-s3';
import { mockClient } from 'aws-sdk-client-mock';
import { S3Client } from '@aws-sdk/client-s3';

import copyObject from '../../../src/storage/object/copy.js';

const s3Mock = mockClient(S3Client);

describe('Object copy', () => {
beforeEach(() => {
s3Mock.reset();
});

it('does not allow copying to the same location', async () => {
const details = {
source: 'mydir',
destination: 'mydir',
};
const resp = await copyObject({}, {}, details, false);
assert.strictEqual(resp.status, 409);
});

it('Copies a file', async () => {
s3Mock.on(ListObjectsV2Command).resolves({ Contents: [{ Key: 'mydir/xyz.html' }] });

const s3Sent = [];
const mockS3Client = {
send(command) {
s3Sent.push(command);
}
};
s3Mock.on(CopyObjectCommand).callsFake((input => {
s3Sent.push(input);
}));

const ctx = {
org: 'foo',
users: [{email: "[email protected]"}],
users: [{email: '[email protected]'}],
};
const sourceKey = 'mydir/xyz.html';
const details = {
source: 'mydir',
destination: 'mydir/newdir',
};
copyFile(mockS3Client, ctx, sourceKey, details, false);
await copyObject({}, ctx, details, false);

assert.equal(1, s3Sent.length);
const input = s3Sent[0].input;
assert.equal('foo-content', input.Bucket);
assert.equal('foo-content/mydir/xyz.html', input.CopySource);
assert.equal('mydir/newdir/xyz.html', input.Key);
assert.strictEqual(s3Sent.length, 3);
const input = s3Sent[0];
assert.strictEqual(input.Bucket, 'foo-content');
assert.strictEqual(input.CopySource, 'foo-content/mydir/xyz.html');
assert.strictEqual(input.Key, 'mydir/newdir/xyz.html');

const md = input.Metadata;
assert(md.ID, "ID should be set");
assert(md.Version, "Version should be set");
assert.equal('string', typeof(md.Timestamp), "Timestamp should be set as a string");
assert.equal(md.Users, '[{"email":"[email protected]"}]');
assert.equal(md.Path, 'mydir/newdir');
assert.strictEqual(typeof(md.Timestamp), 'string', 'Timestamp should be set as a string');
assert.strictEqual(md.Users, '[{"email":"[email protected]"}]');
assert.strictEqual(md.Path, 'mydir/newdir/xyz.html');
});

it('Copies a file for rename', async () => {
s3Mock.on(ListObjectsV2Command).resolves({ Contents: [{ Key: 'mydir/dir1/myfile.html' }] });

const s3Sent = [];
const mockS3Client = {
send(command) {
s3Sent.push(command);
}
};
s3Mock.on(CopyObjectCommand).callsFake((input => {
s3Sent.push(input);
}));

const ctx = { org: 'testorg' };
const sourceKey = 'mydir/dir1/myfile.html';
const details = {
source: 'mydir/dir1',
destination: 'mydir/dir2',
};
copyFile(mockS3Client, ctx, sourceKey, details, true);
await copyObject({}, ctx, details, true);


assert.equal(1, s3Sent.length);
const input = s3Sent[0].input;
assert.equal('testorg-content', input.Bucket);
assert.equal('testorg-content/mydir/dir1/myfile.html', input.CopySource);
assert.equal('mydir/dir2/myfile.html', input.Key);
assert(input.Metadata === undefined, "Should not redefine metadata for rename");
assert.strictEqual(s3Sent.length, 3);
const input = s3Sent[0];
assert.strictEqual(input.Bucket, 'testorg-content');
assert.strictEqual(input.CopySource, 'testorg-content/mydir/dir1/myfile.html');
assert.strictEqual(input.Key, 'mydir/dir2/myfile.html');
assert.ifError(input.Metadata);
});
});

0 comments on commit 2696893

Please sign in to comment.