Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
185 changes: 185 additions & 0 deletions CapMonsterCloud.Client.IntegrationTests/IntegrationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -824,7 +824,7 @@
}

[Test]
public async Task RecaptchaV2_IncorrectProxyPort_ShouldThrowArgumentException()

Check warning on line 827 in CapMonsterCloud.Client.IntegrationTests/IntegrationTests.cs

View workflow job for this annotation

GitHub Actions / build

This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread.
{
Action actual = () => ObjectGen.RecaptchaV2.CreateTask(
proxyPort: Gen.RandomInt(65535));
Expand Down Expand Up @@ -1249,5 +1249,190 @@
sut.GetActualRequests().Should().BeEquivalentTo(expectedRequests);
actual.Should().BeEquivalentTo(expectedResult);
}

[Test]
public async Task Altcha_ShouldSolve()
{
var clientKey = Gen.RandomString();
var taskId = Gen.RandomInt();

var captchaRequest = ObjectGen.CustomTask.CreateAltchaTask();
var expectedResult = ObjectGen.CustomTask.CreateAltchaSolution();

var expectedRequests = new List<(RequestType Type, string ExpectedRequest)>
{
(
Type: RequestType.CreateTask,
ExpectedRequest: JsonConvert.SerializeObject(new
{ clientKey = clientKey, task = captchaRequest, softId = 53 })
),
(
Type: RequestType.GetTaskResult,
ExpectedRequest: JsonConvert.SerializeObject(new { clientKey = clientKey, taskId = taskId })
),
};

var captchaResults = new List<object>
{
new { taskId = taskId, errorId = 0, errorCode = (string)null! },
new
{
status = "ready",
solution = new
{
data = expectedResult.Solution.Data
},
errorId = 0,
errorCode = (string)null!
}
};

var sut = new Sut(clientKey);
sut.SetupHttpServer(captchaResults);

var actual = await sut.SolveAsync(captchaRequest);

sut.GetActualRequests().Should().BeEquivalentTo(expectedRequests);
actual.Should().BeEquivalentTo(expectedResult);
}

[Test]
public async Task Castle_ShouldSolve()
{
var clientKey = Gen.RandomString();
var taskId = Gen.RandomInt();

var captchaRequest = ObjectGen.CustomTask.CreateCastleTask();
var expectedResult = ObjectGen.CustomTask.CreateCastleSolution();

var expectedRequests = new List<(RequestType Type, string ExpectedRequest)>
{
(
Type: RequestType.CreateTask,
ExpectedRequest: JsonConvert.SerializeObject(new
{ clientKey = clientKey, task = captchaRequest, softId = 53 })
),
(
Type: RequestType.GetTaskResult,
ExpectedRequest: JsonConvert.SerializeObject(new { clientKey = clientKey, taskId = taskId })
),
};

var captchaResults = new List<object>
{
new { taskId = taskId, errorId = 0, errorCode = (string)null! },
new
{
status = "ready",
solution = new
{
data = expectedResult.Solution.Data,
domains = expectedResult.Solution.Domains
},
errorId = 0,
errorCode = (string)null!
}
};

var sut = new Sut(clientKey);
sut.SetupHttpServer(captchaResults);

var actual = await sut.SolveAsync(captchaRequest);

sut.GetActualRequests().Should().BeEquivalentTo(expectedRequests);
actual.Should().BeEquivalentTo(expectedResult);
}

[Test]
public async Task Tspd_ShouldSolve()
{
var clientKey = Gen.RandomString();
var taskId = Gen.RandomInt();

var captchaRequest = ObjectGen.CustomTask.CreateTspdTask();
var expectedResult = ObjectGen.CustomTask.CreateTspdSolution();

var expectedRequests = new List<(RequestType Type, string ExpectedRequest)>
{
(
Type: RequestType.CreateTask,
ExpectedRequest: JsonConvert.SerializeObject(new
{ clientKey = clientKey, task = captchaRequest, softId = 53 })
),
(
Type: RequestType.GetTaskResult,
ExpectedRequest: JsonConvert.SerializeObject(new { clientKey = clientKey, taskId = taskId })
),
};

var captchaResults = new List<object>
{
new { taskId = taskId, errorId = 0, errorCode = (string)null! },
new
{
status = "ready",
solution = new
{
domains = expectedResult.Solution.Domains
},
errorId = 0,
errorCode = (string)null!
}
};

var sut = new Sut(clientKey);
sut.SetupHttpServer(captchaResults);

var actual = await sut.SolveAsync(captchaRequest);

sut.GetActualRequests().Should().BeEquivalentTo(expectedRequests);
actual.Should().BeEquivalentTo(expectedResult);
}

