Skip to content

Commit 7588e27

Browse files
committed
Add unit tests #1
1 parent ef11ea3 commit 7588e27

6 files changed

Lines changed: 589 additions & 0 deletions

File tree

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,149 @@
1+
using Amazon.S3.Model;
2+
using Amazon.S3;
3+
using Moq;
4+
using System.Text;
5+
using Amazon;
6+
using FlowSynx.Plugins.Amazon.S3.Extensions;
7+
8+
namespace FlowSynx.Plugins.Amazon.S3.UnitTests.Extensions;
9+
10+
public class ConverterExtensionsTests
11+
{
12+
[Fact]
13+
public async Task ToContext_TextFile_ReturnsContent()
14+
{
15+
// Arrange
16+
var bucketName = "test-bucket";
17+
var key = "text-file.txt";
18+
var textContent = "Hello, this is a test!";
19+
var contentBytes = Encoding.UTF8.GetBytes(textContent);
20+
21+
var mockClient = new Mock<AmazonS3Client>("accessKey", "secretKey", RegionEndpoint.USEast1);
22+
var mockResponseStream = new MemoryStream(contentBytes);
23+
24+
var mockGetObjectResponse = new GetObjectResponse
25+
{
26+
BucketName = bucketName,
27+
Key = key,
28+
ResponseStream = mockResponseStream,
29+
ContentLength = contentBytes.Length,
30+
LastModified = DateTime.UtcNow,
31+
ETag = "\"etagvalue\"",
32+
StorageClass = S3StorageClass.Standard
33+
};
34+
35+
mockClient.Setup(c => c.GetObjectAsync(
36+
It.Is<GetObjectRequest>(r => r.BucketName == bucketName && r.Key == key),
37+
It.IsAny<CancellationToken>()
38+
))
39+
.ReturnsAsync(mockGetObjectResponse);
40+
41+
mockClient.Setup(c => c.GetObjectMetadataAsync(
42+
bucketName,
43+
key,
44+
It.IsAny<CancellationToken>()
45+
))
46+
.ReturnsAsync(new GetObjectMetadataResponse
47+
{
48+
Headers = { ContentType = "text/plain" },
49+
});
50+
51+
// Act
52+
var result = await mockClient.Object.ToContext(bucketName, key, includeMetadata: true, CancellationToken.None);
53+
54+
// Assert
55+
Assert.Equal(key, result.Id);
56+
Assert.Equal("File", result.SourceType);
57+
Assert.Null(result.RawData);
58+
Assert.Equal(textContent, result.Content);
59+
Assert.Equal("text/plain", result.Format);
60+
}
61+
62+
[Fact]
63+
public async Task ToContext_BinaryFile_ReturnsRawData()
64+
{
65+
// Arrange
66+
var bucketName = "test-bucket";
67+
var key = "binary.dat";
68+
var binaryData = new byte[] { 0x00, 0xFF, 0x10, 0x20, 0x30, 0x40 };
69+
70+
var mockClient = new Mock<AmazonS3Client>("accessKey", "secretKey", RegionEndpoint.USEast1);
71+
var mockResponseStream = new MemoryStream(binaryData);
72+
73+
var mockGetObjectResponse = new GetObjectResponse
74+
{
75+
BucketName = bucketName,
76+
Key = key,
77+
ResponseStream = mockResponseStream,
78+
ContentLength = binaryData.Length,
79+
LastModified = DateTime.UtcNow,
80+
ETag = "\"etagvalue\"",
81+
StorageClass = S3StorageClass.Standard
82+
};
83+
84+
mockClient.Setup(c => c.GetObjectAsync(
85+
It.Is<GetObjectRequest>(r => r.BucketName == bucketName && r.Key == key),
86+
It.IsAny<CancellationToken>()
87+
))
88+
.ReturnsAsync(mockGetObjectResponse);
89+
90+
mockClient.Setup(c => c.GetObjectMetadataAsync(
91+
bucketName,
92+
key,
93+
It.IsAny<CancellationToken>()
94+
))
95+
.ReturnsAsync(new GetObjectMetadataResponse
96+
{
97+
Headers = { ContentType = "application/octet-stream" }
98+
});
99+
100+
// Act
101+
var result = await mockClient.Object.ToContext(bucketName, key, includeMetadata: true, CancellationToken.None);
102+
103+
// Assert
104+
Assert.Equal(key, result.Id);
105+
Assert.Equal("File", result.SourceType);
106+
Assert.NotNull(result.RawData);
107+
Assert.Null(result.Content);
108+
Assert.Equal("application/octet-stream", result.Format);
109+
}
110+
111+
[Fact]
112+
public async Task ToContext_WithoutMetadata_DoesNotAddMetadata()
113+
{
114+
// Arrange
115+
var bucketName = "test-bucket";
116+
var key = "file.txt";
117+
var contentBytes = Encoding.UTF8.GetBytes("Some content");
118+
119+
var mockClient = new Mock<AmazonS3Client>("accessKey", "secretKey", RegionEndpoint.USEast1);
120+
var mockResponseStream = new MemoryStream(contentBytes);
121+
122+
var mockGetObjectResponse = new GetObjectResponse
123+
{
124+
BucketName = bucketName,
125+
Key = key,
126+
ResponseStream = mockResponseStream,
127+
ContentLength = contentBytes.Length,
128+
LastModified = DateTime.UtcNow,
129+
ETag = "\"etagvalue\"",
130+
StorageClass = S3StorageClass.Standard
131+
};
132+
133+
mockClient.Setup(c => c.GetObjectAsync(
134+
It.Is<GetObjectRequest>(r => r.BucketName == bucketName && r.Key == key),
135+
It.IsAny<CancellationToken>()
136+
))
137+
.ReturnsAsync(mockGetObjectResponse);
138+
139+
// Act
140+
var result = await mockClient.Object.ToContext(bucketName, key, includeMetadata: false, CancellationToken.None);
141+
142+
// Assert
143+
Assert.Equal(key, result.Id);
144+
Assert.Equal("File", result.SourceType);
145+
Assert.Null(result.RawData);
146+
Assert.NotNull(result.Content);
147+
Assert.Empty(result.Metadata); // Metadata should be empty
148+
}
149+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
using System.Text;
2+
using FlowSynx.Plugins.Amazon.S3.Extensions;
3+
4+
namespace FlowSynx.Plugins.Amazon.S3.UnitTests.Extensions;
5+
6+
public class StringExtensionsTests
7+
{
8+
[Theory]
9+
[InlineData("SGVsbG8gV29ybGQ=", true)] // "Hello World"
10+
[InlineData("U29tZSBkYXRhIHdpdGggcGFkZGluZw==", true)]
11+
[InlineData("", false)]
12+
[InlineData("NotBase64!!", false)]
13+
[InlineData("SGVsbG8gV29ybGQ", false)] // Invalid length (not divisible by 4)
14+
[InlineData("SG VsbG8=", false)] // Contains space
15+
[InlineData("SG\tVsbG8=", false)] // Contains tab
16+
[InlineData("SG\rVsbG8=", false)] // Contains carriage return
17+
[InlineData("SG\nVsbG8=", false)] // Contains line feed
18+
[InlineData("SGVsbG8=", true)] // Valid short base64
19+
[InlineData("c3RyaW5nLXdpdGgtc3ltYm9sLXMh", true)] // includes "-" and "!" -> not valid base64
20+
public void IsBase64String_Should_ReturnExpectedResult(string input, bool expected)
21+
{
22+
var result = input.IsBase64String();
23+
Assert.Equal(expected, result);
24+
}
25+
26+
[Fact]
27+
public void ToByteArray_Should_ConvertCorrectly()
28+
{
29+
var input = "Hello World!";
30+
var expected = Encoding.UTF8.GetBytes(input);
31+
32+
var result = input.ToByteArray();
33+
34+
Assert.Equal(expected, result);
35+
}
36+
37+
[Fact]
38+
public void Base64ToByteArray_Should_DecodeCorrectly()
39+
{
40+
var original = "TestString";
41+
var base64 = Convert.ToBase64String(Encoding.UTF8.GetBytes(original));
42+
43+
var result = base64.Base64ToByteArray();
44+
45+
Assert.Equal(original, Encoding.UTF8.GetString(result));
46+
}
47+
48+
[Fact]
49+
public void Base64ToByteArray_InvalidInput_ShouldThrowFormatException()
50+
{
51+
var invalidBase64 = "ThisIsNotBase64!!";
52+
53+
Assert.Throws<FormatException>(() => invalidBase64.Base64ToByteArray());
54+
}
55+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net9.0</TargetFramework>
5+
<ImplicitUsings>enable</ImplicitUsings>
6+
<Nullable>enable</Nullable>
7+
<IsPackable>false</IsPackable>
8+
</PropertyGroup>
9+
10+
<ItemGroup>
11+
<PackageReference Include="coverlet.collector" Version="6.0.2" />
12+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
13+
<PackageReference Include="Moq" Version="4.20.72" />
14+
<PackageReference Include="xunit" Version="2.9.2" />
15+
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2" />
16+
</ItemGroup>
17+
18+
<ItemGroup>
19+
<ProjectReference Include="..\..\src\FlowSynx.Plugins.Amazon.S3.csproj" />
20+
</ItemGroup>
21+
22+
<ItemGroup>
23+
<Using Include="Xunit" />
24+
</ItemGroup>
25+
26+
</Project>
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
namespace FlowSynx.Plugins.Amazon.S3.UnitTests;
2+
3+
public class PathHelperTests
4+
{
5+
[Fact]
6+
public void IsDirectory_ShouldReturnTrue_WhenEndsWithSlash()
7+
{
8+
Assert.True(PathHelper.IsDirectory("folder/"));
9+
}
10+
11+
[Fact]
12+
public void IsDirectory_ShouldReturnFalse_WhenNotEndsWithSlash()
13+
{
14+
Assert.False(PathHelper.IsDirectory("file.txt"));
15+
}
16+
17+
[Fact]
18+
public void IsFile_ShouldReturnTrue_WhenNotEndsWithSlash()
19+
{
20+
Assert.True(PathHelper.IsFile("file.txt"));
21+
}
22+
23+
[Fact]
24+
public void IsFile_ShouldReturnFalse_WhenEndsWithSlash()
25+
{
26+
Assert.False(PathHelper.IsFile("folder/"));
27+
}
28+
29+
[Fact]
30+
public void AddTrailingPathSeparator_ShouldAdd_WhenNotPresent()
31+
{
32+
Assert.Equal("folder/", PathHelper.AddTrailingPathSeparator("folder"));
33+
}
34+
35+
[Fact]
36+
public void AddTrailingPathSeparator_ShouldNotAdd_WhenAlreadyPresent()
37+
{
38+
Assert.Equal("folder/", PathHelper.AddTrailingPathSeparator("folder/"));
39+
}
40+
41+
[Fact]
42+
public void AddPathSeparator_ShouldInsertAtIndex_WhenMissing()
43+
{
44+
Assert.Equal("folder/", PathHelper.AddPathSeparator("folder", 6));
45+
}
46+
47+
[Fact]
48+
public void AddPathSeparator_ShouldDoNothing_WhenAlreadyEndsWithSeparator()
49+
{
50+
Assert.Equal("folder/", PathHelper.AddPathSeparator("folder/", 7));
51+
}
52+
53+
[Fact]
54+
public void Combine_ShouldJoinParts_Correctly()
55+
{
56+
var combined = PathHelper.Combine("folder", "subfolder", "file.txt");
57+
Assert.Equal("folder/subfolder/file.txt", combined);
58+
}
59+
60+
[Fact]
61+
public void Combine_ShouldHandleNulls_AndEmptyStrings()
62+
{
63+
var combined = PathHelper.Combine("folder", null, "", "file.txt");
64+
Assert.Equal("folder/file.txt", combined);
65+
}
66+
67+
[Theory]
68+
[InlineData("folder/subfolder/file.txt", "folder/subfolder/")]
69+
[InlineData("file.txt", "/")]
70+
[InlineData("/", "")]
71+
[InlineData("", "")]
72+
public void GetParent_ShouldReturnCorrectParent(string input, string expected)
73+
{
74+
Assert.Equal(expected, PathHelper.GetParent(input));
75+
}
76+
77+
[Theory]
78+
[InlineData("folder/../subfolder", "subfolder")]
79+
[InlineData("a/b/../c", "a/c")]
80+
[InlineData(null, "/")]
81+
[InlineData("", "/")]
82+
public void Normalize_ShouldResolvePathsCorrectly(string input, string expected)
83+
{
84+
Assert.Equal(expected, PathHelper.Normalize(input));
85+
}
86+
87+
[Fact]
88+
public void NormalizePart_ShouldTrimSlashes()
89+
{
90+
Assert.Equal("folder", PathHelper.NormalizePart("/folder/"));
91+
}
92+
93+
[Fact]
94+
public void NormalizePart_ShouldThrow_WhenNull()
95+
{
96+
Assert.Throws<ArgumentNullException>(() => PathHelper.NormalizePart(null));
97+
}
98+
99+
[Fact]
100+
public void Split_ShouldReturnParts()
101+
{
102+
var result = PathHelper.Split("/a/b/c/");
103+
Assert.Equal(new[] { "a", "b", "c" }, result);
104+
}
105+
106+
[Fact]
107+
public void Split_ShouldReturnEmptyArray_WhenNullOrEmpty()
108+
{
109+
Assert.Empty(PathHelper.Split(null));
110+
Assert.Empty(PathHelper.Split(""));
111+
}
112+
113+
[Theory]
114+
[InlineData(null, true)]
115+
[InlineData("", true)]
116+
[InlineData("/", true)]
117+
[InlineData("folder", false)]
118+
public void IsRootPath_ShouldIdentifyRootCorrectly(string input, bool expected)
119+
{
120+
Assert.Equal(expected, PathHelper.IsRootPath(input));
121+
}
122+
123+
[Theory]
124+
[InlineData("folder/../file.txt", "file.txt", true)]
125+
[InlineData("folder/file.txt", "folder/file.txt", true)]
126+
[InlineData("folder/file.txt", "folder2/file.txt", false)]
127+
public void ComparePath_ShouldReturnTrueForEquivalentPaths(string p1, string p2, bool expected)
128+
{
129+
Assert.Equal(expected, PathHelper.ComparePath(p1, p2));
130+
}
131+
132+
[Theory]
133+
[InlineData(null, "")]
134+
[InlineData(@"folder\subfolder\file.txt", "folder/subfolder/file.txt")]
135+
public void ToUnixPath_ShouldConvertBackslashesToForwardSlashes(string input, string expected)
136+
{
137+
Assert.Equal(expected, PathHelper.ToUnixPath(input));
138+
}
139+
}

0 commit comments

Comments
 (0)