[Test]
public async Task Hunt_ShouldSolve()
{
var clientKey = Gen.RandomString();
var taskId = Gen.RandomInt();

var captchaRequest = ObjectGen.CustomTask.CreateHuntTask();
var expectedResult = ObjectGen.CustomTask.CreateHuntSolution();

var expectedRequests = new List<(RequestType Type, string ExpectedRequest)>
{
(
Type: RequestType.CreateTask,
ExpectedRequest: JsonConvert.SerializeObject(new
{ clientKey = clientKey, task = captchaRequest, softId = 53 })
),
(
Type: RequestType.GetTaskResult,
ExpectedRequest: JsonConvert.SerializeObject(new { clientKey = clientKey, taskId = taskId })
),
};

var captchaResults = new List<object>
{
new { taskId = taskId, errorId = 0, errorCode = (string)null! },
new
{
status = "ready",
solution = new
{
data = expectedResult.Solution.Data
},
errorId = 0,
errorCode = (string)null!
}
};

var sut = new Sut(clientKey);
sut.SetupHttpServer(captchaResults);

var actual = await sut.SolveAsync(captchaRequest);

sut.GetActualRequests().Should().BeEquivalentTo(expectedRequests);
actual.Should().BeEquivalentTo(expectedResult);
}
}
}
127 changes: 127 additions & 0 deletions CapMonsterCloud.Client.IntegrationTests/ObjectGen.cs
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,133 @@ public static CaptchaResult<CustomTaskResponse> CreateImpervaSolution()
}
};
}

public static AltchaCustomTaskRequest CreateAltchaTask()
{
return new AltchaCustomTaskRequest(Gen.RandomString(), Gen.RandomString(), Gen.RandomString(), Gen.RandomString())
{
WebsiteKey = Gen.RandomGuid(),
WebsiteUrl = Gen.RandomUri().ToString(),
UserAgent = Gen.UserAgent(),
Proxy = new ProxyContainer(Gen.RandomString(), Gen.RandomInt(0, 65535), Gen.RandomEnum<ProxyType>(), Gen.RandomString(), Gen.RandomString())
};
}

public static CaptchaResult<CustomTaskResponse> CreateAltchaSolution()
{
return new CaptchaResult<CustomTaskResponse>
{
Error = null,
Solution = new CustomTaskResponse
{
Data = new Dictionary<string, string>
{
{ "token", Gen.RandomString() } ,
{ "number", Gen.RandomInt().ToString() }
}
}
};
}

public static CastleCustomTaskRequest CreateCastleTask()
{
return new CastleCustomTaskRequest(Gen.RandomUri().ToString(), Gen.RandomUri().ToString(), Gen.RandomInt(1, 49))
{
WebsiteKey = Gen.RandomGuid(),
WebsiteUrl = Gen.RandomUri().ToString(),
UserAgent = Gen.UserAgent(),
Proxy = new ProxyContainer(Gen.RandomString(), Gen.RandomInt(0, 65535), Gen.RandomEnum<ProxyType>(), Gen.RandomString(), Gen.RandomString())
};
}

public static CaptchaResult<CustomTaskResponse> CreateCastleSolution()
{
return new CaptchaResult<CustomTaskResponse>
{
Error = null,
Solution = new CustomTaskResponse
{
Domains = new Dictionary<string, CustomTaskResponse.DomainInfo>
{
{
Gen.RandomString(),
new CustomTaskResponse.DomainInfo()
{
Cookies = new Dictionary<string, string> { { "__cuid", Gen.RandomGuid() } }
}
}
},
Data = new Dictionary<string, string>
{
{ "tokens", Gen.RandomString() }
}
}
};
}

public static TspdCustomTaskRequest CreateTspdTask()
{
return new TspdCustomTaskRequest(Gen.RandomString(), Gen.RandomString())
{
WebsiteUrl = Gen.RandomUri().ToString(),
UserAgent = Gen.UserAgent(),
Proxy = new ProxyContainer(Gen.RandomString(), Gen.RandomInt(0, 65535), Gen.RandomEnum<ProxyType>(), Gen.RandomString(), Gen.RandomString())
};
}

public static CaptchaResult<CustomTaskResponse> CreateTspdSolution()
{
return new CaptchaResult<CustomTaskResponse>
{
Error = null,
Solution = new CustomTaskResponse
{
Domains = new Dictionary<string, CustomTaskResponse.DomainInfo>
{
{
Gen.RandomString(),
new CustomTaskResponse.DomainInfo()
{
Cookies = new Dictionary<string, string>
{
{ "TS386a400d029", Gen.RandomString() },
{ "TS386a400d078", Gen.RandomString() },
{ "TSd2153684027", Gen.RandomString() },
{ "TS00000000076", Gen.RandomString() },
{ "TSPD_101_DID", Gen.RandomString() },
{ "TS386a400d075", Gen.RandomString() }
}
}
}
}
}
};
}

public static HuntCustomTaskRequest CreateHuntTask()
{
return new HuntCustomTaskRequest(Gen.RandomUri().ToString(), Gen.RandomString())
{
WebsiteUrl = Gen.RandomUri().ToString(),
UserAgent = Gen.UserAgent(),
Proxy = new ProxyContainer(Gen.RandomString(), Gen.RandomInt(0, 65535), Gen.RandomEnum<ProxyType>(), Gen.RandomString(), Gen.RandomString())
};
}

public static CaptchaResult<CustomTaskResponse> CreateHuntSolution()
{
return new CaptchaResult<CustomTaskResponse>
{
Error = null,
Solution = new CustomTaskResponse
{
Data = new Dictionary<string, string>
{
{ "token", Gen.RandomString() }
}
}
};
}
}

public static class AmazonWaf
Expand Down
12 changes: 12 additions & 0 deletions CapMonsterCloud.Client.IntegrationTests/Sut.cs
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,18 @@ public async Task<CaptchaResult<MTCaptchaTaskResponse>> SolveAsync(
public async Task<CaptchaResult<YidunTaskResponse>> SolveAsync(
YidunTaskRequest request) => await _cloudClient.SolveAsync<YidunTaskResponse>(request);

public async Task<CaptchaResult<CustomTaskResponse>> SolveAsync(
AltchaCustomTaskRequest request) => await _cloudClient.SolveAsync<CustomTaskResponse>(request);

public async Task<CaptchaResult<CustomTaskResponse>> SolveAsync(
CastleCustomTaskRequest request) => await _cloudClient.SolveAsync<CustomTaskResponse>(request);

public async Task<CaptchaResult<CustomTaskResponse>> SolveAsync(
TspdCustomTaskRequest request) => await _cloudClient.SolveAsync<CustomTaskResponse>(request);

public async Task<CaptchaResult<CustomTaskResponse>> SolveAsync(
HuntCustomTaskRequest request) => await _cloudClient.SolveAsync<CustomTaskResponse>(request);

public async Task<decimal> GetBalanceAsync()
{
return await _cloudClient.GetBalanceAsync();
Expand Down
4 changes: 2 additions & 2 deletions CapMonsterCloud.Client/CapMonsterCloud.Client.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
<PackageReadmeFile>README.md</PackageReadmeFile>
<PackageIcon>logo.png</PackageIcon>
<RepositoryUrl>https://github.com/ZennoLab/capmonstercloud-client-dotnet</RepositoryUrl>
<Version>3.1.0</Version>
<PackageReleaseNotes>Add Yidun, Temu, Prosopo, MTCaptcha solving support</PackageReleaseNotes>
<Version>3.2.0</Version>
<PackageReleaseNotes>Add Altcha, Castle, Tspd, Hunt solving support</PackageReleaseNotes>
</PropertyGroup>

<ItemGroup>
Expand Down
36 changes: 36 additions & 0 deletions CapMonsterCloud.Client/CapMonsterCloudClient_GetResultTimeouts.cs
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,42 @@ private static GetResultTimeouts GetTimeouts(Type type)
Timeout = TimeSpan.FromSeconds(180)
}
},
{
typeof(AltchaCustomTaskRequest),
new GetResultTimeouts
{
FirstRequestDelay = TimeSpan.FromSeconds(1),
RequestsInterval = TimeSpan.FromSeconds(2),
Timeout = TimeSpan.FromSeconds(50)
}
},
{
typeof(CastleCustomTaskRequest),
new GetResultTimeouts
{
FirstRequestDelay = TimeSpan.FromSeconds(1),
RequestsInterval = TimeSpan.FromSeconds(2),
Timeout = TimeSpan.FromSeconds(60)
}
},
{
typeof(TspdCustomTaskRequest),
new GetResultTimeouts
{
FirstRequestDelay = TimeSpan.FromSeconds(1),
RequestsInterval = TimeSpan.FromSeconds(2),
Timeout = TimeSpan.FromSeconds(60)
}
},
{
typeof(HuntCustomTaskRequest),
new GetResultTimeouts
{
FirstRequestDelay = TimeSpan.FromSeconds(1),
RequestsInterval = TimeSpan.FromSeconds(3),
Timeout = TimeSpan.FromSeconds(180)
}
},
};
}
}
Loading
Loading