├── .github ├── ISSUE_TEMPLATE.md └── PULL_REQUEST_TEMPLATE.md ├── .gitignore ├── .nuget ├── NuGet.Config ├── NuGet.exe └── NuGet.targets ├── .travis.yml ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── CONTRIBUTORS.md ├── FluentTc.Samples ├── App.config ├── FluentTc.Samples.csproj ├── Program.cs ├── Properties │ └── AssemblyInfo.cs └── packages.config ├── FluentTc.Tests ├── AcceptanceTests.cs ├── AgentsRetrieverTests.cs ├── BootstrapperTests.cs ├── BuildsRetrieverTests.cs ├── ConnectedTcTests.cs ├── Domain │ └── BuildTests.cs ├── Engine │ ├── BuildConfigurationRetrieverTests.cs │ ├── BuildConfigurationTemplateRetrieverTests.cs │ ├── BuildModelToBuildConverterTests.cs │ ├── BuildParametersTests.cs │ ├── BuildQueueRemoverTests.cs │ ├── BuildStatisticConverterTests.cs │ ├── BuildStatisticsRetrieverTests.cs │ ├── ChangedFilesParserTests.cs │ ├── ChangesRetrieverTests.cs │ ├── ModelFiltersTest.cs │ ├── NewProjectDetailsBuilderTests.cs │ ├── ProjectsRetrieverTests.cs │ ├── PropertiesFileParserTests.cs │ └── UniversalTypeConverterTests.cs ├── Extensions │ └── StringExtensionsTests.cs ├── FluentTc.Tests.csproj ├── LocalTcTests.cs ├── Locators │ ├── AgentHavingBuilderTests.cs │ ├── Auto.cs │ ├── BranchHavingBuilderFactoryTests.cs │ ├── BranchHavingBuilderTests.cs │ ├── BuildAdditionalIncludeBuilderTests.cs │ ├── BuildConfigurationHavingBuilderTests.cs │ ├── BuildHavingBuilderTests.cs │ ├── BuildIncludeBuilderTests.cs │ ├── BuildParameterTypeBuilderFormatTests.cs │ ├── BuildProjectHavingBuilderTests.cs │ ├── BuildQueueIdHavingBuilderTests.cs │ ├── ChangesHavingBuilderTests.cs │ ├── ChangesIncludeBuilderTests.cs │ ├── CountBuilderTests.cs │ ├── GitVCSRootBuilderTests.cs │ ├── QueueHavingBuilderTests.cs │ ├── TeamCityConfigurationBuilderTests.cs │ ├── UserHavingBuilderTests.cs │ └── VCSRootEntryBuilderTests.cs ├── Properties │ └── AssemblyInfo.cs ├── RemoteTcTests.cs ├── Resources │ └── PropertiesFile.txt ├── TestingTools │ └── EmbeddedResourceReader.cs ├── app.config └── packages.config ├── FluentTc.ndproj ├── FluentTc.sln ├── FluentTc.sln.DotSettings ├── FluentTc ├── Bootstrapper.cs ├── ConnectedTc.cs ├── Domain │ ├── Agent.cs │ ├── AgentPool.cs │ ├── AgentRequirement.cs │ ├── AgentRequirements.cs │ ├── AgentWrapper.cs │ ├── ArtifactDependencies.cs │ ├── ArtifactDependency.cs │ ├── Assignment.cs │ ├── Build.cs │ ├── BuildConfiguration.cs │ ├── BuildModel.cs │ ├── BuildStatisticsModel.cs │ ├── BuildStep.cs │ ├── BuildSteps.cs │ ├── BuildTrigger.cs │ ├── BuildTriggers.cs │ ├── BuildTypeWrapper.cs │ ├── BuildWrapper.cs │ ├── Change.cs │ ├── ChangedFile.cs │ ├── ChangesList.cs │ ├── ChangesWrapper.cs │ ├── File.cs │ ├── FileWrapper.cs │ ├── Group.cs │ ├── IBuildStatistic.cs │ ├── Investigation.cs │ ├── InvestigationWrapper.cs │ ├── Parameters.cs │ ├── Project.cs │ ├── ProjectWrapper.cs │ ├── Properties.cs │ ├── Property.cs │ ├── PropertyType.cs │ ├── ResolutionWrapper.cs │ ├── RevisionsList.cs │ ├── RevisionsWrapper.cs │ ├── Role.cs │ ├── RoleWrapper.cs │ ├── SnapshotDependencies.cs │ ├── SnapshotDependency.cs │ ├── SourceBuildType.cs │ ├── Test.cs │ ├── TestOccurrence.cs │ ├── TestOccurrenceWrapper.cs │ ├── TestOccurrences.cs │ ├── User.cs │ ├── UserGroupWrapper.cs │ ├── UserWrapper.cs │ ├── VcsRoot.cs │ ├── VcsRootEntries.cs │ └── VcsRootEntry.cs ├── Engine │ ├── AgentEnabler.cs │ ├── AgentHavingBuilderFactory.cs │ ├── AgentsRetriever.cs │ ├── ArtifactsDownloader.cs │ ├── BuildConfigurationCreator.cs │ ├── BuildConfigurationRetriever.cs │ ├── BuildConfigurationRunner.cs │ ├── BuildConfigurationTemplateRetriever.cs │ ├── BuildIncludeBuilderFactory.cs │ ├── BuildModelToBuildConverter.cs │ ├── BuildParameters.cs │ ├── BuildQueueIdHavingBuilderFactory.cs │ ├── BuildQueueRemover.cs │ ├── BuildStatisticConverter.cs │ ├── BuildStatisticsRetriever.cs │ ├── BuildTemplateAttacher.cs │ ├── BuildsRetriever.cs │ ├── ChangedFilesParser.cs │ ├── ChangesRetriever.cs │ ├── CountBuilderFactory.cs │ ├── HttpClientWrapper.cs │ ├── HttpClientWrapperFactory.cs │ ├── IBuildParameterHavingBuilder.cs │ ├── NewProjectDetailsBuilder.cs │ ├── ProjectCreator.cs │ ├── ProjectPropertySetter.cs │ ├── ProjectsRetriever.cs │ ├── PropertiesFileParser.cs │ ├── QueueHavingBuilderFactory.cs │ ├── TeamCityBuildPropertiesFileRetriever.cs │ ├── TeamCityCaller.cs │ ├── TeamCityDateFilter.cs │ ├── TeamCityWriterFactory.cs │ ├── TeamcityJsonEncoderDecoderConfiguration.cs │ ├── UniversalTypeConverter.cs │ ├── UserRetriever.cs │ ├── VCSRootAttacher.cs │ ├── VCSRootCreator.cs │ └── ZipExtractor.cs ├── Exceptions │ ├── AgentNotFoundException.cs │ ├── BuildConfigurationNotFoundException.cs │ ├── BuildNotFoundException.cs │ ├── MissingBuildParameterException.cs │ ├── MoreThanOneAgentFoundException.cs │ ├── MoreThanOneBuildConfigurationFoundException.cs │ └── MoreThanOneBuildFoundException.cs ├── Extensions │ └── StringExtensions.cs ├── FluentTc.csproj ├── FluentTc.nuspec ├── InvestigationRetriever.cs ├── LocalTc.cs ├── Locators │ ├── AgentHavingBuilder.cs │ ├── BranchHavingBuilder.cs │ ├── BranchHavingBuilderFactory.cs │ ├── BuildAdditionalIncludeBuilder.cs │ ├── BuildConfigurationHavingBuilder.cs │ ├── BuildConfigurationHavingBuilderFactory.cs │ ├── BuildConfigurationTemplateHavingBuilder.cs │ ├── BuildFieldValueBuilder.cs │ ├── BuildHavingBuilder.cs │ ├── BuildHavingBuilderFactory.cs │ ├── BuildIncludeBuilder.cs │ ├── BuildParameterCheckboxTypeBuilder.cs │ ├── BuildParameterSelectListTypeBuilder.cs │ ├── BuildParameterTextTypeBuilder.cs │ ├── BuildParameterTypeBuilder.cs │ ├── BuildParameterValueBuilder.cs │ ├── BuildParametersBuilder.cs │ ├── BuildProjectFieldValueBuilder.cs │ ├── BuildProjectHavingBuilder.cs │ ├── BuildProjectHavingBuilderFactory.cs │ ├── BuildQueueIdHavingBuilder.cs │ ├── BuildState.cs │ ├── BuildStatus.cs │ ├── ChangesHavingBuilder.cs │ ├── ChangesIncludeBuilder.cs │ ├── CountBuilder.cs │ ├── GitVCSRootBuilder.cs │ ├── LocatorBuilder.cs │ ├── MoreOptionsHavingBuilder.cs │ ├── OnChangeHavingBuilder.cs │ ├── QueueHavingBuilder.cs │ ├── TeamCityConfigurationBuilder.cs │ ├── TeamCityConnectionDetails.cs │ ├── UserHavingBuilder.cs │ ├── UserHavingBuilderFactory.cs │ └── VCSRootEntryBuilder.cs ├── Properties │ └── AssemblyInfo.cs ├── RemoteTc.cs └── packages.config ├── LICENSE ├── Quali-Shells-Open-Source.rtf └── README.md /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ### Bug/Feature Request 2 | _Remove the unnecessary and provide detailed description_ 3 | 4 | ### Test to reproduce 5 | ```C# 6 | _Please provide necessary steps for reproduction of this issue_. 7 | [Test] 8 | public void Test_To_Reproduce_The_Issue() 9 | { 10 | } 11 | ``` 12 | 13 | ### Affected versions 14 | 15 | Product | Version 16 | --------|-------- 17 | FluentTc | 18 | TeamCity | 19 | Autofac | 20 | EasyHttp | 21 | SharpZipLib | 22 | System.IO.Abstractions | 23 | TeamCity.ServiceMessages | 24 | 25 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ### Issue details 2 | 3 | _Please provide issue details here_. 4 | 5 | ### Relates to issue 6 | _Use close #XX or connect #XX in order to resolve or link an issue_ 7 | 8 | ### Checklist 9 | - [ ] All unit tests passed on build server 10 | - [ ] Acceptance test(s) covers new/modified functionality 11 | - [ ] Code coverage is at least the same or higher 12 | - [ ] Breaking change in public API 13 | 14 | # Example of using new/modified functionality 15 | 16 | ```C# 17 | // _Please provide necessary steps for reproduction of this issue_. 18 | [Test] 19 | public void Test_To_Reproduce_The_Issue() 20 | { 21 | } 22 | ``` 23 | -------------------------------------------------------------------------------- /.nuget/NuGet.Config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /.nuget/NuGet.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QualiSystems/FluentTc/612532dd7d87bb00e3b965f013f7d18e1ad61677/.nuget/NuGet.exe -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: csharp 2 | solution: FluentTc.sln 3 | 4 | install: 5 | - sudo apt-get install -y gtk-sharp2 6 | - nuget restore FluentTc.sln 7 | - nuget install NUnit.Runners -Version 2.6.4 -OutputDirectory testrunner 8 | 9 | script: 10 | - xbuild /p:Configuration=Release FluentTc.sln 11 | - mono ./testrunner/NUnit.Runners.2.6.4/tools/nunit-console.exe ./FluentTc.Tests/bin/Release/FluentTc.Tests.dll 12 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. 6 | 7 | ## Our Standards 8 | 9 | Examples of behavior that contributes to creating a positive environment include: 10 | 11 | * Using welcoming and inclusive language 12 | * Being respectful of differing viewpoints and experiences 13 | * Gracefully accepting constructive criticism 14 | * Focusing on what is best for the community 15 | * Showing empathy towards other community members 16 | 17 | Examples of unacceptable behavior by participants include: 18 | 19 | * The use of sexualized language or imagery and unwelcome sexual attention or advances 20 | * Trolling, insulting/derogatory comments, and personal or political attacks 21 | * Public or private harassment 22 | * Publishing others' private information, such as a physical or electronic address, without explicit permission 23 | * Other conduct which could reasonably be considered inappropriate in a professional setting 24 | 25 | ## Our Responsibilities 26 | 27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. 28 | 29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. 30 | 31 | ## Scope 32 | 33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. 34 | 35 | ## Enforcement 36 | 37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at borismod@gmail.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. 38 | 39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. 40 | 41 | ## Attribution 42 | 43 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version] 44 | 45 | [homepage]: http://contributor-covenant.org 46 | [version]: http://contributor-covenant.org/version/1/4/ 47 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | We love your input! We want to make contributing to this project as easy and transparent as possible, whether it's: 3 | 4 | - Reporting a bug 5 | - Discussing the current state of the code 6 | - Submitting a fix 7 | - Proposing new features 8 | - Becoming a maintainer 9 | 10 | ## We Develop with Github 11 | We use github to host code, to track issues and feature requests, as well as accept pull requests. 12 | 13 | ## We Use [Github Flow](https://guides.github.com/introduction/flow/index.html), So All Code Changes Happen Through Pull Requests 14 | Pull requests are the best way to propose changes to the codebase (we use [Github Flow](https://guides.github.com/introduction/flow/index.html)). We actively welcome your pull requests: 15 | 16 | 1. Fork the repo and create your branch from `master`. 17 | 2. If you've added code that should be tested, add tests. 18 | 3. If you've changed APIs, update the documentation. 19 | 4. Ensure the test suite passes. 20 | 5. Make sure your code lints. 21 | 6. Issue that pull request! 22 | 23 | ## Any contributions you make will be under the MIT Software License 24 | In short, when you submit code changes, your submissions are understood to be under the same [MIT License](http://choosealicense.com/licenses/mit/) that covers the project. Feel free to contact the maintainers if that's a concern. 25 | 26 | ## Report bugs using Github's [issues](https://github.com/QualiSystems/FluentTc/issues) 27 | We use GitHub issues to track public bugs. Report a bug by [opening a new issue](); it's that easy! 28 | 29 | ## Write bug reports with detail, background, and sample code 30 | [This is an example](http://stackoverflow.com/q/12488905/180626) of a bug report. Here's [another example from Craig Hockenberry](http://www.openradar.me/11905408), an app developer whom I greatly respect. 31 | 32 | **Great Bug Reports** tend to have: 33 | 34 | - A quick summary and/or background 35 | - Steps to reproduce 36 | - Be specific! 37 | - Give sample code if you can. 38 | - What you expected would happen 39 | - What actually happens 40 | - Notes (possibly including why you think this might be happening, or stuff you tried that didn't work) 41 | 42 | People *love* thorough bug reports. I'm not even kidding. 43 | 44 | ## Use a Consistent Coding Style 45 | 46 | -------------------------------------------------------------------------------- /CONTRIBUTORS.md: -------------------------------------------------------------------------------- 1 | # Contributors 2 | 3 | in order of contribution 4 | 5 | * Boris Modylevsky [@borismod](https://github.com/borismod) 6 | * Tomer Cohen [@TCDooM](https://github.com/TCDooM) 7 | * Igor Olikh [@igoro1975](https://github.com/igoro1975) 8 | * Derrick Wood [@asmoran](https://github.com/asmoran) 9 | * sokolovsv90 [@sokolovsv90](https://github.com/sokolovsv90) 10 | * Tomer Admon [@TomerAdmon](https://github.com/TomerAdmon) 11 | * Artem Kuznetsov [@nex-54](https://github.com/nex-54) 12 | * Stephen Brown [@evolvedlight](https://github.com/evolvedlight) 13 | * Tomas Bezouska [@bezysoftware](http://github.com/bezysoftware) 14 | * Pat Hermens [@phermens-coolblue](https://github.com/phermens-coolblue) 15 | * Daniel Dreibrodt [@3breadt](https://github.com/3breadt) 16 | * Polzoni Gilberto [@GibbOne](https://github.com/GibbOne) 17 | * Jakub Bartkowiak [@gralin](https://github.com/gralin) 18 | -------------------------------------------------------------------------------- /FluentTc.Samples/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /FluentTc.Samples/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("FluentTc.Samples")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("FluentTc.Samples")] 13 | [assembly: AssemblyCopyright("Copyright © 2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("dff815ed-32f7-417a-9005-93f246291921")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /FluentTc.Samples/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /FluentTc.Tests/BootstrapperTests.cs: -------------------------------------------------------------------------------- 1 | using FakeItEasy; 2 | using FluentAssertions; 3 | using FluentTc.Locators; 4 | using NUnit.Framework; 5 | 6 | namespace FluentTc.Tests 7 | { 8 | [TestFixture] 9 | public class BootstrapperTests 10 | { 11 | [Test] 12 | public void GetConnectedTc_FakeConnection_NotNull() 13 | { 14 | // Arrange 15 | var bootstrapper = new Bootstrapper(A.Fake()); 16 | 17 | // Act 18 | var connectedTc = bootstrapper.GetConnectedTc(); 19 | 20 | // Assert 21 | connectedTc.Should().NotBeNull(); 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /FluentTc.Tests/Domain/BuildTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using FluentAssertions; 4 | using FluentTc.Domain; 5 | using FluentTc.Locators; 6 | using NUnit.Framework; 7 | 8 | namespace FluentTc.Tests.Domain 9 | { 10 | [TestFixture] 11 | public class BuildTests 12 | { 13 | [Test] 14 | public void SetBuildConfiguration() 15 | { 16 | // Arrange 17 | var build = new Build(1, "2", BuildStatus.Success, new DateTime(), new DateTime(), new DateTime(), null, 18 | null, 19 | new List(), "", 20 | null, new TestOccurrences { Count = 0 }, BuildState.Finished); 21 | 22 | // Act 23 | build.SetBuildConfiguration(new BuildConfiguration {Id = "ConfigId"}); 24 | 25 | // Assert 26 | build.BuildConfiguration.Id.Should().Be("ConfigId"); 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /FluentTc.Tests/Engine/BuildConfigurationRetrieverTests.cs: -------------------------------------------------------------------------------- 1 | using System.Net; 2 | using EasyHttp.Infrastructure; 3 | using FakeItEasy; 4 | using FluentAssertions; 5 | using FluentTc.Domain; 6 | using FluentTc.Engine; 7 | using FluentTc.Tests.Locators; 8 | using NUnit.Framework; 9 | using Ploeh.AutoFixture; 10 | 11 | namespace FluentTc.Tests.Engine 12 | { 13 | [TestFixture] 14 | public class BuildConfigurationRetrieverTests 15 | { 16 | [Test] 17 | public void RetrieveBuildConfigurations_NotFoundExceptionThrown_Empty() 18 | { 19 | // Arrange 20 | var fixture = Auto.Fixture(); 21 | var teamCityCaller = fixture.Freeze(); 22 | A.CallTo(() => teamCityCaller.GetFormat("/app/rest/buildTypes/{0}", A._)) 23 | .Throws(new HttpException(HttpStatusCode.NotFound, "")); 24 | 25 | var buildConfigurationRetriever = fixture.Create(); 26 | 27 | // Act 28 | var retrieveBuildConfigurations = 29 | buildConfigurationRetriever.RetrieveBuildConfigurations(h => h.Project(i => i.Id("projId"))); 30 | 31 | // Assert 32 | retrieveBuildConfigurations.Should().BeEmpty(); 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /FluentTc.Tests/Engine/BuildQueueRemoverTests.cs: -------------------------------------------------------------------------------- 1 | using FakeItEasy; 2 | using FluentTc.Engine; 3 | using FluentTc.Locators; 4 | using FluentTc.Tests.Locators; 5 | using NUnit.Framework; 6 | using Ploeh.AutoFixture; 7 | 8 | namespace FluentTc.Tests.Engine 9 | { 10 | [TestFixture] 11 | public class BuildQueueRemoverTests 12 | { 13 | [Test] 14 | public void RemoveBuildFromQueue_Id_DeleteFormatCalled() 15 | { 16 | // Arrange 17 | var fixture = Auto.Fixture(); 18 | 19 | var buildQueueIdHavingBuilder = new BuildQueueIdHavingBuilder(); 20 | 21 | var buildQueueIdHavingBuilderFactory = fixture.Freeze(); 22 | A.CallTo(() => buildQueueIdHavingBuilderFactory.CreateBuildQueueIdHavingBuilder()) 23 | .Returns(buildQueueIdHavingBuilder); 24 | 25 | var teamCityCaller = fixture.Freeze(); 26 | 27 | var buildQueueRemover = fixture.Create(); 28 | 29 | // Act 30 | buildQueueRemover.RemoveBuildFromQueue(_ => _.Id(123)); 31 | 32 | // Assert 33 | A.CallTo( 34 | () => 35 | teamCityCaller.DeleteFormat(@"/app/rest/buildQueue/{0}", 36 | A.That.IsSameSequenceAs(new[] {"id:123"}))).MustHaveHappened(); 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /FluentTc.Tests/Engine/BuildStatisticConverterTests.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using FluentAssertions; 4 | using FluentTc.Domain; 5 | using FluentTc.Engine; 6 | using NUnit.Framework; 7 | 8 | namespace FluentTc.Tests.Engine 9 | { 10 | [TestFixture] 11 | public class BuildStatisticConverterTests 12 | { 13 | [Test] 14 | public void Convert_EmptyModel_EmptyList() 15 | { 16 | // Arrange 17 | var buildStatisticConverter = new BuildStatisticConverter(); 18 | 19 | // Act 20 | var buildStatistics = buildStatisticConverter.Convert(new BuildStatisticsModel()); 21 | 22 | // Assert 23 | buildStatistics.Should().BeEmpty(); 24 | } 25 | 26 | [Test] 27 | public void Convert_ModelWithOneProperty_OneStatistic() 28 | { 29 | // Arrange 30 | var buildStatisticConverter = new BuildStatisticConverter(); 31 | 32 | // Act 33 | var buildStatistics = buildStatisticConverter.Convert(new BuildStatisticsModel 34 | { 35 | Count = "1", 36 | Property = new List {new Property {Name = "PropName", Value = "PropVal"}} 37 | }); 38 | 39 | // Assert 40 | buildStatistics.Count.Should().Be(1); 41 | buildStatistics.Single().Name.Should().Be("PropName"); 42 | buildStatistics.Single().Value.Should().Be("PropVal"); 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /FluentTc.Tests/Engine/ChangedFilesParserTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO.Abstractions.TestingHelpers; 3 | using System.Linq; 4 | using FluentAssertions; 5 | using FluentTc.Domain; 6 | using FluentTc.Engine; 7 | using NUnit.Framework; 8 | 9 | namespace FluentTc.Tests.Engine 10 | { 11 | [TestFixture] 12 | public class ChangedFilesParserTests 13 | { 14 | [Test] 15 | public void ParseChangedFiles_FileWithOneChange_Parsed() 16 | { 17 | // Arrange 18 | var fileSystem = new MockFileSystem(); 19 | fileSystem.AddFile("changes.txt", new MockFileData(@"VCE Drivers/Cisco NxOS/Debug.tsdrv:CHANGED:136346")); 20 | var changedFilesParser = new ChangedFilesParser(fileSystem); 21 | // Act 22 | var changedFiles = changedFilesParser.ParseChangedFiles("changes.txt"); 23 | 24 | 25 | // Assert 26 | var changedFile = changedFiles.Single(); 27 | changedFile.RelativeFilePath.Should().Be(@"VCE Drivers\Cisco NxOS\Debug.tsdrv"); 28 | changedFile.ChangeStatus.Should().Be(FileChangeStatus.Changed); 29 | changedFile.ChangesetNumber.Should().Be("136346"); 30 | } 31 | 32 | [Test] 33 | public void ParseChangedFiles_FileWithUnknownStatus_ExceptionThrown() 34 | { 35 | // Arrange 36 | var fileSystem = new MockFileSystem(); 37 | fileSystem.AddFile("changes.txt", new MockFileData(@"VCE Drivers/Cisco NxOS/Debug.tsdrv:UNKNOWN:136346")); 38 | var changedFilesParser = new ChangedFilesParser(fileSystem); 39 | // Act 40 | Action action = () => changedFilesParser.ParseChangedFiles("changes.txt"); 41 | 42 | // Assert 43 | action.ShouldThrow().WithMessage("Could not parse FileStatusChange: UNKNOWN"); 44 | } 45 | 46 | [Test] 47 | public void ParseChangedFiles_FileWithOneFileRemoved_Parsed() 48 | { 49 | // Arrange 50 | var fileSystem = new MockFileSystem(); 51 | fileSystem.AddFile("changes.txt", new MockFileData(@"VCE Drivers/Cisco NxOS/Debug.tsdrv:REMOVED:136346")); 52 | var changedFilesParser = new ChangedFilesParser(fileSystem); 53 | // Act 54 | var changedFiles = changedFilesParser.ParseChangedFiles("changes.txt"); 55 | 56 | // Assert 57 | var changedFile = changedFiles.Single(); 58 | changedFile.RelativeFilePath.Should().Be(@"VCE Drivers\Cisco NxOS\Debug.tsdrv"); 59 | changedFile.ChangeStatus.Should().Be(FileChangeStatus.Removed); 60 | changedFile.ChangesetNumber.Should().Be("136346"); 61 | } 62 | } 63 | } -------------------------------------------------------------------------------- /FluentTc.Tests/Engine/ChangesRetrieverTests.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using FakeItEasy; 4 | using FluentAssertions; 5 | using FluentTc.Domain; 6 | using FluentTc.Engine; 7 | using FluentTc.Locators; 8 | using NUnit.Framework; 9 | 10 | namespace FluentTc.Tests.Engine 11 | { 12 | [TestFixture] 13 | public class ChangesRetrieverTests 14 | { 15 | [Test] 16 | public void GetChanges_BuildIdIncludeDefaults() 17 | { 18 | // Arrange 19 | var teamCityCaller = A.Fake(); 20 | A.CallTo( 21 | () => 22 | teamCityCaller.GetFormat(@"/app/rest/changes?locator={0}&fields=change({1})", 23 | A.Ignored)).Returns(new ChangesList(){Change = new List(){new Change(){Id = 123}}}); 24 | 25 | 26 | var buildHavingBuilder = A.Fake(); 27 | A.CallTo(() => buildHavingBuilder.GetLocator()).Returns("id:123"); 28 | 29 | var buildHavingBuilderFactory = A.Fake(); 30 | A.CallTo(() => buildHavingBuilderFactory.CreateBuildHavingBuilder()) 31 | .Returns(buildHavingBuilder); 32 | 33 | // Act 34 | var changesRetriever = new ChangesRetriever(teamCityCaller, buildHavingBuilderFactory); 35 | var changes = changesRetriever.GetChanges(_ => _.Build(__ => __.Id(123)), __ => __.IncludeDefaults()); 36 | 37 | // Assert 38 | changes.Single().Id.Should().Be(123); 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /FluentTc.Tests/Engine/ModelFiltersTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using FakeItEasy; 5 | using FluentAssertions; 6 | using FluentTc.Engine; 7 | using JsonFx.IO; 8 | using JsonFx.Model; 9 | using JsonFx.Serialization; 10 | using NUnit.Framework; 11 | 12 | namespace FluentTc.Tests.Engine 13 | { 14 | [TestFixture] 15 | public class ModelFiltersTest 16 | { 17 | [Test] 18 | public void TeamCityDateFilter_TryRead() 19 | { 20 | // Arrange 21 | var stream = A.Fake>>(); 22 | A.CallTo(() => stream.Peek()).Returns(new Token(ModelTokenType.Primitive, "20160815T233118+0000")); 23 | 24 | // Act 25 | DateTime dateTimeValue; 26 | new TeamCityDateFilter().TryRead(new DataReaderSettings(), stream, out dateTimeValue); 27 | 28 | var expectedUtcDateTime = 29 | new DateTime( 30 | year: 2016, month: 08, day: 15, 31 | hour: 23, minute: 31, second: 18, 32 | kind: DateTimeKind.Utc); 33 | 34 | // Assert 35 | dateTimeValue.ShouldBeEquivalentTo(expectedUtcDateTime.ToLocalTime()); 36 | } 37 | 38 | [Test] 39 | public void TeamCityDateFilter_TryWrite() 40 | { 41 | // Arrange 42 | var datetime = new DateTime( 43 | year: 2016, month: 08, day: 15, 44 | hour: 23, minute: 31, second: 18, 45 | kind: DateTimeKind.Utc); 46 | 47 | // Act 48 | new TeamCityDateFilter().TryWrite(new DataWriterSettings(), datetime, out var tokens); 49 | var expectedOffset = TimeZone.CurrentTimeZone.GetUtcOffset(datetime.ToLocalTime()).ToString("hhmm"); 50 | 51 | // Assert 52 | tokens.Single().Value.ShouldBeEquivalentTo($"20160815T233118+{expectedOffset}"); 53 | } 54 | } 55 | } -------------------------------------------------------------------------------- /FluentTc.Tests/Engine/NewProjectDetailsBuilderTests.cs: -------------------------------------------------------------------------------- 1 | using FluentAssertions; 2 | using FluentTc.Engine; 3 | using NUnit.Framework; 4 | 5 | namespace FluentTc.Tests.Engine 6 | { 7 | [TestFixture] 8 | public class NewProjectDetailsBuilderTests 9 | { 10 | [Test] 11 | public void GetDataXml_IdNameAndParent_XmlFormatted() 12 | { 13 | // Arrange 14 | var newProjectDetailsBuilder = new NewProjectDetailsBuilder(); 15 | 16 | // Act 17 | newProjectDetailsBuilder.Name("New Project Name") 18 | .Id("newProjectId") 19 | .ParentProject(x => x.Id("parentProjectId")); 20 | 21 | // Assert 22 | newProjectDetailsBuilder.GetDataXml() 23 | .Should() 24 | .Be( 25 | @""); 26 | 27 | } 28 | 29 | [Test] 30 | public void GetDataXml_Name_XmlFormatted() 31 | { 32 | // Arrange 33 | var newProjectDetailsBuilder = new NewProjectDetailsBuilder(); 34 | 35 | // Act 36 | newProjectDetailsBuilder.Name("New Project Name"); 37 | 38 | // Assert 39 | newProjectDetailsBuilder.GetDataXml() 40 | .Should() 41 | .Be( 42 | @""); 43 | 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /FluentTc.Tests/Engine/ProjectsRetrieverTests.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using FakeItEasy; 4 | using FluentAssertions; 5 | using FluentTc.Domain; 6 | using FluentTc.Engine; 7 | using FluentTc.Locators; 8 | using NUnit.Framework; 9 | 10 | namespace FluentTc.Tests.Engine 11 | { 12 | [TestFixture] 13 | public class ProjectsRetrieverTests 14 | { 15 | [Test] 16 | public void GetProjects_NoLocator_AllProjects() 17 | { 18 | // Arrange 19 | var teamCityCaller = A.Fake(); 20 | A.CallTo(() => teamCityCaller.GetFormat("/app/rest/projects/{0}", "")) 21 | .Returns(new ProjectWrapper {Project = new List(new[] {new Project {Id = "123"}})}); 22 | var projectsRetriever = new ProjectsRetriever(A.Fake(), teamCityCaller); 23 | 24 | // Act 25 | var projects = projectsRetriever.GetProjects(); 26 | 27 | // Assert 28 | projects.Single().Id.Should().Be("123"); 29 | } 30 | 31 | [Test] 32 | public void GetProjects_Name_ProjectWithName() 33 | { 34 | // Arrange 35 | var teamCityCaller = A.Fake(); 36 | A.CallTo(() => teamCityCaller.GetFormat("/app/rest/projects/{0}", "name:Proj1")) 37 | .Returns(new ProjectWrapper {Project = new List(new[] {new Project {Id = "123"}})}); 38 | 39 | var buildProjectHavingBuilderFactory = A.Fake(); 40 | A.CallTo(() => buildProjectHavingBuilderFactory.CreateBuildProjectHavingBuilder()) 41 | .Returns(new BuildProjectHavingBuilder()); 42 | 43 | var projectsRetriever = new ProjectsRetriever(buildProjectHavingBuilderFactory, teamCityCaller); 44 | 45 | // Act 46 | var projects = projectsRetriever.GetProjects(a=>a.Name("Proj1")); 47 | 48 | // Assert 49 | projects.Single().Id.Should().Be("123"); 50 | } 51 | 52 | [Test] 53 | public void GetProject_Id_Project() 54 | { 55 | // Arrange 56 | var teamCityCaller = A.Fake(); 57 | A.CallTo(() => teamCityCaller.GetFormat("/app/rest/projects/id:{0}", "ProjId1")) 58 | .Returns(new Project { Id = "ProjId1" }); 59 | 60 | var buildProjectHavingBuilderFactory = A.Fake(); 61 | A.CallTo(() => buildProjectHavingBuilderFactory.CreateBuildProjectHavingBuilder()) 62 | .Returns(new BuildProjectHavingBuilder()); 63 | 64 | var projectsRetriever = new ProjectsRetriever(buildProjectHavingBuilderFactory, teamCityCaller); 65 | 66 | // Act 67 | var project = projectsRetriever.GetProject("ProjId1"); 68 | 69 | // Assert 70 | project.Id.Should().Be("ProjId1"); 71 | } 72 | } 73 | } -------------------------------------------------------------------------------- /FluentTc.Tests/Engine/PropertiesFileParserTests.cs: -------------------------------------------------------------------------------- 1 | using System.IO.Abstractions.TestingHelpers; 2 | using FluentAssertions; 3 | using FluentTc.Engine; 4 | using FluentTc.Tests.TestingTools; 5 | using NUnit.Framework; 6 | 7 | namespace FluentTc.Tests.Engine 8 | { 9 | [TestFixture] 10 | public class PropertiesFileParserTests 11 | { 12 | [Test] 13 | public void ParsePropertiesFile_File_Parsed() 14 | { 15 | // Arrange 16 | var mockFileSystem = new MockFileSystem(); 17 | var propertiesFile = @"C:\BuildAgent\temp\buildTmp\teamcity.build322130465402584030.properties"; 18 | mockFileSystem.AddFile(propertiesFile, @"#TeamCity build properties without 'system.' prefix 19 | #Sun Nov 01 14:40:00 IST 2015 20 | agent.home.dir=C\:\\BuildAgent 21 | "); 22 | 23 | var fileParser = new PropertiesFileParser(mockFileSystem); 24 | 25 | // Act 26 | var dictionary = fileParser.ParsePropertiesFile(propertiesFile); 27 | 28 | // Assert 29 | dictionary["agent.home.dir"].Should().Be(@"C:\BuildAgent"); 30 | } 31 | 32 | [Test] 33 | public void ParsePropertiesFile_RealFile_Parsed() 34 | { 35 | var resource = new EmbeddedResourceReader().GetResource("PropertiesFile.txt"); 36 | 37 | // Arrange 38 | var mockFileSystem = new MockFileSystem(); 39 | var propertiesFile = @"C:\BuildAgent\temp\buildTmp\teamcity.build322130465402584030.properties"; 40 | mockFileSystem.AddFile(propertiesFile, resource); 41 | 42 | var propertiesFileParser = new PropertiesFileParser(mockFileSystem); 43 | 44 | // Act 45 | var dictionary = propertiesFileParser.ParsePropertiesFile(propertiesFile); 46 | 47 | // Assert 48 | dictionary["agent.home.dir"].Should().Be(@"C:\BuildAgent"); 49 | dictionary["agent.name"].Should().Be(@"BUILDS8"); 50 | dictionary["agent.ownPort"].Should().Be(@"9090"); 51 | dictionary["agent.work.dir"].Should().Be(@"C:\BuildAgent\work"); 52 | dictionary["build.number"].Should().Be(@"4"); 53 | dictionary["FxCopRoot"].Should() 54 | .Be(@"C:\Program Files (x86)\Microsoft Visual Studio 12.0\Team Tools\Static Analysis Tools\FxCop"); 55 | dictionary["teamcity.agent.dotnet.agent_url"].Should().Be(@"http://localhost:9090/RPC2"); 56 | dictionary["teamcity.auth.userId"].Should().Be(@"TeamCityBuildId=781682"); 57 | } 58 | } 59 | } -------------------------------------------------------------------------------- /FluentTc.Tests/Engine/UniversalTypeConverterTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using FluentAssertions; 3 | using FluentTc.Engine; 4 | using NUnit.Framework; 5 | 6 | namespace FluentTc.Tests.Engine 7 | { 8 | [TestFixture] 9 | public class UniversalTypeConverterTests 10 | { 11 | [Test] 12 | public void StringToType_123_Int() 13 | { 14 | var value = UniversalTypeConverter.StringToType("123"); 15 | 16 | value.Should().Be(123); 17 | } 18 | 19 | [Test] 20 | public void StringToType_true_True() 21 | { 22 | var value = UniversalTypeConverter.StringToType("true"); 23 | 24 | value.Should().BeTrue(); 25 | } 26 | 27 | [Test] 28 | public void StringToType_BooleanStringEmpty_FormatExceptionThrown() 29 | { 30 | Action action = () => UniversalTypeConverter.StringToType(""); 31 | 32 | action.ShouldThrow().WithMessage("String was not recognized as a valid Boolean."); 33 | } 34 | 35 | [Test] 36 | public void StringToType_NullableBooleanStringEmpty_HasNoValue() 37 | { 38 | var value = UniversalTypeConverter.StringToType(""); 39 | 40 | value.HasValue.Should().BeFalse(); 41 | } 42 | 43 | [Test] 44 | public void StringToType_NullableBooleanTrue_True() 45 | { 46 | var value = UniversalTypeConverter.StringToType("true"); 47 | 48 | value.HasValue.Should().BeTrue(); 49 | value.Value.Should().BeTrue(); 50 | } 51 | } 52 | } -------------------------------------------------------------------------------- /FluentTc.Tests/Extensions/StringExtensionsTests.cs: -------------------------------------------------------------------------------- 1 | using NUnit.Framework; 2 | using FluentTc.Extensions; 3 | using FluentAssertions; 4 | 5 | namespace FluentTc.Tests.Extensions 6 | { 7 | [TestFixture] 8 | public class StringExtensionsTests 9 | { 10 | [Test] 11 | [TestCase("ThisIsAPascalCaseExample", "THIS_IS_A_PASCAL_CASE_EXAMPLE")] 12 | [TestCase("", "")] 13 | [TestCase("A", "A")] 14 | [TestCase("Test", "TEST")] 15 | public void FromPascalToCapitalizedCase(string input, string output) 16 | { 17 | input.FromPascalToCapitalizedCase().Should().Be(output); 18 | } 19 | 20 | [Test] 21 | [TestCase("ThisIsAPascalCaseExample", "thisIsAPascalCaseExample")] 22 | [TestCase("", "")] 23 | [TestCase("A", "a")] 24 | [TestCase("Test", "test")] 25 | public void FromPascalToCamelCase(string input, string output) 26 | { 27 | input.FromPascalToCamelCase().Should().Be(output); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /FluentTc.Tests/Locators/AgentHavingBuilderTests.cs: -------------------------------------------------------------------------------- 1 | using FluentAssertions; 2 | using FluentTc.Locators; 3 | using NUnit.Framework; 4 | using Ploeh.AutoFixture; 5 | 6 | namespace FluentTc.Tests.Locators 7 | { 8 | [TestFixture] 9 | public class AgentHavingBuilderTests 10 | { 11 | [Test] 12 | public void Connected() 13 | { 14 | // Arrange 15 | var fixture = Auto.Fixture(); 16 | var agentHavingBuilder = fixture.Create(); 17 | 18 | // Act 19 | agentHavingBuilder.Connected(); 20 | 21 | // Assert 22 | agentHavingBuilder.GetLocator().Should().Be("connected:True"); 23 | } 24 | 25 | [Test] 26 | public void Disabled() 27 | { 28 | // Arrange 29 | var fixture = Auto.Fixture(); 30 | var agentHavingBuilder = fixture.Create(); 31 | 32 | // Act 33 | agentHavingBuilder.Disabled(); 34 | 35 | // Assert 36 | agentHavingBuilder.GetLocator().Should().Be("enabled:False"); 37 | } 38 | 39 | [Test] 40 | public void Authorized() 41 | { 42 | // Arrange 43 | var fixture = Auto.Fixture(); 44 | var agentHavingBuilder = fixture.Create(); 45 | 46 | // Act 47 | agentHavingBuilder.Authorized(); 48 | 49 | // Assert 50 | agentHavingBuilder.GetLocator().Should().Be("authorized:True"); 51 | } 52 | 53 | [Test] 54 | public void Name() 55 | { 56 | // Arrange 57 | var fixture = Auto.Fixture(); 58 | var agentHavingBuilder = fixture.Create(); 59 | 60 | // Act 61 | agentHavingBuilder.Name("agent1"); 62 | 63 | // Assert 64 | agentHavingBuilder.GetLocator().Should().Be("name:agent1"); 65 | } 66 | 67 | [Test] 68 | public void Disconnected() 69 | { 70 | // Arrange 71 | var fixture = Auto.Fixture(); 72 | var agentHavingBuilder = fixture.Create(); 73 | 74 | // Act 75 | agentHavingBuilder.Disconnected(); 76 | 77 | // Assert 78 | agentHavingBuilder.GetLocator().Should().Be("connected:False"); 79 | 80 | 81 | } 82 | [Test] 83 | public void NotAuthorized() 84 | { 85 | // Arrange 86 | var fixture = Auto.Fixture(); 87 | var agentHavingBuilder = fixture.Create(); 88 | 89 | // Act 90 | agentHavingBuilder.NotAuthorized(); 91 | 92 | // Assert 93 | agentHavingBuilder.GetLocator().Should().Be("authorized:False"); 94 | } 95 | 96 | [Test] 97 | public void Ip() 98 | { 99 | // Arrange 100 | var fixture = Auto.Fixture(); 101 | var agentHavingBuilder = fixture.Create(); 102 | 103 | // Act 104 | agentHavingBuilder.Ip("127.0.0.1"); 105 | 106 | // Assert 107 | agentHavingBuilder.GetLocator().Should().Be("ip:127.0.0.1"); 108 | } 109 | } 110 | } -------------------------------------------------------------------------------- /FluentTc.Tests/Locators/Auto.cs: -------------------------------------------------------------------------------- 1 | using Ploeh.AutoFixture; 2 | using Ploeh.AutoFixture.AutoFakeItEasy; 3 | 4 | namespace FluentTc.Tests.Locators 5 | { 6 | public class Auto 7 | { 8 | public static IFixture Fixture() 9 | { 10 | return new Fixture().Customize(new AutoFakeItEasyCustomization()); 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /FluentTc.Tests/Locators/BranchHavingBuilderFactoryTests.cs: -------------------------------------------------------------------------------- 1 | using FluentAssertions; 2 | using FluentTc.Locators; 3 | using NUnit.Framework; 4 | 5 | namespace FluentTc.Tests.Locators 6 | { 7 | [TestFixture] 8 | public class BranchHavingBuilderFactoryTests 9 | { 10 | [Test] 11 | public void CreateBranchHavingBuilder_None_NotNull() 12 | { 13 | // Arrange 14 | var branchHavingBuilderFactory = new BranchHavingBuilderFactory(); 15 | 16 | // Act 17 | var branchHavingBuilder = branchHavingBuilderFactory.CreateBranchHavingBuilder(); 18 | 19 | // Assert 20 | branchHavingBuilder.Should().NotBeNull(); 21 | } 22 | } 23 | } 24 | 25 | -------------------------------------------------------------------------------- /FluentTc.Tests/Locators/BranchHavingBuilderTests.cs: -------------------------------------------------------------------------------- 1 | using FluentAssertions; 2 | using FluentTc.Locators; 3 | using NUnit.Framework; 4 | 5 | namespace FluentTc.Tests.Locators 6 | { 7 | [TestFixture] 8 | public class BranchHavingBuilderTests 9 | { 10 | [Test] 11 | public void Name() 12 | { 13 | // Arrange 14 | var branchHavingBuilder = new BranchHavingBuilder(); 15 | 16 | // Act 17 | branchHavingBuilder.Name("Branch1"); 18 | 19 | // Assert 20 | branchHavingBuilder.GetLocator().Should().Be("name:Branch1"); 21 | } 22 | 23 | [Test] 24 | public void Branched() 25 | { 26 | var branchHavingBuilder = new BranchHavingBuilder(); 27 | 28 | branchHavingBuilder.Branched(); 29 | 30 | branchHavingBuilder.GetLocator().Should().Be("branched:True"); 31 | } 32 | 33 | [Test] 34 | public void NotBranched() 35 | { 36 | var branchHavingBuilder = new BranchHavingBuilder(); 37 | 38 | branchHavingBuilder.NotBranched(); 39 | 40 | branchHavingBuilder.GetLocator().Should().Be("branched:False"); 41 | } 42 | 43 | [Test] 44 | public void Default() 45 | { 46 | var branchHavingBuilder = new BranchHavingBuilder(); 47 | 48 | branchHavingBuilder.Default(); 49 | 50 | branchHavingBuilder.GetLocator().Should().Be("default:True"); 51 | } 52 | 53 | [Test] 54 | public void DefaultFalse() 55 | { 56 | var branchHavingBuilder = new BranchHavingBuilder(); 57 | 58 | branchHavingBuilder.NotDefault(); 59 | 60 | branchHavingBuilder.GetLocator().Should().Be("default:False"); 61 | } 62 | 63 | [Test] 64 | public void Unspecified() 65 | { 66 | var branchHavingBuilder = new BranchHavingBuilder(); 67 | 68 | branchHavingBuilder.Unspecified(); 69 | 70 | branchHavingBuilder.GetLocator().Should().Be("unspecified:True"); 71 | } 72 | 73 | [Test] 74 | public void NotUnspecified() 75 | { 76 | var branchHavingBuilder = new BranchHavingBuilder(); 77 | 78 | branchHavingBuilder.NotUnspecified(); 79 | 80 | branchHavingBuilder.GetLocator().Should().Be("unspecified:False"); 81 | } 82 | } 83 | } -------------------------------------------------------------------------------- /FluentTc.Tests/Locators/BuildAdditionalIncludeBuilderTests.cs: -------------------------------------------------------------------------------- 1 | using FluentAssertions; 2 | using FluentTc.Locators; 3 | using NUnit.Framework; 4 | 5 | namespace FluentTc.Tests.Locators 6 | { 7 | [TestFixture] 8 | public class BuildAdditionalIncludeBuilderTests 9 | { 10 | [Test] 11 | public void ShouldIncludeChanges_False() 12 | { 13 | // Arrange 14 | var buildAdditionalIncludeBuilder = new BuildAdditionalIncludeBuilder(); 15 | 16 | // Act 17 | var shouldIncludeChanges = buildAdditionalIncludeBuilder.ShouldIncludeChanges; 18 | 19 | // Assert 20 | shouldIncludeChanges.Should().BeFalse(); 21 | } 22 | 23 | [Test] 24 | public void ShouldIncludeChanges_True() 25 | { 26 | // Arrange 27 | var buildAdditionalIncludeBuilder = new BuildAdditionalIncludeBuilder(); 28 | 29 | // Act 30 | buildAdditionalIncludeBuilder.IncludeChanges(_ => _.IncludeComment()); 31 | var shouldIncludeChanges = buildAdditionalIncludeBuilder.ShouldIncludeChanges; 32 | 33 | // Assert 34 | shouldIncludeChanges.Should().BeTrue(); 35 | var changesIncludeBuilder = new ChangesIncludeBuilder(); 36 | buildAdditionalIncludeBuilder.ChangesInclude(changesIncludeBuilder); 37 | changesIncludeBuilder.GetColumns().Should().Be("id,version,href,username,date,webUrl,comment"); 38 | } 39 | } 40 | } 41 | 42 | -------------------------------------------------------------------------------- /FluentTc.Tests/Locators/BuildConfigurationHavingBuilderTests.cs: -------------------------------------------------------------------------------- 1 | using FluentAssertions; 2 | using FluentTc.Locators; 3 | using NUnit.Framework; 4 | using Ploeh.AutoFixture; 5 | 6 | namespace FluentTc.Tests.Locators 7 | { 8 | [TestFixture] 9 | public class BuildConfigurationHavingBuilderTests 10 | { 11 | [Test] 12 | public void Id() 13 | { 14 | // Arrange 15 | var fixture = Auto.Fixture(); 16 | var buildConfigurationHavingBuilder = fixture.Create(); 17 | 18 | // Act 19 | buildConfigurationHavingBuilder.Id("bt2"); 20 | 21 | // Assert 22 | buildConfigurationHavingBuilder.GetLocator().Should().Be("id:bt2"); 23 | } 24 | 25 | [Test] 26 | public void Name() 27 | { 28 | // Arrange 29 | var fixture = Auto.Fixture(); 30 | var buildConfigurationHavingBuilder = fixture.Create(); 31 | 32 | // Act 33 | buildConfigurationHavingBuilder.Name("FluentTc"); 34 | 35 | // Assert 36 | buildConfigurationHavingBuilder.GetLocator().Should().Be("name:FluentTc"); 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /FluentTc.Tests/Locators/BuildIncludeBuilderTests.cs: -------------------------------------------------------------------------------- 1 | using FluentAssertions; 2 | using FluentTc.Locators; 3 | using NUnit.Framework; 4 | 5 | namespace FluentTc.Tests.Locators 6 | { 7 | [TestFixture] 8 | public class BuildIncludeBuilderTests 9 | { 10 | [Test] 11 | public void GetColumns_IncludeStartDate_Formatted() 12 | { 13 | // Arrange 14 | var buildIncludeBuilder = new BuildIncludeBuilder(); 15 | buildIncludeBuilder.IncludeStartDate(); 16 | 17 | // Act 18 | var columns = buildIncludeBuilder.GetColumns(); 19 | 20 | // Assert 21 | columns.Should().Be("buildTypeId,href,id,number,state,status,webUrl,startDate"); 22 | } 23 | 24 | [Test] 25 | public void GetColumns_IncludeFinishDate_Formatted() 26 | { 27 | // Arrange 28 | var buildIncludeBuilder = new BuildIncludeBuilder(); 29 | buildIncludeBuilder.IncludeFinishDate(); 30 | 31 | // Act 32 | var columns = buildIncludeBuilder.GetColumns(); 33 | 34 | // Assert 35 | columns.Should().Be("buildTypeId,href,id,number,state,status,webUrl,finishDate"); 36 | } 37 | 38 | [Test] 39 | public void GetColumns_IncludeStatusText_Formatted() 40 | { 41 | // Arrange 42 | var buildIncludeBuilder = new BuildIncludeBuilder(); 43 | buildIncludeBuilder.IncludeStatusText(); 44 | 45 | // Act 46 | var columns = buildIncludeBuilder.GetColumns(); 47 | 48 | // Assert 49 | columns.Should().Be("buildTypeId,href,id,number,state,status,webUrl,statusText"); 50 | } 51 | 52 | [Test] 53 | public void GetColumns_IncludeDefaults_Formatted() 54 | { 55 | // Arrange 56 | var buildIncludeBuilder = new BuildIncludeBuilder(); 57 | buildIncludeBuilder.IncludeDefaults(); 58 | 59 | // Act 60 | var columns = buildIncludeBuilder.GetColumns(); 61 | 62 | // Assert 63 | columns.Should().Be("buildTypeId,href,id,number,state,status,webUrl"); 64 | } 65 | 66 | [Test] 67 | public void GetColumns_IncludeStartDatefinishDateStatusText_Formatted() 68 | { 69 | // Arrange 70 | var buildIncludeBuilder = new BuildIncludeBuilder(); 71 | buildIncludeBuilder.IncludeStartDate().IncludeFinishDate().IncludeStatusText(); 72 | 73 | // Act 74 | var columns = buildIncludeBuilder.GetColumns(); 75 | 76 | // Assert 77 | columns.Should().Be("buildTypeId,href,id,number,state,status,webUrl,startDate,finishDate,statusText"); 78 | } 79 | 80 | [Test] 81 | public void GetColumns_IncludeRevisions_Formatted() 82 | { 83 | // Arrange 84 | var buildIncludeBuilder = new BuildIncludeBuilder(); 85 | buildIncludeBuilder.IncludeRevisions(); 86 | 87 | // Act 88 | var columns = buildIncludeBuilder.GetColumns(); 89 | 90 | // Assert 91 | columns.Should().Be("buildTypeId,href,id,number,state,status,webUrl,revisions"); 92 | } 93 | } 94 | } -------------------------------------------------------------------------------- /FluentTc.Tests/Locators/BuildProjectHavingBuilderTests.cs: -------------------------------------------------------------------------------- 1 | using FluentAssertions; 2 | using FluentTc.Locators; 3 | using NUnit.Framework; 4 | 5 | namespace FluentTc.Tests.Locators 6 | { 7 | [TestFixture] 8 | public class BuildProjectHavingBuilderTests 9 | { 10 | [Test] 11 | public void Id() 12 | { 13 | // Arrange 14 | var buildProjectHavingBuilder = new BuildProjectHavingBuilder(); 15 | 16 | // Act 17 | buildProjectHavingBuilder.Id("ProjectId1"); 18 | 19 | // Assert 20 | buildProjectHavingBuilder.GetLocator().Should().Be("id:ProjectId1"); 21 | } 22 | 23 | [Test] 24 | public void Name() 25 | { 26 | // Arrange 27 | var buildProjectHavingBuilder = new BuildProjectHavingBuilder(); 28 | 29 | // Act 30 | buildProjectHavingBuilder.Name("ProjectName1"); 31 | 32 | // Assert 33 | buildProjectHavingBuilder.GetLocator().Should().Be("name:ProjectName1"); 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /FluentTc.Tests/Locators/BuildQueueIdHavingBuilderTests.cs: -------------------------------------------------------------------------------- 1 | using FluentAssertions; 2 | using FluentTc.Locators; 3 | using NUnit.Framework; 4 | 5 | namespace FluentTc.Tests.Locators 6 | { 7 | [TestFixture] 8 | public class BuildQueueIdHavingBuilderTests 9 | { 10 | [Test] 11 | public void GetLocator_Id() 12 | { 13 | // Arrange 14 | var buildQueueIdHavingBuilder = new BuildQueueIdHavingBuilder(); 15 | 16 | // Act 17 | buildQueueIdHavingBuilder.Id(123); 18 | 19 | // Assert 20 | buildQueueIdHavingBuilder.GetLocator().Should().Be("id:123"); 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /FluentTc.Tests/Locators/ChangesHavingBuilderTests.cs: -------------------------------------------------------------------------------- 1 | using FakeItEasy; 2 | using FluentAssertions; 3 | using FluentTc.Engine; 4 | using FluentTc.Locators; 5 | using NUnit.Framework; 6 | 7 | namespace FluentTc.Tests.Locators 8 | { 9 | [TestFixture] 10 | public class ChangesHavingBuilderTests 11 | { 12 | [Test] 13 | public void Build() 14 | { 15 | // Arrange 16 | var buildHavingBuilder = A.Fake(); 17 | A.CallTo(() => buildHavingBuilder.GetLocator()).Returns("id:123"); 18 | 19 | var buildHavingBuilderFactory = A.Fake(); 20 | A.CallTo(() => buildHavingBuilderFactory.CreateBuildHavingBuilder()).Returns(buildHavingBuilder); 21 | 22 | var changesHavingBuilder = new ChangesHavingBuilder(buildHavingBuilderFactory); 23 | 24 | // Act 25 | changesHavingBuilder.Build(_ => _.Id(123)); 26 | var locator = changesHavingBuilder.GetLocator(); 27 | 28 | // Assertions 29 | locator.Should().Be("build:id:123"); 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /FluentTc.Tests/Locators/ChangesIncludeBuilderTests.cs: -------------------------------------------------------------------------------- 1 | using FluentAssertions; 2 | using FluentTc.Locators; 3 | using NUnit.Framework; 4 | 5 | namespace FluentTc.Tests.Locators 6 | { 7 | [TestFixture] 8 | public class ChangesIncludeBuilderTests 9 | { 10 | [Test] 11 | public void IncludeDefaults() 12 | { 13 | // Arrange + Act 14 | var changesIncludeBuilder = new ChangesIncludeBuilder(); 15 | changesIncludeBuilder.IncludeDefaults(); 16 | 17 | var columns = changesIncludeBuilder.GetColumns(); 18 | 19 | // Assert 20 | columns.Should().Be("id,version,href,username,date,webUrl"); 21 | } 22 | 23 | [Test] 24 | public void IncludeFilesDefaults() 25 | { 26 | // Arrange + Act 27 | var changesIncludeBuilder = new ChangesIncludeBuilder(); 28 | changesIncludeBuilder.IncludeFiles(); 29 | 30 | var columns = changesIncludeBuilder.GetColumns(); 31 | 32 | // Assert 33 | columns.Should().Be("id,version,href,username,date,webUrl,files"); 34 | } 35 | 36 | [Test] 37 | public void IncludeComment() 38 | { 39 | // Arrange + Act 40 | var changesIncludeBuilder = new ChangesIncludeBuilder(); 41 | changesIncludeBuilder.IncludeComment(); 42 | 43 | var columns = changesIncludeBuilder.GetColumns(); 44 | 45 | // Assert 46 | columns.Should().Be("id,version,href,username,date,webUrl,comment"); 47 | } 48 | 49 | [Test] 50 | public void IncludeVcsRootInstance() 51 | { 52 | // Arrange + Act 53 | var changesIncludeBuilder = new ChangesIncludeBuilder(); 54 | changesIncludeBuilder.IncludeVcsRootInstance(); 55 | 56 | var columns = changesIncludeBuilder.GetColumns(); 57 | 58 | // Assert 59 | columns.Should().Be("id,version,href,username,date,webUrl,vcsRootInstance"); 60 | } 61 | 62 | [Test] 63 | public void IncludeAll() 64 | { 65 | // Arrange + Act 66 | var changesIncludeBuilder = new ChangesIncludeBuilder(); 67 | changesIncludeBuilder.IncludeComment().IncludeFiles().IncludeVcsRootInstance(); 68 | 69 | var columns = changesIncludeBuilder.GetColumns(); 70 | 71 | // Assert 72 | columns.Should().Be("id,version,href,username,date,webUrl,comment,files,vcsRootInstance"); 73 | } 74 | } 75 | } 76 | 77 | -------------------------------------------------------------------------------- /FluentTc.Tests/Locators/CountBuilderTests.cs: -------------------------------------------------------------------------------- 1 | using FluentAssertions; 2 | using FluentTc.Locators; 3 | using NUnit.Framework; 4 | 5 | namespace FluentTc.Tests.Locators 6 | { 7 | [TestFixture] 8 | public class CountBuilderTests 9 | { 10 | [Test] 11 | public void All() 12 | { 13 | // Arrange 14 | var countBuilder = new CountBuilder(); 15 | 16 | // Act 17 | countBuilder.DefaultCount(); 18 | 19 | // Assert 20 | countBuilder.GetCount().Should().BeEmpty(); 21 | } 22 | 23 | [Test] 24 | public void CountFive() 25 | { 26 | // Arrange 27 | var countBuilder = new CountBuilder(); 28 | 29 | // Act 30 | countBuilder.Count(5); 31 | 32 | // Assert 33 | countBuilder.GetCount().Should().Be("count:5"); 34 | } 35 | 36 | [Test] 37 | public void StartTwoCountFive() 38 | { 39 | // Arrange 40 | var countBuilder = new CountBuilder(); 41 | 42 | // Act 43 | countBuilder.Start(2).Count(5); 44 | 45 | // Assert 46 | countBuilder.GetCount().Should().Be("start:2,count:5"); 47 | } 48 | } 49 | } -------------------------------------------------------------------------------- /FluentTc.Tests/Locators/QueueHavingBuilderTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using FakeItEasy; 3 | using FluentAssertions; 4 | using FluentTc.Locators; 5 | using NUnit.Framework; 6 | using Ploeh.AutoFixture; 7 | 8 | namespace FluentTc.Tests.Locators 9 | { 10 | [TestFixture] 11 | public class QueueHavingBuilderTests 12 | { 13 | [Test] 14 | public void QueueHavingBuilder_BuildType_LocatorString() 15 | { 16 | // Arrange 17 | var fixture = Auto.Fixture(); 18 | var locatorBuilder = fixture.Freeze(); 19 | Action havingBuildConfig = _ => _.Id("bt2"); 20 | A.CallTo(() => locatorBuilder.GetBuildConfigurationLocator(havingBuildConfig)).Returns("id:bt2"); 21 | QueueHavingBuilder queueHavingBuilder = fixture.Create(); 22 | 23 | // Act 24 | queueHavingBuilder.BuildConfiguration(havingBuildConfig); 25 | 26 | // Assert 27 | queueHavingBuilder.GetLocator().Should().Be("buildType:id:bt2"); 28 | } 29 | 30 | [Test] 31 | public void QueueHavingBuilder_Project_LocatorString() 32 | { 33 | // Arrange 34 | var fixture = Auto.Fixture(); 35 | var locatorBuilder = fixture.Freeze(); 36 | Action havingBuildConfig = _ => _.Id("bt2"); 37 | A.CallTo(() => locatorBuilder.GetProjectLocator(havingBuildConfig)).Returns("id:bt2"); 38 | QueueHavingBuilder queueHavingBuilder = fixture.Create(); 39 | 40 | // Act 41 | queueHavingBuilder.Project(havingBuildConfig); 42 | 43 | // Assert 44 | queueHavingBuilder.GetLocator().Should().Be("project:id:bt2"); 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /FluentTc.Tests/Locators/TeamCityConfigurationBuilderTests.cs: -------------------------------------------------------------------------------- 1 | using FluentAssertions; 2 | using FluentTc.Locators; 3 | using NUnit.Framework; 4 | 5 | namespace FluentTc.Tests.Locators 6 | { 7 | [TestFixture] 8 | public class TeamCityConfigurationBuilderTests 9 | { 10 | [Test] 11 | public void GetTeamCityConnectionDetails_Guest_ActAsGuestTrue() 12 | { 13 | // Arrange 14 | var teamCityConfigurationBuilder = new TeamCityConfigurationBuilder(); 15 | // Act 16 | var teamCityConnectionDetails = 17 | teamCityConfigurationBuilder.ToHost("teamcity").AsGuest().GetTeamCityConnectionDetails(); 18 | 19 | // Assert 20 | teamCityConnectionDetails.ActAsGuest.Should().BeTrue(); 21 | teamCityConnectionDetails.TeamCityHost.Should().Be("teamcity"); 22 | } 23 | 24 | [Test] 25 | public void GetTeamCityConnectionDetails_AsUser_ActAsGuestFalse() 26 | { 27 | // Arrange 28 | var teamCityConfigurationBuilder = new TeamCityConfigurationBuilder(); 29 | // Act 30 | var teamCityConnectionDetails = 31 | teamCityConfigurationBuilder.ToHost("teamcity").AsUser("user", "pwd").GetTeamCityConnectionDetails(); 32 | 33 | // Assert 34 | teamCityConnectionDetails.TeamCityHost.Should().Be("teamcity"); 35 | teamCityConnectionDetails.ActAsGuest.Should().BeFalse(); 36 | teamCityConnectionDetails.Username.Should().Be("user"); 37 | teamCityConnectionDetails.Password.Should().Be("pwd"); 38 | } 39 | 40 | [Test] 41 | public void GetTeamCityConnectionDetails_AsUserUseSsl_UseSSLTrue() 42 | { 43 | // Arrange 44 | var teamCityConfigurationBuilder = new TeamCityConfigurationBuilder(); 45 | // Act 46 | var teamCityConnectionDetails = 47 | teamCityConfigurationBuilder.ToHost("teamcity").AsUser("user", "pwd").UseSsl().GetTeamCityConnectionDetails(); 48 | 49 | // Assert 50 | teamCityConnectionDetails.TeamCityHost.Should().Be("teamcity"); 51 | teamCityConnectionDetails.ActAsGuest.Should().BeFalse(); 52 | teamCityConnectionDetails.Username.Should().Be("user"); 53 | teamCityConnectionDetails.Password.Should().Be("pwd"); 54 | teamCityConnectionDetails.UseSSL.Should().BeTrue(); 55 | } 56 | 57 | [Test] 58 | public void GetTeamCityConnectionDetails_AsUserDoNotUseSsl_UseSSLFalse() 59 | { 60 | // Arrange 61 | var teamCityConfigurationBuilder = new TeamCityConfigurationBuilder(); 62 | // Act 63 | var teamCityConnectionDetails = 64 | teamCityConfigurationBuilder.ToHost("teamcity").AsUser("user", "pwd").DoNotUseSsl().GetTeamCityConnectionDetails(); 65 | 66 | // Assert 67 | teamCityConnectionDetails.TeamCityHost.Should().Be("teamcity"); 68 | teamCityConnectionDetails.ActAsGuest.Should().BeFalse(); 69 | teamCityConnectionDetails.Username.Should().Be("user"); 70 | teamCityConnectionDetails.Password.Should().Be("pwd"); 71 | teamCityConnectionDetails.UseSSL.Should().BeFalse(); 72 | } 73 | } 74 | } -------------------------------------------------------------------------------- /FluentTc.Tests/Locators/UserHavingBuilderTests.cs: -------------------------------------------------------------------------------- 1 | using FluentAssertions; 2 | using FluentTc.Locators; 3 | using NUnit.Framework; 4 | 5 | namespace FluentTc.Tests.Locators 6 | { 7 | [TestFixture] 8 | public class UserHavingBuilderTests 9 | { 10 | [Test] 11 | public void InternalUserId() 12 | { 13 | var userHavingBuilder = new UserHavingBuilder(); 14 | var havingBuilder = userHavingBuilder.Id("123"); 15 | 16 | var locator = ((IUserHavingBuilder) havingBuilder).GetLocator(); 17 | 18 | locator.Should().Be("id:123"); 19 | } 20 | 21 | [Test] 22 | public void Username() 23 | { 24 | var userHavingBuilder = new UserHavingBuilder(); 25 | var havingBuilder = userHavingBuilder.Username("chuck"); 26 | 27 | var locator = ((IUserHavingBuilder) havingBuilder).GetLocator(); 28 | 29 | locator.Should().Be("username:chuck"); 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /FluentTc.Tests/Locators/VCSRootEntryBuilderTests.cs: -------------------------------------------------------------------------------- 1 | using FluentAssertions; 2 | using FluentTc.Locators; 3 | using NUnit.Framework; 4 | 5 | namespace FluentTc.Tests.Locators 6 | { 7 | [TestFixture] 8 | public class VCSRootEntryBuilderTests 9 | { 10 | [Test] 11 | [TestCase("id")] 12 | public void Id(string id) 13 | { 14 | var vcsHavingBuilder = new VCSRootEntryBuilder(); 15 | 16 | vcsHavingBuilder 17 | .Id(id); 18 | 19 | vcsHavingBuilder.GetVCSRootEntry().VcsRoot.Should().NotBeNull(); 20 | vcsHavingBuilder.GetVCSRootEntry().VcsRoot.Id.Should().Be(id); 21 | } 22 | 23 | [Test] 24 | [TestCase("id", "checkoutRules")] 25 | public void IdAndCheckoutRules(string id, string checkoutRules) 26 | { 27 | var vcsHavingBuilder = new VCSRootEntryBuilder(); 28 | 29 | vcsHavingBuilder 30 | .Id(id) 31 | .CheckoutRules(checkoutRules); 32 | 33 | vcsHavingBuilder.GetVCSRootEntry().VcsRoot.Should().NotBeNull(); 34 | vcsHavingBuilder.GetVCSRootEntry().VcsRoot.Id.Should().Be(id); 35 | vcsHavingBuilder.GetVCSRootEntry().CheckoutRules.Should().Be(checkoutRules); 36 | } 37 | 38 | [Test] 39 | [TestCase("checkoutRules")] 40 | public void CheckoutRules(string checkoutRules) 41 | { 42 | var vcsHavingBuilder = new VCSRootEntryBuilder(); 43 | 44 | vcsHavingBuilder 45 | .CheckoutRules(checkoutRules); 46 | 47 | vcsHavingBuilder.GetVCSRootEntry().VcsRoot.Should().NotBeNull(); 48 | vcsHavingBuilder.GetVCSRootEntry().VcsRoot.Id.Should().BeNull(); 49 | vcsHavingBuilder.GetVCSRootEntry().CheckoutRules.Should().Be(checkoutRules); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /FluentTc.Tests/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("FluentTc.Tests")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("FluentTc.Tests")] 13 | [assembly: AssemblyCopyright("Copyright © 2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("6307194a-9336-49c5-85b5-6fe6e724236f")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /FluentTc.Tests/Resources/PropertiesFile.txt: -------------------------------------------------------------------------------- 1 | #TeamCity build properties without 'system.' prefix 2 | #Sun Nov 22 10:50:03 IST 2015 3 | agent.home.dir=C\:\\BuildAgent 4 | agent.name=BUILDS8 5 | agent.ownPort=9090 6 | agent.work.dir=C\:\\BuildAgent\\work 7 | build.number=4 8 | FxCopCmdFileVersion=12.0.21005.1 9 | FxCopRoot=C\:\\Program Files (x86)\\Microsoft Visual Studio 12.0\\Team Tools\\Static Analysis Tools\\FxCop 10 | java.io.tmpdir=C\:\\BuildAgent\\temp\\buildTmp 11 | teamcity.agent.cpuBenchmark=637 12 | teamcity.agent.dotnet.agent_url=http\://localhost\:9090/RPC2 13 | teamcity.agent.dotnet.build_id=781682 14 | teamcity.agent.ensure.free.space=10Gb 15 | teamcity.auth.password=iHC4MiyFceXU5aKGWM4yeaBEjZWVdd7v 16 | teamcity.auth.userId=TeamCityBuildId\=781682 17 | teamcity.build.changedFiles.file=C\:\\BuildAgent\\temp\\buildTmp\\changedFiles5455301907873295404.txt 18 | teamcity.build.checkoutDir=C\:\\BuildAgent\\work\\78d85da0b512507 19 | teamcity.build.id=781682 20 | teamcity.build.properties.file=C\:\\BuildAgent\\temp\\buildTmp\\teamcity.build7041482380633247652.properties 21 | teamcity.build.tempDir=C\:\\BuildAgent\\temp\\buildTmp 22 | teamcity.build.workingDir=C\:\\BuildAgent\\work\\78d85da0b512507 23 | teamcity.buildConfName=Trying by Boris 24 | teamcity.buildType.id=Misc_Tryout_TryingByBoris 25 | teamcity.configuration.properties.file=C\:\\BuildAgent\\temp\\buildTmp\\teamcity.config1948038384398008623.properties 26 | teamcity.dotnet.nunitaddin=C\:\\BuildAgent\\plugins\\dotnetPlugin\\bin\\JetBrains.TeamCity.NUnitAddin-NUnit 27 | teamcity.dotnet.nunitlauncher=C\:\\BuildAgent\\plugins\\dotnetPlugin\\bin\\JetBrains.BuildServer.NUnitLauncher.exe 28 | teamcity.dotnet.nunitlauncher.msbuild.task=C\:\\BuildAgent\\plugins\\dotnetPlugin\\bin\\JetBrains.BuildServer.MSBuildLoggers.dll 29 | teamcity.dotnet.nunitlauncher1.1=C\:\\BuildAgent\\plugins\\dotnetPlugin\\bin\\JetBrains.BuildServer.NUnitLauncher1.1.exe 30 | teamcity.dotnet.nunitlauncher2.0=C\:\\BuildAgent\\plugins\\dotnetPlugin\\bin\\JetBrains.BuildServer.NUnitLauncher2.0.exe 31 | teamcity.dotnet.nunitlauncher2.0.vsts=C\:\\BuildAgent\\plugins\\dotnetPlugin\\bin\\JetBrains.BuildServer.NUnitLauncher2.0.VSTS.exe 32 | teamcity.dotnet.platform=C\:\\BuildAgent\\plugins\\dotnetPlugin\\bin\\JetBrains.TeamCity.PlatformProcessRunner.1.1.exe 33 | teamcity.projectName=Tryout 34 | teamcity.runner.properties.file=C\:\\BuildAgent\\temp\\buildTmp\\teamcity.runner5136921864276882166.properties 35 | teamcity.tests.recentlyFailedTests.file=C\:\\BuildAgent\\temp\\buildTmp\\testsToRunFirst1331030541797073503.txt 36 | teamcity.version=9.1.2 (build 37168) 37 | -------------------------------------------------------------------------------- /FluentTc.Tests/TestingTools/EmbeddedResourceReader.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Reflection; 4 | 5 | namespace FluentTc.Tests.TestingTools 6 | { 7 | public class EmbeddedResourceReader 8 | { 9 | public string GetResource(string resourceName) 10 | { 11 | var assembly = Assembly.GetExecutingAssembly(); 12 | 13 | var fullResourceName = string.Format("{0}.Resources.{1}", assembly.GetName().Name, resourceName); 14 | 15 | using (var stream = assembly.GetManifestResourceStream(fullResourceName)) 16 | { 17 | if (stream == null) throw new Exception(string.Format("Embedded resource not found {0}", resourceName)); 18 | using (var reader = new StreamReader(stream)) 19 | { 20 | return reader.ReadToEnd(); 21 | } 22 | } 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /FluentTc.Tests/app.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /FluentTc.Tests/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /FluentTc.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.40629.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{12F98C0B-0C8B-4835-98A8-C00B1C856611}" 7 | ProjectSection(SolutionItems) = preProject 8 | .nuget\NuGet.Config = .nuget\NuGet.Config 9 | .nuget\NuGet.exe = .nuget\NuGet.exe 10 | .nuget\NuGet.targets = .nuget\NuGet.targets 11 | EndProjectSection 12 | EndProject 13 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FluentTc", "FluentTc\FluentTc.csproj", "{7ADB6E1B-2C4E-4094-BF6D-71CE797232D3}" 14 | EndProject 15 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FluentTc.Samples", "FluentTc.Samples\FluentTc.Samples.csproj", "{74A8A3FE-8067-4DCA-8526-BB58FEFCF298}" 16 | EndProject 17 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FluentTc.Tests", "FluentTc.Tests\FluentTc.Tests.csproj", "{DFEB0AA2-5DDC-4CD8-AA46-2AED21FEADB5}" 18 | EndProject 19 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{108A1F9B-4949-4446-AF6A-B5F22FC86A3B}" 20 | ProjectSection(SolutionItems) = preProject 21 | README.md = README.md 22 | EndProjectSection 23 | EndProject 24 | Global 25 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 26 | Debug|Any CPU = Debug|Any CPU 27 | Release|Any CPU = Release|Any CPU 28 | EndGlobalSection 29 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 30 | {7ADB6E1B-2C4E-4094-BF6D-71CE797232D3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 31 | {7ADB6E1B-2C4E-4094-BF6D-71CE797232D3}.Debug|Any CPU.Build.0 = Debug|Any CPU 32 | {7ADB6E1B-2C4E-4094-BF6D-71CE797232D3}.Release|Any CPU.ActiveCfg = Release|Any CPU 33 | {7ADB6E1B-2C4E-4094-BF6D-71CE797232D3}.Release|Any CPU.Build.0 = Release|Any CPU 34 | {74A8A3FE-8067-4DCA-8526-BB58FEFCF298}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 35 | {74A8A3FE-8067-4DCA-8526-BB58FEFCF298}.Debug|Any CPU.Build.0 = Debug|Any CPU 36 | {74A8A3FE-8067-4DCA-8526-BB58FEFCF298}.Release|Any CPU.ActiveCfg = Release|Any CPU 37 | {74A8A3FE-8067-4DCA-8526-BB58FEFCF298}.Release|Any CPU.Build.0 = Release|Any CPU 38 | {DFEB0AA2-5DDC-4CD8-AA46-2AED21FEADB5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 39 | {DFEB0AA2-5DDC-4CD8-AA46-2AED21FEADB5}.Debug|Any CPU.Build.0 = Debug|Any CPU 40 | {DFEB0AA2-5DDC-4CD8-AA46-2AED21FEADB5}.Release|Any CPU.ActiveCfg = Release|Any CPU 41 | {DFEB0AA2-5DDC-4CD8-AA46-2AED21FEADB5}.Release|Any CPU.Build.0 = Release|Any CPU 42 | EndGlobalSection 43 | GlobalSection(SolutionProperties) = preSolution 44 | HideSolutionNode = FALSE 45 | EndGlobalSection 46 | EndGlobal 47 | -------------------------------------------------------------------------------- /FluentTc.sln.DotSettings: -------------------------------------------------------------------------------- 1 |  2 | NUnit TestCop Test 3 | <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /> -------------------------------------------------------------------------------- /FluentTc/Bootstrapper.cs: -------------------------------------------------------------------------------- 1 | using System.IO.Abstractions; 2 | using System.Linq; 3 | using Autofac; 4 | using JetBrains.TeamCity.ServiceMessages.Write.Special; 5 | 6 | namespace FluentTc 7 | { 8 | internal class Bootstrapper 9 | { 10 | private readonly object[] m_Overrides; 11 | 12 | internal Bootstrapper(params object[] overrides) 13 | { 14 | m_Overrides = overrides; 15 | } 16 | 17 | internal IConnectedTc GetConnectedTc() 18 | { 19 | return Get(); 20 | } 21 | 22 | internal T Get() 23 | { 24 | var builder = new ContainerBuilder(); 25 | builder.RegisterType().As(); 26 | builder.RegisterType().AsImplementedInterfaces().SingleInstance(); 27 | builder.RegisterAssemblyTypes(typeof(Bootstrapper).Assembly).AsImplementedInterfaces(); 28 | OverrideRegistrations(builder, m_Overrides); 29 | var container = builder.Build(); 30 | 31 | return container.Resolve(); 32 | } 33 | 34 | private static void OverrideRegistrations(ContainerBuilder builder, params object[] overrides) 35 | { 36 | if (overrides == null || !overrides.Any()) return; 37 | foreach (var instance in overrides) 38 | { 39 | builder.RegisterInstance(instance).AsImplementedInterfaces(); 40 | } 41 | } 42 | } 43 | } -------------------------------------------------------------------------------- /FluentTc/Domain/Agent.cs: -------------------------------------------------------------------------------- 1 | namespace FluentTc.Domain 2 | { 3 | public class Agent 4 | { 5 | public int Id { get; set; } 6 | public int TypeId { get; set; } 7 | public string Name { get; set; } 8 | public string Href { get; set; } 9 | } 10 | } -------------------------------------------------------------------------------- /FluentTc/Domain/AgentPool.cs: -------------------------------------------------------------------------------- 1 | namespace FluentTc.Domain 2 | { 3 | public class AgentPool 4 | { 5 | 6 | } 7 | } -------------------------------------------------------------------------------- /FluentTc/Domain/AgentRequirement.cs: -------------------------------------------------------------------------------- 1 | namespace FluentTc.Domain 2 | { 3 | public class AgentRequirement 4 | { 5 | public override string ToString() 6 | { 7 | return "agent_requirement"; 8 | } 9 | 10 | public string Id { get; set; } 11 | public string Type { get; set; } 12 | public Properties Properties { get; set; } 13 | } 14 | } -------------------------------------------------------------------------------- /FluentTc/Domain/AgentRequirements.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace FluentTc.Domain 4 | { 5 | public class AgentRequirements 6 | { 7 | public override string ToString() 8 | { 9 | return "agent-requirements"; 10 | } 11 | 12 | public List AgentRequirement { get; set; } 13 | } 14 | } -------------------------------------------------------------------------------- /FluentTc/Domain/AgentWrapper.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace FluentTc.Domain 4 | { 5 | public class AgentWrapper 6 | { 7 | public string Count { get; set; } 8 | public List Agent { get; set; } 9 | } 10 | } -------------------------------------------------------------------------------- /FluentTc/Domain/ArtifactDependencies.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace FluentTc.Domain 4 | { 5 | public class ArtifactDependencies 6 | { 7 | public override string ToString() 8 | { 9 | return "artifact-dependencies"; 10 | } 11 | 12 | public List ArtifactDependency { get; set; } 13 | } 14 | } -------------------------------------------------------------------------------- /FluentTc/Domain/ArtifactDependency.cs: -------------------------------------------------------------------------------- 1 | namespace FluentTc.Domain 2 | { 3 | using JsonFx.Json; 4 | 5 | public class ArtifactDependency 6 | { 7 | public override string ToString() 8 | { 9 | return "artifact_dependency"; 10 | } 11 | 12 | public string Id { get; set; } 13 | 14 | public string Type { get; set; } 15 | 16 | public Properties Properties { get; set; } 17 | 18 | [JsonName("source-buildType")] 19 | public SourceBuildType SourceBuildType { get; set; } 20 | } 21 | } -------------------------------------------------------------------------------- /FluentTc/Domain/Assignment.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace FluentTc.Domain 4 | { 5 | public class Assignment 6 | { 7 | public User User { get; set; } 8 | 9 | public DateTime Timestamp { get; set; } 10 | } 11 | } -------------------------------------------------------------------------------- /FluentTc/Domain/BuildConfiguration.cs: -------------------------------------------------------------------------------- 1 | namespace FluentTc.Domain 2 | { 3 | public class BuildConfiguration 4 | { 5 | public override string ToString() 6 | { 7 | return Name; 8 | } 9 | 10 | public string Id { get; set; } 11 | public string Name { get; set; } 12 | public string Href { get; set; } 13 | public string ProjectId { get; set; } 14 | public string ProjectName { get; set; } 15 | public string Description { get; set; } 16 | public string WebUrl { get; set; } 17 | 18 | public Project Project { get; set; } 19 | 20 | public Parameters Parameters { get; set; } 21 | public ArtifactDependencies ArtifactDependencies { get; set; } 22 | public SnapshotDependencies SnapshotDependencies { get; set; } 23 | public VcsRootEntries VcsRootEntries { get; set; } 24 | public BuildSteps Steps { get; set; } 25 | public AgentRequirements AgentRequirements { get; set; } 26 | public BuildTriggers Triggers { get; set; } 27 | public Properties Settings { get; set; } 28 | } 29 | } -------------------------------------------------------------------------------- /FluentTc/Domain/BuildModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace FluentTc.Domain 5 | { 6 | public class BuildModel 7 | { 8 | public long Id { get; set; } 9 | public string Number { get; set; } 10 | public string Status { get; set; } 11 | public string State { get; set; } 12 | public string BuildTypeId { get; set; } 13 | public string Href { get; set; } 14 | public string WebUrl { get; set; } 15 | public string StatusText { get; set; } 16 | public DateTime StartDate { get; set; } 17 | public DateTime FinishDate { get; set; } 18 | public DateTime QueuedDate { get; set; } 19 | 20 | public BuildConfiguration BuildType { get; set; } 21 | public Agent Agent { get; set; } 22 | public TestOccurrences TestOccurrences { get; set; } 23 | public ChangesList LastChanges { get; set; } 24 | public ChangesWrapper Changes { get; set; } 25 | public RevisionsWrapper Revisions { get; set; } 26 | public List BuildChanges { get; set; } 27 | public Properties Properties { get; set; } 28 | } 29 | } -------------------------------------------------------------------------------- /FluentTc/Domain/BuildStatisticsModel.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace FluentTc.Domain 4 | { 5 | public class BuildStatisticsModel 6 | { 7 | public string Count { get; set; } 8 | public List Property { get; set; } 9 | } 10 | } -------------------------------------------------------------------------------- /FluentTc/Domain/BuildStep.cs: -------------------------------------------------------------------------------- 1 | namespace FluentTc.Domain 2 | { 3 | public class BuildStep 4 | { 5 | public override string ToString() 6 | { 7 | return "step"; 8 | } 9 | public string Id { get; set; } 10 | public string Name { get; set; } 11 | public string Type { get; set; } 12 | public string Disabled { get; set; } 13 | public Properties Properties { get; set; } 14 | } 15 | } -------------------------------------------------------------------------------- /FluentTc/Domain/BuildSteps.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace FluentTc.Domain 4 | { 5 | public class BuildSteps 6 | { 7 | public override string ToString() 8 | { 9 | return "steps"; 10 | } 11 | 12 | public List Step { get; set; } 13 | } 14 | } -------------------------------------------------------------------------------- /FluentTc/Domain/BuildTrigger.cs: -------------------------------------------------------------------------------- 1 | namespace FluentTc.Domain 2 | { 3 | public class BuildTrigger 4 | { 5 | public override string ToString() 6 | { 7 | return "trigger"; 8 | } 9 | 10 | public string Id { get; set; } 11 | public string Type { get; set; } 12 | public Properties Properties { get; set; } 13 | } 14 | } -------------------------------------------------------------------------------- /FluentTc/Domain/BuildTriggers.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace FluentTc.Domain 4 | { 5 | public class BuildTriggers 6 | { 7 | public override string ToString() 8 | { 9 | return "triggers"; 10 | } 11 | 12 | public List Trigger { get; set; } 13 | } 14 | } -------------------------------------------------------------------------------- /FluentTc/Domain/BuildTypeWrapper.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace FluentTc.Domain 4 | { 5 | public class BuildTypeWrapper 6 | { 7 | public List BuildType { get; set; } 8 | } 9 | } -------------------------------------------------------------------------------- /FluentTc/Domain/BuildWrapper.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace FluentTc.Domain 4 | { 5 | public class BuildWrapper 6 | { 7 | public string Count { get; set; } 8 | public List Build { get; set; } 9 | } 10 | } -------------------------------------------------------------------------------- /FluentTc/Domain/Change.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace FluentTc.Domain 4 | { 5 | public class Change 6 | { 7 | public string Username { get; set; } 8 | public string WebUrl { get; set; } 9 | public string Href { get; set; } 10 | public long Id { get; set; } 11 | public string Version { get; set; } 12 | public DateTime Date { get; set; } 13 | public string Comment { get; set; } 14 | 15 | public FileWrapper Files { get; set; } 16 | 17 | public User User { get; set; } 18 | } 19 | } -------------------------------------------------------------------------------- /FluentTc/Domain/ChangedFile.cs: -------------------------------------------------------------------------------- 1 | namespace FluentTc.Domain 2 | { 3 | public enum FileChangeStatus 4 | { 5 | Changed, 6 | Added, 7 | Removed, 8 | Not_Changed, 9 | Directory_Changed, 10 | Directory_Added, 11 | Directory_Removed 12 | } 13 | 14 | public interface IChangedFile 15 | { 16 | string RelativeFilePath { get; } 17 | FileChangeStatus ChangeStatus { get; } 18 | string ChangesetNumber { get; } 19 | } 20 | 21 | public class ChangedFile : IChangedFile 22 | { 23 | private readonly string m_RelativeFilePath; 24 | private readonly FileChangeStatus m_ChangeStatus; 25 | private readonly string m_ChangesetNumber; 26 | 27 | public ChangedFile(string relativeFilePath, FileChangeStatus changeStatus, string changesetNumber) 28 | { 29 | m_RelativeFilePath = relativeFilePath; 30 | m_ChangeStatus = changeStatus; 31 | m_ChangesetNumber = changesetNumber; 32 | } 33 | 34 | public string RelativeFilePath { get { return m_RelativeFilePath; } } 35 | public FileChangeStatus ChangeStatus { get { return m_ChangeStatus; } } 36 | public string ChangesetNumber { get { return m_ChangesetNumber; } } 37 | } 38 | 39 | } -------------------------------------------------------------------------------- /FluentTc/Domain/ChangesList.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace FluentTc.Domain 4 | { 5 | public class ChangesList 6 | { 7 | public List Change { get; set; } 8 | } 9 | } -------------------------------------------------------------------------------- /FluentTc/Domain/ChangesWrapper.cs: -------------------------------------------------------------------------------- 1 | namespace FluentTc.Domain 2 | { 3 | public class ChangesWrapper 4 | { 5 | public int Count { get; set; } 6 | public string Href { get; set; } 7 | } 8 | } -------------------------------------------------------------------------------- /FluentTc/Domain/File.cs: -------------------------------------------------------------------------------- 1 | namespace FluentTc.Domain 2 | { 3 | public class File 4 | { 5 | public string relativefile { get; set; } 6 | } 7 | } -------------------------------------------------------------------------------- /FluentTc/Domain/FileWrapper.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace FluentTc.Domain 4 | { 5 | public class FileWrapper 6 | { 7 | public List File { get; set; } 8 | } 9 | } -------------------------------------------------------------------------------- /FluentTc/Domain/Group.cs: -------------------------------------------------------------------------------- 1 | namespace FluentTc.Domain 2 | { 3 | public class Group 4 | { 5 | public override string ToString() 6 | { 7 | return Name; 8 | } 9 | public string Href { get; set; } 10 | public string Name { get; set; } 11 | public string Key { get; set; } 12 | 13 | public UserWrapper Users { get; set; } 14 | public RoleWrapper Roles { get; set; } 15 | } 16 | } -------------------------------------------------------------------------------- /FluentTc/Domain/IBuildStatistic.cs: -------------------------------------------------------------------------------- 1 | namespace FluentTc.Domain 2 | { 3 | public interface IBuildStatistic 4 | { 5 | string Name { get; } 6 | string Value { get; } 7 | } 8 | 9 | public class BuildStatistic : IBuildStatistic 10 | { 11 | private readonly string m_Name; 12 | private readonly string m_Value; 13 | 14 | public BuildStatistic(string name, string value) 15 | { 16 | m_Name = name; 17 | m_Value = value; 18 | } 19 | 20 | public string Name 21 | { 22 | get { return m_Name; } 23 | } 24 | 25 | public string Value 26 | { 27 | get { return m_Value; } 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /FluentTc/Domain/Investigation.cs: -------------------------------------------------------------------------------- 1 | namespace FluentTc.Domain 2 | { 3 | public class Investigation 4 | { 5 | public User Assignee { get; set; } 6 | 7 | public Assignment Assignment { get; set; } 8 | 9 | public TestOccurrenceWrapper TargetWrap { get; set; } 10 | 11 | public ResolutionWrapper Resolution { get; set; } 12 | 13 | public string State { get; set; } 14 | } 15 | } -------------------------------------------------------------------------------- /FluentTc/Domain/InvestigationWrapper.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace FluentTc.Domain 4 | { 5 | public class InvestigationWrapper 6 | { 7 | public List Investigation { get; set; } 8 | } 9 | } -------------------------------------------------------------------------------- /FluentTc/Domain/Parameters.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace FluentTc.Domain 4 | { 5 | public class Parameters 6 | { 7 | public override string ToString() 8 | { 9 | return "parameters"; 10 | } 11 | 12 | public List Property { get; set; } 13 | } 14 | } -------------------------------------------------------------------------------- /FluentTc/Domain/Project.cs: -------------------------------------------------------------------------------- 1 | namespace FluentTc.Domain 2 | { 3 | public class Project 4 | { 5 | public override string ToString() 6 | { 7 | return Name; 8 | } 9 | 10 | public bool Archived { get; set; } 11 | public string Description { get; set; } 12 | public string Href { get; set; } 13 | public string Id { get; set; } 14 | public string Name { get; set; } 15 | public string WebUrl { get; set; } 16 | 17 | public BuildTypeWrapper BuildTypes { get; set; } 18 | public ProjectWrapper Projects { get; set; } 19 | public Parameters Parameters { get; set; } 20 | public bool IsRoot { get { return !string.IsNullOrEmpty(Id) && Id.Equals("_Root"); } } 21 | } 22 | } -------------------------------------------------------------------------------- /FluentTc/Domain/ProjectWrapper.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace FluentTc.Domain 4 | { 5 | public class ProjectWrapper 6 | { 7 | public List Project { get; set; } 8 | } 9 | } -------------------------------------------------------------------------------- /FluentTc/Domain/Properties.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace FluentTc.Domain 4 | { 5 | public class Properties 6 | { 7 | public override string ToString() 8 | { 9 | return "properties"; 10 | } 11 | public List Property { get; set; } 12 | } 13 | } -------------------------------------------------------------------------------- /FluentTc/Domain/Property.cs: -------------------------------------------------------------------------------- 1 | namespace FluentTc.Domain 2 | { 3 | public class Property 4 | { 5 | public override string ToString() 6 | { 7 | return Name; 8 | } 9 | 10 | public string Name { get; set; } 11 | public string Value { get; set; } 12 | public PropertyType Type { get; set; } 13 | } 14 | } -------------------------------------------------------------------------------- /FluentTc/Domain/PropertyType.cs: -------------------------------------------------------------------------------- 1 | namespace FluentTc.Domain 2 | { 3 | public class PropertyType 4 | { 5 | public string RawValue { get; set; } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /FluentTc/Domain/ResolutionWrapper.cs: -------------------------------------------------------------------------------- 1 | namespace FluentTc.Domain 2 | { 3 | public class ResolutionWrapper 4 | { 5 | public string Type { get; set; } 6 | } 7 | } -------------------------------------------------------------------------------- /FluentTc/Domain/RevisionsList.cs: -------------------------------------------------------------------------------- 1 | namespace FluentTc.Domain 2 | { 3 | using System.Collections.Generic; 4 | 5 | public class RevisionsList 6 | { 7 | public List Revisions { get; set; } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /FluentTc/Domain/RevisionsWrapper.cs: -------------------------------------------------------------------------------- 1 | namespace FluentTc.Domain 2 | { 3 | using System.Collections.Generic; 4 | 5 | public class RevisionsWrapper 6 | { 7 | public int Count { get; set; } 8 | public List Revision { get; set; } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /FluentTc/Domain/Role.cs: -------------------------------------------------------------------------------- 1 | namespace FluentTc.Domain 2 | { 3 | public class Role 4 | { 5 | public string Href { get; set; } 6 | public string Scope { get; set; } 7 | public string RoleId { get; set; } 8 | 9 | public override string ToString() 10 | { 11 | return RoleId; 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /FluentTc/Domain/RoleWrapper.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace FluentTc.Domain 4 | { 5 | public class RoleWrapper 6 | { 7 | public List Role { get; set; } 8 | } 9 | } -------------------------------------------------------------------------------- /FluentTc/Domain/SnapshotDependencies.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace FluentTc.Domain 4 | { 5 | public class SnapshotDependencies 6 | { 7 | public override string ToString() 8 | { 9 | return "snapshot-dependencies"; 10 | } 11 | 12 | public List SnapshotDependency { get; set; } 13 | } 14 | } -------------------------------------------------------------------------------- /FluentTc/Domain/SnapshotDependency.cs: -------------------------------------------------------------------------------- 1 | namespace FluentTc.Domain 2 | { 3 | using JsonFx.Json; 4 | 5 | public class SnapshotDependency 6 | { 7 | public override string ToString() 8 | { 9 | return "snapshot_dependency"; 10 | } 11 | 12 | public string Id { get; set; } 13 | 14 | public string Type { get; set; } 15 | 16 | public Properties Properties { get; set; } 17 | 18 | [JsonName("source-buildType")] 19 | public SourceBuildType SourceBuildType { get; set; } 20 | } 21 | } -------------------------------------------------------------------------------- /FluentTc/Domain/SourceBuildType.cs: -------------------------------------------------------------------------------- 1 | namespace FluentTc.Domain 2 | { 3 | public class SourceBuildType 4 | { 5 | public override string ToString() 6 | { 7 | return "source-buildType"; 8 | } 9 | 10 | public string Id { get; set; } 11 | public string Name { get; set; } 12 | public string ProjectName { get; set; } 13 | public string ProjectId { get; set; } 14 | public string Href { get; set; } 15 | public string WebUrl { get; set; } 16 | } 17 | } -------------------------------------------------------------------------------- /FluentTc/Domain/Test.cs: -------------------------------------------------------------------------------- 1 | using System.Text.RegularExpressions; 2 | 3 | namespace FluentTc.Domain 4 | { 5 | public class Test 6 | { 7 | private static readonly Regex IdRegex = new Regex("^\\/httpAuth\\/app\\/rest/tests\\/id\\:(?\\-?\\d+)$", RegexOptions.Compiled); 8 | 9 | public string Id 10 | { 11 | get 12 | { 13 | return Test.IdRegex.Match(Href).Groups["id"].Value; 14 | } 15 | } 16 | 17 | public string Name { get; set; } 18 | 19 | public string Href { get; set; } 20 | } 21 | } -------------------------------------------------------------------------------- /FluentTc/Domain/TestOccurrence.cs: -------------------------------------------------------------------------------- 1 | namespace FluentTc.Domain 2 | { 3 | public class TestOccurrence 4 | { 5 | public int Duration { get; set; } 6 | 7 | public string Href { get; set; } 8 | 9 | public string Id { get; set; } 10 | 11 | public string Name { get; set; } 12 | 13 | public string Status { get; set; } 14 | 15 | public string Details { get; set; } 16 | 17 | public Test Test { get; set; } 18 | } 19 | } -------------------------------------------------------------------------------- /FluentTc/Domain/TestOccurrenceWrapper.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace FluentTc.Domain 4 | { 5 | public class TestOccurrenceWrapper 6 | { 7 | public string Count { get; set; } 8 | 9 | public List TestOccurrence { get; set; } 10 | } 11 | } -------------------------------------------------------------------------------- /FluentTc/Domain/TestOccurrences.cs: -------------------------------------------------------------------------------- 1 | namespace FluentTc.Domain 2 | { 3 | public interface ITestOccurrences 4 | { 5 | int Count { get; } 6 | string Href { get; } 7 | int Passed { get; } 8 | int Failed { get; } 9 | int NewFailed { get; } 10 | int Muted { get; } 11 | int Ignored { get; } 12 | } 13 | 14 | public class TestOccurrences : ITestOccurrences 15 | { 16 | public int Count { get; set; } 17 | 18 | public string Href { get; set; } 19 | 20 | public int Passed { get; set; } 21 | public int Failed { get; set; } 22 | public int NewFailed { get; set; } 23 | public int Muted { get; set; } 24 | public int Ignored { get; set; } 25 | } 26 | } -------------------------------------------------------------------------------- /FluentTc/Domain/User.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace FluentTc.Domain 4 | { 5 | public class User 6 | { 7 | public string Username { get; set; } 8 | public string Name { get; set; } 9 | public string Id { get; set; } 10 | public string Href { get; set; } 11 | public string Email { get; set; } 12 | public string Realm { get; set; } 13 | public DateTime LastLogin { get; set; } 14 | 15 | public Properties Properties { get; set; } 16 | public RoleWrapper Roles { get; set; } 17 | public UserGroupWrapper Groups { get; set; } 18 | 19 | public override string ToString() 20 | { 21 | return Username; 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /FluentTc/Domain/UserGroupWrapper.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace FluentTc.Domain 4 | { 5 | public class UserGroupWrapper 6 | { 7 | public List Group { get; set; } 8 | } 9 | } -------------------------------------------------------------------------------- /FluentTc/Domain/UserWrapper.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace FluentTc.Domain 4 | { 5 | public class UserWrapper 6 | { 7 | public List User { get; set; } 8 | } 9 | } -------------------------------------------------------------------------------- /FluentTc/Domain/VcsRoot.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace FluentTc.Domain 4 | { 5 | public class VcsRoot 6 | { 7 | public string Id { get; set; } 8 | public string vcsName { get; set; } 9 | public string Href { get; set; } 10 | public string Name { get; set; } 11 | public string Version { get; set; } 12 | public string Status { get; set; } 13 | public DateTime lastChecked { get; set; } 14 | 15 | public override string ToString() 16 | { 17 | return Name; 18 | } 19 | 20 | public Properties Properties { get; set; } 21 | 22 | public Project Project { get; set; } 23 | } 24 | } -------------------------------------------------------------------------------- /FluentTc/Domain/VcsRootEntries.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace FluentTc.Domain 4 | { 5 | public class VcsRootEntries 6 | { 7 | public override string ToString() 8 | { 9 | return "vcs-root-entries"; 10 | } 11 | 12 | public List VcsRootEntry { get; set; } 13 | } 14 | } -------------------------------------------------------------------------------- /FluentTc/Domain/VcsRootEntry.cs: -------------------------------------------------------------------------------- 1 | namespace FluentTc.Domain 2 | { 3 | public class VcsRootEntry 4 | { 5 | public override string ToString() 6 | { 7 | return "vcs-root-entry"; 8 | } 9 | 10 | public VcsRoot VcsRoot { get; set; } 11 | public string CheckoutRules { get; set; } 12 | } 13 | } -------------------------------------------------------------------------------- /FluentTc/Engine/AgentEnabler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using EasyHttp.Http; 3 | using FluentTc.Locators; 4 | 5 | namespace FluentTc.Engine 6 | { 7 | internal interface IAgentEnabler 8 | { 9 | void DisableAgent(Action having); 10 | void EnableAgent(Action having); 11 | } 12 | 13 | internal class AgentEnabler : IAgentEnabler 14 | { 15 | private readonly IAgentHavingBuilderFactory m_AgentHavingBuilderFactory; 16 | private readonly ITeamCityCaller m_TeamCityCaller; 17 | 18 | public AgentEnabler(IAgentHavingBuilderFactory agentHavingBuilderFactory, ITeamCityCaller teamCityCaller) 19 | { 20 | m_AgentHavingBuilderFactory = agentHavingBuilderFactory; 21 | m_TeamCityCaller = teamCityCaller; 22 | } 23 | 24 | public void DisableAgent(Action having) 25 | { 26 | ToggleAgent(having, bool.FalseString); 27 | } 28 | 29 | public void EnableAgent(Action having) 30 | { 31 | ToggleAgent(having, bool.TrueString); 32 | } 33 | 34 | private void ToggleAgent(Action having, string enabled) 35 | { 36 | var agentHavingBuilder = m_AgentHavingBuilderFactory.CreateAgentHavingBuilder(); 37 | having(agentHavingBuilder); 38 | var locator = agentHavingBuilder.GetLocator(); 39 | m_TeamCityCaller.PutFormat(enabled, HttpContentTypes.TextPlain, "/app/rest/agents/{0}/enabled", 40 | locator); 41 | } 42 | } 43 | } -------------------------------------------------------------------------------- /FluentTc/Engine/AgentHavingBuilderFactory.cs: -------------------------------------------------------------------------------- 1 | using FluentTc.Locators; 2 | 3 | namespace FluentTc.Engine 4 | { 5 | internal interface IAgentHavingBuilderFactory 6 | { 7 | AgentHavingBuilder CreateAgentHavingBuilder(); 8 | } 9 | 10 | internal class AgentHavingBuilderFactory : IAgentHavingBuilderFactory 11 | { 12 | public AgentHavingBuilder CreateAgentHavingBuilder() 13 | { 14 | return new AgentHavingBuilder(); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /FluentTc/Engine/AgentsRetriever.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using FluentTc.Domain; 5 | using FluentTc.Exceptions; 6 | using FluentTc.Locators; 7 | 8 | namespace FluentTc.Engine 9 | { 10 | internal interface IAgentsRetriever 11 | { 12 | List GetAgents(Action having); 13 | Agent GetAgent(Action having); 14 | } 15 | 16 | internal class AgentsRetriever : IAgentsRetriever 17 | { 18 | private readonly ITeamCityCaller m_Caller; 19 | private readonly IAgentHavingBuilderFactory m_AgentHavingBuilderFactory; 20 | 21 | public AgentsRetriever(ITeamCityCaller caller, IAgentHavingBuilderFactory agentHavingBuilderFactory) 22 | { 23 | m_Caller = caller; 24 | m_AgentHavingBuilderFactory = agentHavingBuilderFactory; 25 | } 26 | 27 | public List GetAgents(Action having) 28 | { 29 | var agentHavingBuilder = m_AgentHavingBuilderFactory.CreateAgentHavingBuilder(); 30 | having(agentHavingBuilder); 31 | 32 | var locator = agentHavingBuilder.GetLocator(); 33 | var agentWrapper = m_Caller.GetFormat("/app/rest/agents?locator={0}", locator); 34 | if (int.Parse(agentWrapper.Count) > 0) 35 | { 36 | return agentWrapper.Agent; 37 | } 38 | return new List(); 39 | } 40 | 41 | public Agent GetAgent(Action having) 42 | { 43 | var buildConfigurations = GetAgents(having); 44 | if (!buildConfigurations.Any()) throw new AgentNotFoundException(); 45 | if (buildConfigurations.Count() > 1) throw new MoreThanOneAgentFoundException(); 46 | return buildConfigurations.Single(); 47 | } 48 | } 49 | } -------------------------------------------------------------------------------- /FluentTc/Engine/ArtifactsDownloader.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.IO.Abstractions; 3 | 4 | namespace FluentTc.Engine 5 | { 6 | internal interface IArtifactsDownloader 7 | { 8 | IList DownloadArtifacts(int buildId, string destinationPath); 9 | string DownloadArtifact(int buildId, string destinationPath, string fileToDownload); 10 | } 11 | 12 | internal class ArtifactsDownloader : IArtifactsDownloader 13 | { 14 | private readonly ITeamCityCaller m_TeamCityCaller; 15 | private readonly IZipExtractor m_ZipExtractor; 16 | private readonly IFileSystem m_FileSystem; 17 | 18 | public ArtifactsDownloader(ITeamCityCaller teamCityCaller, IZipExtractor zipExtractor, IFileSystem fileSystem) 19 | { 20 | m_TeamCityCaller = teamCityCaller; 21 | m_ZipExtractor = zipExtractor; 22 | m_FileSystem = fileSystem; 23 | } 24 | 25 | public IList DownloadArtifacts(int buildId, string destinationPath) 26 | { 27 | return DownloadAllFiles(buildId, destinationPath); 28 | } 29 | 30 | public string DownloadArtifact(int buildId, string destinationPath, string fileToDownload) 31 | { 32 | return DownloadSpecificFile(buildId, destinationPath, fileToDownload); 33 | } 34 | 35 | private string DownloadSpecificFile(int buildId, string destinationPath, string fileToDownload) 36 | { 37 | var downloadedFile = m_FileSystem.Path.Combine(destinationPath, fileToDownload); 38 | m_TeamCityCaller.GetDownloadFormat( 39 | s => 40 | { 41 | m_FileSystem.File.Move(s, downloadedFile); 42 | }, "/app/rest/builds/id:{0}/artifacts/content/{1}", buildId, fileToDownload); 43 | return downloadedFile; 44 | } 45 | 46 | private IList DownloadAllFiles(int buildId, string destinationPath) 47 | { 48 | IList extractedFiles = null; 49 | m_TeamCityCaller.GetDownloadFormat( 50 | s => 51 | { 52 | extractedFiles = m_ZipExtractor.ExtractZipFile(s, destinationPath); 53 | m_FileSystem.File.Delete(s); 54 | }, "/downloadArtifacts.html?buildId={0}", buildId); 55 | 56 | return extractedFiles ?? new List(); 57 | } 58 | } 59 | } -------------------------------------------------------------------------------- /FluentTc/Engine/BuildConfigurationCreator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using EasyHttp.Http; 3 | using FluentTc.Domain; 4 | using FluentTc.Locators; 5 | 6 | namespace FluentTc.Engine 7 | { 8 | internal interface IBuildConfigurationCreator 9 | { 10 | BuildConfiguration Create(Action having, string buildConfigurationName); 11 | } 12 | 13 | internal class BuildConfigurationCreator : IBuildConfigurationCreator 14 | { 15 | private readonly ITeamCityCaller m_TeamCityCaller; 16 | private readonly IBuildProjectHavingBuilderFactory m_BuildProjectHavingBuilderFactory; 17 | 18 | public BuildConfigurationCreator(ITeamCityCaller teamCityCaller, IBuildProjectHavingBuilderFactory buildProjectHavingBuilderFactory) 19 | { 20 | m_TeamCityCaller = teamCityCaller; 21 | m_BuildProjectHavingBuilderFactory = buildProjectHavingBuilderFactory; 22 | } 23 | 24 | public BuildConfiguration Create(Action having, string buildConfigurationName) 25 | { 26 | var buildProjectHavingBuilder = m_BuildProjectHavingBuilderFactory.CreateBuildProjectHavingBuilder(); 27 | having(buildProjectHavingBuilder); 28 | return m_TeamCityCaller.PostFormat(buildConfigurationName, HttpContentTypes.TextPlain, HttpContentTypes.ApplicationJson, "/app/rest/projects/{0}/buildTypes", buildProjectHavingBuilder.GetLocator()); 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /FluentTc/Engine/BuildConfigurationTemplateRetriever.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Net; 4 | using EasyHttp.Infrastructure; 5 | using FluentTc.Domain; 6 | using FluentTc.Locators; 7 | 8 | namespace FluentTc.Engine 9 | { 10 | internal interface IBuildConfigurationTemplateRetriever 11 | { 12 | List GetAllBuildConfigurationTemplates(); 13 | BuildConfiguration GetBuildConfigurationTemplate(Action having); 14 | } 15 | 16 | internal class BuildConfigurationTemplateRetriever : IBuildConfigurationTemplateRetriever 17 | { 18 | private readonly ITeamCityCaller m_TeamCityCaller; 19 | 20 | public BuildConfigurationTemplateRetriever(ITeamCityCaller teamCityCaller) 21 | { 22 | m_TeamCityCaller = teamCityCaller; 23 | } 24 | 25 | public List GetAllBuildConfigurationTemplates() 26 | { 27 | try 28 | { 29 | var buildWrapper = m_TeamCityCaller.GetFormat("/app/rest/buildTypes?locator=templateFlag:true"); 30 | if (buildWrapper == null || buildWrapper.BuildType == null) return new List(); 31 | return buildWrapper.BuildType; 32 | } 33 | catch (HttpException httpException) 34 | { 35 | if (httpException.StatusCode == HttpStatusCode.NotFound) return new List(); 36 | throw; 37 | } 38 | } 39 | 40 | public BuildConfiguration GetBuildConfigurationTemplate(Action having) 41 | { 42 | var buildConfigurationHavingBuilder = new BuildConfigurationTemplateHavingBuilder(); 43 | having(buildConfigurationHavingBuilder); 44 | var locator = buildConfigurationHavingBuilder.GetLocator(); 45 | 46 | return m_TeamCityCaller.GetFormat("/app/rest/buildTypes/{0}", locator); 47 | } 48 | } 49 | } -------------------------------------------------------------------------------- /FluentTc/Engine/BuildIncludeBuilderFactory.cs: -------------------------------------------------------------------------------- 1 | using FluentTc.Locators; 2 | 3 | namespace FluentTc.Engine 4 | { 5 | internal interface IBuildIncludeBuilderFactory 6 | { 7 | BuildIncludeBuilder CreateBuildIncludeBuilder(); 8 | } 9 | 10 | internal class BuildIncludeBuilderFactory : IBuildIncludeBuilderFactory 11 | { 12 | public BuildIncludeBuilder CreateBuildIncludeBuilder() 13 | { 14 | return new BuildIncludeBuilder(); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /FluentTc/Engine/BuildModelToBuildConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using FluentTc.Domain; 5 | using FluentTc.Locators; 6 | 7 | namespace FluentTc.Engine 8 | { 9 | internal interface IBuildModelToBuildConverter 10 | { 11 | IList ConvertToBuilds(BuildWrapper buildWrapper); 12 | IBuild ConvertToBuild(BuildModel buildModel); 13 | } 14 | 15 | internal class BuildModelToBuildConverter : IBuildModelToBuildConverter 16 | { 17 | public IList ConvertToBuilds(BuildWrapper buildWrapper) 18 | { 19 | if (int.Parse(buildWrapper.Count) > 0) 20 | { 21 | return buildWrapper.Build.Select(ConvertToBuild).ToList(); 22 | } 23 | return new List(); 24 | } 25 | 26 | public IBuild ConvertToBuild(BuildModel buildModel) 27 | { 28 | List changes = new List(); 29 | 30 | if (buildModel.LastChanges != null) 31 | { 32 | changes = buildModel.LastChanges.Change; 33 | } 34 | else if (buildModel.Revisions != null) 35 | { 36 | changes = buildModel.Revisions.Revision; 37 | } 38 | 39 | var buildConfiguration = buildModel.BuildType ?? new BuildConfiguration { Id = buildModel.BuildTypeId }; 40 | 41 | return new Build(buildModel.Id, buildModel.Number, 42 | ConvertBuildStatus(buildModel), 43 | buildModel.StartDate, buildModel.FinishDate, buildModel.QueuedDate, buildConfiguration, 44 | buildModel.Agent, changes, buildModel.WebUrl, 45 | buildModel.Properties, buildModel.TestOccurrences, ConvertBuildState(buildModel)); 46 | } 47 | 48 | private static BuildStatus? ConvertBuildStatus(BuildModel buildModel) 49 | { 50 | if (buildModel.Status == null) 51 | return null; 52 | BuildStatus result; 53 | if (!Enum.TryParse(buildModel.Status, true, out result)) 54 | return null; 55 | return result; 56 | } 57 | 58 | private static BuildState? ConvertBuildState(BuildModel buildModel) 59 | { 60 | if (buildModel.State == null) 61 | return null; 62 | BuildState result; 63 | if (!Enum.TryParse(buildModel.State, true, out result)) 64 | return null; 65 | return result; 66 | } 67 | } 68 | } -------------------------------------------------------------------------------- /FluentTc/Engine/BuildQueueIdHavingBuilderFactory.cs: -------------------------------------------------------------------------------- 1 | using FluentTc.Locators; 2 | 3 | namespace FluentTc.Engine 4 | { 5 | internal interface IBuildQueueIdHavingBuilderFactory 6 | { 7 | BuildQueueIdHavingBuilder CreateBuildQueueIdHavingBuilder(); 8 | } 9 | 10 | internal class BuildQueueIdHavingBuilderFactory : IBuildQueueIdHavingBuilderFactory 11 | { 12 | public BuildQueueIdHavingBuilder CreateBuildQueueIdHavingBuilder() 13 | { 14 | return new BuildQueueIdHavingBuilder(); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /FluentTc/Engine/BuildQueueRemover.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using FluentTc.Locators; 3 | 4 | namespace FluentTc.Engine 5 | { 6 | internal interface IBuildQueueRemover 7 | { 8 | void RemoveBuildFromQueue(Action having); 9 | void RemoveBuildFromQueue(Action having); 10 | } 11 | 12 | internal class BuildQueueRemover : IBuildQueueRemover 13 | { 14 | private readonly ITeamCityCaller m_TeamCityCaller; 15 | private readonly IQueueHavingBuilderFactory m_QueueHavingBuilderFactory; 16 | private readonly IBuildQueueIdHavingBuilderFactory m_BuildQueueIdHavingBuilderFactory; 17 | 18 | public BuildQueueRemover(ITeamCityCaller teamCityCaller, IQueueHavingBuilderFactory queueHavingBuilderFactory, IBuildQueueIdHavingBuilderFactory buildQueueIdHavingBuilderFactory) 19 | { 20 | m_TeamCityCaller = teamCityCaller; 21 | m_QueueHavingBuilderFactory = queueHavingBuilderFactory; 22 | m_BuildQueueIdHavingBuilderFactory = buildQueueIdHavingBuilderFactory; 23 | } 24 | 25 | public void RemoveBuildFromQueue(Action having) 26 | { 27 | var buildProjectHavingBuilder = m_QueueHavingBuilderFactory.CreateBuildProjectHavingBuilder(); 28 | having(buildProjectHavingBuilder); 29 | var locator = "?locator=" + buildProjectHavingBuilder.GetLocator(); 30 | RemoveFromQueuebyLocator(locator); 31 | } 32 | 33 | public void RemoveBuildFromQueue(Action having) 34 | { 35 | var buildQueueIdHavingBuilder = m_BuildQueueIdHavingBuilderFactory.CreateBuildQueueIdHavingBuilder(); 36 | having(buildQueueIdHavingBuilder); 37 | RemoveFromQueuebyLocator(buildQueueIdHavingBuilder.GetLocator()); 38 | } 39 | 40 | private void RemoveFromQueuebyLocator(string locator) 41 | { 42 | m_TeamCityCaller.DeleteFormat(@"/app/rest/buildQueue/{0}", locator); 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /FluentTc/Engine/BuildStatisticConverter.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using FluentTc.Domain; 3 | using System.Linq; 4 | 5 | namespace FluentTc.Engine 6 | { 7 | internal interface IBuildStatisticConverter 8 | { 9 | IList Convert(BuildStatisticsModel buildStatisticsModel); 10 | } 11 | 12 | internal class BuildStatisticConverter : IBuildStatisticConverter 13 | { 14 | public IList Convert(BuildStatisticsModel buildStatisticsModel) 15 | { 16 | if (string.IsNullOrEmpty(buildStatisticsModel.Count) || int.Parse(buildStatisticsModel.Count) <= 0) 17 | { 18 | return new List(); 19 | } 20 | return buildStatisticsModel.Property.Select(CreateBuildStatistic).ToList(); 21 | } 22 | 23 | private static IBuildStatistic CreateBuildStatistic(Property property) 24 | { 25 | return new BuildStatistic(property.Name, property.Value); 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /FluentTc/Engine/BuildStatisticsRetriever.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using FluentTc.Domain; 4 | using FluentTc.Locators; 5 | 6 | namespace FluentTc.Engine 7 | { 8 | internal interface IBuildStatisticsRetriever 9 | { 10 | IList GetBuildStatistics(Action having); 11 | } 12 | internal class BuildStatisticsRetriever : IBuildStatisticsRetriever 13 | { 14 | private readonly ITeamCityCaller m_Caller; 15 | private readonly IBuildHavingBuilderFactory m_BuildHavingBuilderFactory; 16 | private readonly IBuildStatisticConverter m_BuildStatisticConverter; 17 | 18 | public BuildStatisticsRetriever(ITeamCityCaller caller, IBuildHavingBuilderFactory buildHavingBuilderFactory, IBuildStatisticConverter buildStatisticConverter) 19 | { 20 | m_Caller = caller; 21 | m_BuildHavingBuilderFactory = buildHavingBuilderFactory; 22 | m_BuildStatisticConverter = buildStatisticConverter; 23 | } 24 | 25 | public IList GetBuildStatistics(Action having) 26 | { 27 | var buildHavingBuilder = m_BuildHavingBuilderFactory.CreateBuildHavingBuilder(); 28 | having(buildHavingBuilder); 29 | var locator = buildHavingBuilder.GetLocator(); 30 | var buildStatisticsModel = m_Caller.GetFormat("/app/rest/builds/{0}/statistics", locator); 31 | 32 | return m_BuildStatisticConverter.Convert(buildStatisticsModel); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /FluentTc/Engine/BuildTemplateAttacher.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using EasyHttp.Http; 3 | using FluentTc.Locators; 4 | 5 | namespace FluentTc.Engine 6 | { 7 | internal interface IBuildTemplateAttacher 8 | { 9 | void Attach(Action having, string buildTemplateId); 10 | } 11 | 12 | internal class BuildTemplateAttacher : IBuildTemplateAttacher 13 | { 14 | private readonly IBuildConfigurationHavingBuilderFactory m_BuildConfigurationHavingBuilderFactory; 15 | private readonly ITeamCityCaller m_TeamCityCaller; 16 | 17 | public BuildTemplateAttacher(ITeamCityCaller teamCityCaller, IBuildConfigurationHavingBuilderFactory buildConfigurationHavingBuilderFactory) 18 | { 19 | m_TeamCityCaller = teamCityCaller; 20 | m_BuildConfigurationHavingBuilderFactory = buildConfigurationHavingBuilderFactory; 21 | } 22 | 23 | public void Attach(Action having, string buildTemplateId) 24 | { 25 | var buildConfigurationHavingBuilder = m_BuildConfigurationHavingBuilderFactory.CreateBuildConfigurationHavingBuilder(); 26 | having(buildConfigurationHavingBuilder); 27 | m_TeamCityCaller.PutFormat(buildTemplateId, HttpContentTypes.TextPlain, "/app/rest/buildTypes/{0}/template", buildConfigurationHavingBuilder.GetLocator()); 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /FluentTc/Engine/ChangedFilesParser.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO.Abstractions; 4 | using System.Linq; 5 | using FluentTc.Domain; 6 | 7 | namespace FluentTc.Engine 8 | { 9 | public interface IChangedFilesParser 10 | { 11 | IList ParseChangedFiles(string changedFilesPath); 12 | } 13 | 14 | public class ChangedFilesParser : IChangedFilesParser 15 | { 16 | private readonly IFileSystem m_FileSystem; 17 | private readonly char m_AltDirectorySeparatorChar; 18 | private readonly char m_DirectorySeparatorChar; 19 | 20 | public ChangedFilesParser(IFileSystem fileSystem) 21 | { 22 | m_FileSystem = fileSystem; 23 | m_AltDirectorySeparatorChar = m_FileSystem.Path.AltDirectorySeparatorChar; 24 | m_DirectorySeparatorChar = m_FileSystem.Path.DirectorySeparatorChar; 25 | } 26 | 27 | public IList ParseChangedFiles(string changedFilesPath) 28 | { 29 | return m_FileSystem.File.ReadAllLines(changedFilesPath) 30 | .Select(ParseChangedFile).ToList(); 31 | } 32 | 33 | private IChangedFile ParseChangedFile(string fileLine) 34 | { 35 | var lineParts = fileLine.Split(':'); 36 | if (lineParts.Length < 2) 37 | { 38 | throw new ArgumentException("Could not parse line " + fileLine); 39 | } 40 | 41 | var relativeFilePath = lineParts[0].Replace(m_AltDirectorySeparatorChar, m_DirectorySeparatorChar); 42 | return new ChangedFile(relativeFilePath, GetChangeStatus(lineParts[1]), lineParts[2]); 43 | } 44 | 45 | private static FileChangeStatus GetChangeStatus(string fileChangeStatus) 46 | { 47 | FileChangeStatus result; 48 | if (Enum.TryParse(fileChangeStatus, true, out result)) 49 | { 50 | return result; 51 | } 52 | throw new ArgumentException("Could not parse FileStatusChange: " + fileChangeStatus); 53 | } 54 | } 55 | } -------------------------------------------------------------------------------- /FluentTc/Engine/ChangesRetriever.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using FluentTc.Domain; 4 | using FluentTc.Locators; 5 | 6 | namespace FluentTc.Engine 7 | { 8 | internal interface IChangesRetriever 9 | { 10 | List GetChanges(Action having, Action include); 11 | } 12 | 13 | internal class ChangesRetriever : IChangesRetriever 14 | { 15 | private readonly ITeamCityCaller m_TeamCityCaller; 16 | private readonly IBuildHavingBuilderFactory m_BuildHavingBuilderFactory; 17 | 18 | public ChangesRetriever(ITeamCityCaller teamCityCaller, IBuildHavingBuilderFactory buildHavingBuilderFactory) 19 | { 20 | m_TeamCityCaller = teamCityCaller; 21 | m_BuildHavingBuilderFactory = buildHavingBuilderFactory; 22 | } 23 | 24 | public List GetChanges(Action having, Action include) 25 | { 26 | var changesHavingBuilder = new ChangesHavingBuilder(m_BuildHavingBuilderFactory); 27 | having(changesHavingBuilder); 28 | var changesIncludeBuilder = new ChangesIncludeBuilder(); 29 | include(changesIncludeBuilder); 30 | var columns = changesIncludeBuilder.GetColumns(); 31 | var locator = changesHavingBuilder.GetLocator(); 32 | 33 | return m_TeamCityCaller.GetFormat(@"/app/rest/changes?locator={0}&fields=change({1})", locator, columns).Change; 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /FluentTc/Engine/CountBuilderFactory.cs: -------------------------------------------------------------------------------- 1 | using FluentTc.Locators; 2 | 3 | namespace FluentTc.Engine 4 | { 5 | internal interface ICountBuilderFactory 6 | { 7 | CountBuilder CreateCountBuilder(); 8 | } 9 | 10 | internal class CountBuilderFactory : ICountBuilderFactory 11 | { 12 | public CountBuilder CreateCountBuilder() 13 | { 14 | return new CountBuilder(); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /FluentTc/Engine/HttpClientWrapper.cs: -------------------------------------------------------------------------------- 1 | using EasyHttp.Http; 2 | 3 | namespace FluentTc.Engine 4 | { 5 | internal interface IHttpClientWrapper 6 | { 7 | void SetRequestAccept(string accept); 8 | void SetRequestBasicAuthentication(string userName, string password, bool b); 9 | HttpResponse Get(string url); 10 | HttpResponse GetAsFile(string url, string tempFileName); 11 | HttpResponse Post(string url, object data, string textPlain, object query = null); 12 | bool ThrowExceptionOnHttpError { set; } 13 | HttpResponse Response { get; } 14 | HttpRequest Request { get; } 15 | void Delete(string createUrl); 16 | void Put(string createUrl, object data, string contenttype, object query = null); 17 | } 18 | 19 | internal class HttpClientWrapper : IHttpClientWrapper 20 | { 21 | private readonly HttpClient m_HttpClient; 22 | 23 | public HttpClientWrapper() 24 | { 25 | m_HttpClient = new HttpClient(new TeamcityJsonEncoderDecoderConfiguration()); 26 | } 27 | 28 | public void SetRequestAccept(string accept) 29 | { 30 | m_HttpClient.Request.Accept = accept; 31 | } 32 | 33 | public void SetRequestBasicAuthentication(string userName, string password, bool forceBasicAuth) 34 | { 35 | m_HttpClient.Request.SetBasicAuthentication(userName, password); 36 | m_HttpClient.Request.ForceBasicAuth = forceBasicAuth; 37 | } 38 | 39 | public HttpResponse Get(string url) 40 | { 41 | return m_HttpClient.Get(url); 42 | } 43 | 44 | public HttpResponse GetAsFile(string url, string tempFileName) 45 | { 46 | return m_HttpClient.GetAsFile(url, tempFileName); 47 | } 48 | 49 | public HttpResponse Post(string url, object data, string textPlain, object query) 50 | { 51 | return m_HttpClient.Post(url, data, textPlain, query); 52 | } 53 | 54 | public bool ThrowExceptionOnHttpError 55 | { 56 | set { m_HttpClient.ThrowExceptionOnHttpError = value; } 57 | } 58 | 59 | public HttpResponse Response 60 | { 61 | get { return m_HttpClient.Response; } 62 | } 63 | 64 | public HttpRequest Request 65 | { 66 | get { return m_HttpClient.Request; } 67 | } 68 | 69 | public void Delete(string createUrl) 70 | { 71 | m_HttpClient.Delete(createUrl); 72 | } 73 | 74 | public void Put(string createUrl, object data, string contenttype, object query = null) 75 | { 76 | m_HttpClient.Put(createUrl, data, contenttype, query); 77 | } 78 | } 79 | } -------------------------------------------------------------------------------- /FluentTc/Engine/HttpClientWrapperFactory.cs: -------------------------------------------------------------------------------- 1 | namespace FluentTc.Engine 2 | { 3 | internal interface IHttpClientWrapperFactory 4 | { 5 | IHttpClientWrapper CreateHttpClientWrapper(); 6 | } 7 | 8 | internal class HttpClientWrapperFactory : IHttpClientWrapperFactory 9 | { 10 | public IHttpClientWrapper CreateHttpClientWrapper() 11 | { 12 | return new HttpClientWrapper(); 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /FluentTc/Engine/IBuildParameterHavingBuilder.cs: -------------------------------------------------------------------------------- 1 | namespace FluentTc.Engine 2 | { 3 | public interface IBuildParameterHavingBuilder 4 | { 5 | void ParameterName(string parameterName); 6 | } 7 | 8 | public class BuildParameterHavingBuilder : IBuildParameterHavingBuilder 9 | { 10 | private string m_ParameterName; 11 | 12 | public string GetLocator() 13 | { 14 | return m_ParameterName; 15 | } 16 | 17 | public void ParameterName(string parameterName) 18 | { 19 | m_ParameterName = parameterName; 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /FluentTc/Engine/NewProjectDetailsBuilder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | using FluentTc.Locators; 4 | 5 | namespace FluentTc.Engine 6 | { 7 | public interface INewProjectDetailsBuilder 8 | { 9 | INewProjectDetailsBuilder Name(string newProjectName); 10 | INewProjectDetailsBuilder Id(string newProjectId); 11 | INewProjectDetailsBuilder ParentProject(Action parentProject); 12 | } 13 | 14 | internal class NewProjectDetailsBuilder : INewProjectDetailsBuilder 15 | { 16 | private string m_ProjectName; 17 | private string m_ProjectId; 18 | private string m_ParentLocator; 19 | 20 | public INewProjectDetailsBuilder Name(string newProjectName) 21 | { 22 | m_ProjectName = newProjectName; 23 | return this; 24 | } 25 | 26 | public INewProjectDetailsBuilder Id(string newProjectId) 27 | { 28 | m_ProjectId = newProjectId; 29 | return this; 30 | } 31 | 32 | public INewProjectDetailsBuilder ParentProject(Action parentProject) 33 | { 34 | var buildProjectHavingBuilder = new BuildProjectHavingBuilder(); 35 | parentProject(buildProjectHavingBuilder); 36 | m_ParentLocator = buildProjectHavingBuilder.GetLocator(); 37 | return this; 38 | } 39 | 40 | public string GetDataXml() 41 | { 42 | var dataXmlBuilder = new StringBuilder(); 43 | dataXmlBuilder.AppendFormat(@""); 49 | 50 | if (!string.IsNullOrEmpty(m_ParentLocator)) 51 | { 52 | dataXmlBuilder.AppendFormat("", m_ParentLocator); 53 | } 54 | 55 | dataXmlBuilder.Append(""); 56 | 57 | return dataXmlBuilder.ToString(); 58 | } 59 | } 60 | } -------------------------------------------------------------------------------- /FluentTc/Engine/ProjectCreator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using EasyHttp.Http; 3 | using FluentTc.Domain; 4 | 5 | namespace FluentTc.Engine 6 | { 7 | internal interface IProjectCreator 8 | { 9 | Project CreateProject(Action newProjectDetailsBuilderAction); 10 | } 11 | 12 | internal class ProjectCreator : IProjectCreator 13 | { 14 | private readonly ITeamCityCaller m_TeamCityCaller; 15 | 16 | public ProjectCreator(ITeamCityCaller teamCityCaller) 17 | { 18 | m_TeamCityCaller = teamCityCaller; 19 | } 20 | 21 | public Project CreateProject(Action newProjectDetailsBuilderAction) 22 | { 23 | var newProjectDetailsBuilder = new NewProjectDetailsBuilder(); 24 | newProjectDetailsBuilderAction(newProjectDetailsBuilder); 25 | var dataXml = newProjectDetailsBuilder.GetDataXml(); 26 | return m_TeamCityCaller.PostFormat(dataXml, HttpContentTypes.ApplicationXml, 27 | HttpContentTypes.ApplicationJson, "/app/rest/projects/"); 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /FluentTc/Engine/ProjectPropertySetter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using EasyHttp.Http; 3 | using FluentTc.Locators; 4 | using JsonFx.Serialization.Resolvers; 5 | using JsonFx.Serialization; 6 | using JsonFx.Json; 7 | 8 | namespace FluentTc.Engine 9 | { 10 | internal interface IProjectPropertySetter 11 | { 12 | void SetProjectParameters(Action having, Action parameters); 13 | void DeleteProjectParameter(Action havingProject, Action parameterName); 14 | } 15 | 16 | internal class ProjectPropertySetter : IProjectPropertySetter 17 | { 18 | private readonly ITeamCityCaller m_TeamCityCaller; 19 | private readonly IBuildProjectHavingBuilderFactory m_BuildProjectHavingBuilderFactory; 20 | 21 | public ProjectPropertySetter(ITeamCityCaller teamCityCaller, IBuildProjectHavingBuilderFactory buildProjectHavingBuilderFactory) 22 | { 23 | m_TeamCityCaller = teamCityCaller; 24 | m_BuildProjectHavingBuilderFactory = buildProjectHavingBuilderFactory; 25 | } 26 | 27 | public void SetProjectParameters(Action having, Action parameters) 28 | { 29 | var buildConfigurationHavingBuilder = m_BuildProjectHavingBuilderFactory.CreateBuildProjectHavingBuilder(); 30 | having(buildConfigurationHavingBuilder); 31 | var projectLocator = buildConfigurationHavingBuilder.GetLocator(); 32 | 33 | var writer = new JsonWriter(new DataWriterSettings(new ConventionResolverStrategy(ConventionResolverStrategy.WordCasing.CamelCase))); 34 | 35 | BuildParameterValueBuilder buildParameterValueBuilder = new BuildParameterValueBuilder(); 36 | parameters(buildParameterValueBuilder); 37 | 38 | buildParameterValueBuilder.GetParameters() 39 | .ForEach(p => m_TeamCityCaller.PutFormat(writer.Write(p), HttpContentTypes.ApplicationJson, 40 | "/app/rest/projects/{0}/parameters/{1}", projectLocator, p.Name)); 41 | } 42 | 43 | public void DeleteProjectParameter(Action havingProject, Action parameterName) 44 | { 45 | var buildConfigurationHavingBuilder = m_BuildProjectHavingBuilderFactory.CreateBuildProjectHavingBuilder(); 46 | havingProject(buildConfigurationHavingBuilder); 47 | var projectLocator = buildConfigurationHavingBuilder.GetLocator(); 48 | 49 | var buildParameterHavingBuilder = new BuildParameterHavingBuilder(); 50 | parameterName(buildParameterHavingBuilder); 51 | var parameterNameLocator = buildParameterHavingBuilder.GetLocator(); 52 | 53 | m_TeamCityCaller.DeleteFormat("/app/rest/projects/{0}/parameters/{1}", projectLocator, parameterNameLocator); 54 | } 55 | } 56 | } -------------------------------------------------------------------------------- /FluentTc/Engine/ProjectsRetriever.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using FluentTc.Domain; 4 | using FluentTc.Locators; 5 | using EasyHttp.Http; 6 | 7 | namespace FluentTc.Engine 8 | { 9 | internal interface IProjectsRetriever 10 | { 11 | IList GetProjects(Action having = null); 12 | Project GetProject(string projectId); 13 | 14 | void SetFields(Action having, Action fields); 15 | 16 | } 17 | 18 | internal class ProjectsRetriever : IProjectsRetriever 19 | { 20 | private readonly IBuildProjectHavingBuilderFactory m_BuildProjectHavingBuilderFactory; 21 | private readonly ITeamCityCaller m_TeamCityCaller; 22 | 23 | public ProjectsRetriever(IBuildProjectHavingBuilderFactory buildProjectHavingBuilderFactory, 24 | ITeamCityCaller teamCityCaller) 25 | { 26 | m_BuildProjectHavingBuilderFactory = buildProjectHavingBuilderFactory; 27 | m_TeamCityCaller = teamCityCaller; 28 | } 29 | 30 | public IList GetProjects(Action having = null) 31 | { 32 | var locator = having == null ? string.Empty : GetLocator(having); 33 | return m_TeamCityCaller.GetFormat("/app/rest/projects/{0}", locator).Project; 34 | } 35 | 36 | private string GetLocator(Action having) 37 | { 38 | var buildProjectHavingBuilder = m_BuildProjectHavingBuilderFactory.CreateBuildProjectHavingBuilder(); 39 | having(buildProjectHavingBuilder); 40 | return buildProjectHavingBuilder.GetLocator(); 41 | } 42 | 43 | public Project GetProject(string projectId) 44 | { 45 | return m_TeamCityCaller.GetFormat("/app/rest/projects/id:{0}", projectId); 46 | } 47 | 48 | public void SetFields(Action having, Action fields) 49 | { 50 | var projectConfigurationHavingBuilder = 51 | m_BuildProjectHavingBuilderFactory.CreateBuildProjectHavingBuilder(); 52 | having(projectConfigurationHavingBuilder); 53 | 54 | BuildProjectFieldValueBuilder fieldValueBuilder = new BuildProjectFieldValueBuilder(); 55 | fields(fieldValueBuilder); 56 | fieldValueBuilder.GetFields() 57 | .ForEach( 58 | f => 59 | m_TeamCityCaller.PutFormat(f.Value, HttpContentTypes.TextPlain, 60 | "/app/rest/projects/{0}/{1}", projectConfigurationHavingBuilder.GetLocator(), f.Name)); 61 | 62 | } 63 | } 64 | } -------------------------------------------------------------------------------- /FluentTc/Engine/PropertiesFileParser.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.IO.Abstractions; 3 | using System.Text.RegularExpressions; 4 | 5 | namespace FluentTc.Engine 6 | { 7 | internal interface IPropertiesFileParser 8 | { 9 | Dictionary ParsePropertiesFile(string teamCityBuildPropertiesFile); 10 | } 11 | 12 | internal class PropertiesFileParser : IPropertiesFileParser 13 | { 14 | private readonly IFileSystem m_FileSystem; 15 | private static readonly Regex ParsingRegex = new Regex(@"^(?(\w+\.)*\w+)=(?.*)$", RegexOptions.Compiled | RegexOptions.Multiline); 16 | 17 | public PropertiesFileParser(IFileSystem fileSystem) 18 | { 19 | m_FileSystem = fileSystem; 20 | } 21 | 22 | public Dictionary ParsePropertiesFile(string teamCityBuildPropertiesFile) 23 | { 24 | Dictionary parameters = new Dictionary(); 25 | var allLines = m_FileSystem.File.ReadAllLines(teamCityBuildPropertiesFile); 26 | foreach (var line in allLines) 27 | { 28 | var match = ParsingRegex.Match(line); 29 | if (!match.Success) continue; 30 | parameters.Add(match.Groups["Name"].Value, DecodeValue(match.Groups["Value"].Value)); 31 | } 32 | return parameters; 33 | } 34 | 35 | private static string DecodeValue(string parameterValue) 36 | { 37 | return parameterValue.Replace(@"\:",@":").Replace(@"\\", @"\").Replace(@"\=", @"="); 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /FluentTc/Engine/QueueHavingBuilderFactory.cs: -------------------------------------------------------------------------------- 1 | using FluentTc.Locators; 2 | 3 | namespace FluentTc.Engine 4 | { 5 | internal interface IQueueHavingBuilderFactory 6 | { 7 | QueueHavingBuilder CreateBuildProjectHavingBuilder(); 8 | } 9 | 10 | internal class QueueHavingBuilderFactory : IQueueHavingBuilderFactory 11 | { 12 | private readonly ILocatorBuilder m_LocatorBuilder; 13 | 14 | public QueueHavingBuilderFactory(ILocatorBuilder locatorBuilder) 15 | { 16 | m_LocatorBuilder = locatorBuilder; 17 | } 18 | 19 | public QueueHavingBuilder CreateBuildProjectHavingBuilder() 20 | { 21 | return new QueueHavingBuilder(m_LocatorBuilder); 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /FluentTc/Engine/TeamCityBuildPropertiesFileRetriever.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace FluentTc.Engine 4 | { 5 | internal interface ITeamCityBuildPropertiesFileRetriever 6 | { 7 | string GetTeamCityBuildPropertiesFilePath(); 8 | } 9 | 10 | internal class TeamCityBuildPropertiesFileRetriever : ITeamCityBuildPropertiesFileRetriever 11 | { 12 | private const string TeamcityBuildPropertiesFile = "TEAMCITY_BUILD_PROPERTIES_FILE"; 13 | 14 | public string GetTeamCityBuildPropertiesFilePath() 15 | { 16 | return Environment.GetEnvironmentVariable(TeamcityBuildPropertiesFile); 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /FluentTc/Engine/TeamCityDateFilter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Globalization; 4 | using JsonFx.IO; 5 | using JsonFx.Model; 6 | using JsonFx.Model.Filters; 7 | using JsonFx.Serialization; 8 | 9 | namespace FluentTc.Engine 10 | { 11 | internal class TeamCityDateFilter : ModelFilter 12 | { 13 | private const string DateFormat = "yyyyMMddTHHmmsszz00"; 14 | 15 | public override bool TryRead(DataReaderSettings settings, IStream> tokens, out DateTime value) 16 | { 17 | var token = tokens.Peek(); 18 | if (token == null || token.TokenType != ModelTokenType.Primitive || !(token.Value is string)) 19 | { 20 | value = default(DateTime); 21 | return false; 22 | } 23 | 24 | if (!TryParseDate(token.ValueAsString(), out value)) 25 | { 26 | value = default(DateTime); 27 | return false; 28 | } 29 | 30 | tokens.Pop(); 31 | return true; 32 | } 33 | 34 | public override bool TryWrite(DataWriterSettings settings, DateTime value, out IEnumerable> tokens) 35 | { 36 | tokens = new Token[] 37 | { 38 | ModelGrammar.TokenPrimitive(FormatDate(value)) 39 | }; 40 | 41 | return true; 42 | } 43 | 44 | internal static bool TryParseDate(string date, out DateTime value) 45 | { 46 | return DateTime.TryParseExact(date, DateFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out value); 47 | } 48 | 49 | private static string FormatDate(DateTime value) 50 | { 51 | return value.ToString(DateFormat); 52 | } 53 | } 54 | } -------------------------------------------------------------------------------- /FluentTc/Engine/TeamCityWriterFactory.cs: -------------------------------------------------------------------------------- 1 | using JetBrains.TeamCity.ServiceMessages.Write.Special; 2 | 3 | namespace FluentTc.Engine 4 | { 5 | internal interface ITeamCityWriterFactory 6 | { 7 | ITeamCityWriter CreateTeamCityWriter(); 8 | } 9 | 10 | internal class TeamCityWriterFactory : ITeamCityWriterFactory 11 | { 12 | private readonly ITeamCityServiceMessages m_CityServiceMessages; 13 | 14 | public TeamCityWriterFactory(ITeamCityServiceMessages cityServiceMessages) 15 | { 16 | m_CityServiceMessages = cityServiceMessages; 17 | } 18 | 19 | public ITeamCityWriter CreateTeamCityWriter() 20 | { 21 | return m_CityServiceMessages.CreateWriter(); 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /FluentTc/Engine/TeamcityJsonEncoderDecoderConfiguration.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using EasyHttp.Codecs; 3 | using EasyHttp.Codecs.JsonFXExtensions; 4 | using EasyHttp.Configuration; 5 | using JsonFx.Json; 6 | using JsonFx.Serialization; 7 | 8 | namespace FluentTc.Engine 9 | { 10 | internal class TeamcityJsonEncoderDecoderConfiguration : IEncoderDecoderConfiguration 11 | { 12 | public IEncoder GetEncoder() 13 | { 14 | var jsonWriter = new JsonWriter(new DataWriterSettings(DefaultEncoderDecoderConfiguration.CombinedResolverStrategy() 15 | , new TeamCityDateFilter()), new[] { "application/.*json", "text/.*json" }); 16 | 17 | var writers = new List { jsonWriter }; 18 | var dataWriterProvider = new RegExBasedDataWriterProvider(new List { jsonWriter }); 19 | return new DefaultEncoder(dataWriterProvider); 20 | } 21 | 22 | public IDecoder GetDecoder() 23 | { 24 | var jsonReader = new JsonReader(new DataReaderSettings(DefaultEncoderDecoderConfiguration.CombinedResolverStrategy() 25 | , new TeamCityDateFilter()), new[] { "application/.*json", "text/.*json" }); 26 | 27 | var readers = new List { jsonReader }; 28 | var dataReaderProvider = new RegExBasedDataReaderProvider(readers); 29 | var defaultDecoder = new DefaultDecoder(dataReaderProvider) 30 | { 31 | ShouldRemoveAtSign = true 32 | }; 33 | return defaultDecoder; 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /FluentTc/Engine/UniversalTypeConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Globalization; 3 | 4 | namespace FluentTc.Engine 5 | { 6 | public static class UniversalTypeConverter 7 | { 8 | public static T StringToType(string value) 9 | { 10 | return (T) StringToType(value, typeof(T)); 11 | } 12 | 13 | private static object StringToType(string value, Type propertyType) 14 | { 15 | var underlyingType = Nullable.GetUnderlyingType(propertyType); 16 | if (underlyingType == null) 17 | return Convert.ChangeType(value, propertyType, CultureInfo.InvariantCulture); 18 | return String.IsNullOrEmpty(value) 19 | ? null 20 | : Convert.ChangeType(value, underlyingType, CultureInfo.InvariantCulture); 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /FluentTc/Engine/UserRetriever.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using FluentTc.Domain; 4 | using FluentTc.Locators; 5 | 6 | namespace FluentTc.Engine 7 | { 8 | internal interface IUserRetriever 9 | { 10 | List GetAllUsers(); 11 | User GetUser(Action having); 12 | } 13 | 14 | internal class UserRetriever : IUserRetriever 15 | { 16 | private readonly ITeamCityCaller m_TeamCityCaller; 17 | private readonly IUserHavingBuilderFactory m_UserHavingBuilderFactory; 18 | 19 | public UserRetriever(ITeamCityCaller teamCityCaller, IUserHavingBuilderFactory userHavingBuilderFactory) 20 | { 21 | m_TeamCityCaller = teamCityCaller; 22 | m_UserHavingBuilderFactory = userHavingBuilderFactory; 23 | } 24 | 25 | public List GetAllUsers() 26 | { 27 | return m_TeamCityCaller.GetFormat("/app/rest/users/").User; 28 | } 29 | 30 | public User GetUser(Action having) 31 | { 32 | var userHavingBuilder = m_UserHavingBuilderFactory.CreateUserHavingBuilder(); 33 | having(userHavingBuilder); 34 | 35 | return m_TeamCityCaller.GetFormat(@"/app/rest/users/{0}", userHavingBuilder.GetLocator()); 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /FluentTc/Engine/VCSRootAttacher.cs: -------------------------------------------------------------------------------- 1 | using EasyHttp.Http; 2 | using FluentTc.Domain; 3 | using FluentTc.Locators; 4 | using System; 5 | using System.Security; 6 | 7 | namespace FluentTc.Engine 8 | { 9 | internal interface IVCSRootAttacher 10 | { 11 | void Attach(Action having, Action vcsRootEntryHaving); 12 | } 13 | 14 | internal class VCSRootAttacher: IVCSRootAttacher 15 | { 16 | private readonly IBuildConfigurationHavingBuilderFactory m_BuildConfigurationHavingBuilderFactory; 17 | private readonly ITeamCityCaller m_TeamCityCaller; 18 | 19 | public VCSRootAttacher(ITeamCityCaller teamCityCaller, IBuildConfigurationHavingBuilderFactory buildConfigurationHavingBuilderFactory) 20 | { 21 | m_TeamCityCaller = teamCityCaller; 22 | m_BuildConfigurationHavingBuilderFactory = buildConfigurationHavingBuilderFactory; 23 | } 24 | 25 | public void Attach(Action having, Action vcsRootEntryHaving) 26 | { 27 | var buildConfigurationHavingBuilder = m_BuildConfigurationHavingBuilderFactory.CreateBuildConfigurationHavingBuilder(); 28 | having(buildConfigurationHavingBuilder); 29 | 30 | var vcsRootEntryBuilder = new VCSRootEntryBuilder(); 31 | vcsRootEntryHaving(vcsRootEntryBuilder); 32 | var vcsRootEntry = vcsRootEntryBuilder.GetVCSRootEntry(); 33 | 34 | string xmlData = string.Format( 35 | @" 36 | 37 | {1} 38 | ", 39 | SecurityElement.Escape(vcsRootEntry.VcsRoot.Id), 40 | SecurityElement.Escape(vcsRootEntry.CheckoutRules)); 41 | 42 | m_TeamCityCaller.PostFormat( 43 | xmlData, 44 | HttpContentTypes.ApplicationXml, 45 | "/app/rest/buildTypes/{0}/vcs-root-entries", 46 | buildConfigurationHavingBuilder.GetLocator()); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /FluentTc/Engine/VCSRootCreator.cs: -------------------------------------------------------------------------------- 1 | using EasyHttp.Http; 2 | using FluentTc.Domain; 3 | using FluentTc.Locators; 4 | using System; 5 | using System.Security; 6 | using System.Text; 7 | 8 | namespace FluentTc.Engine 9 | { 10 | internal interface IVCSRootCreator 11 | { 12 | VcsRoot Create(Action having); 13 | } 14 | 15 | internal class VCSRootCreator: IVCSRootCreator 16 | { 17 | private readonly ITeamCityCaller m_TeamCityCaller; 18 | 19 | public VCSRootCreator(ITeamCityCaller teamCityCaller) 20 | { 21 | m_TeamCityCaller = teamCityCaller; 22 | } 23 | 24 | public VcsRoot Create(Action having) 25 | { 26 | var gitVCSBuilder = new GitVCSRootBuilder(); 27 | 28 | having(gitVCSBuilder); 29 | 30 | var vcs = gitVCSBuilder.GetVCSRoot(); 31 | 32 | StringBuilder xmlData = new StringBuilder(); 33 | xmlData.AppendFormat( 34 | @" ", 35 | SecurityElement.Escape(vcs.Id), 36 | SecurityElement.Escape(vcs.Name), 37 | SecurityElement.Escape(vcs.vcsName), 38 | SecurityElement.Escape(vcs.Project.Id), 39 | vcs.Properties.Property.Count); 40 | 41 | foreach (var property in vcs.Properties.Property) 42 | { 43 | xmlData.Append(@"", SecurityElement.Escape(property.Value)); 46 | } 47 | xmlData.Append(@""); 48 | 49 | xmlData.Append(@""); 50 | m_TeamCityCaller.Post( 51 | xmlData.ToString(), 52 | HttpContentTypes.ApplicationXml, 53 | "/app/rest/vcs-roots", 54 | HttpContentTypes.ApplicationJson); 55 | return vcs; 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /FluentTc/Engine/ZipExtractor.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.IO; 3 | using System.IO.Abstractions; 4 | using ICSharpCode.SharpZipLib.Core; 5 | using ICSharpCode.SharpZipLib.Zip; 6 | 7 | namespace FluentTc.Engine 8 | { 9 | internal interface IZipExtractor 10 | { 11 | IList ExtractZipFile(string archiveFilenameIn, string outFolder, string password = null); 12 | } 13 | 14 | internal class ZipExtractor : IZipExtractor 15 | { 16 | private readonly IFileSystem m_FileSystem; 17 | 18 | public ZipExtractor(IFileSystem fileSystem) 19 | { 20 | m_FileSystem = fileSystem; 21 | } 22 | 23 | public IList ExtractZipFile(string archiveFilenameIn, string outFolder, string password = null) 24 | { 25 | ZipFile zf = null; 26 | try 27 | { 28 | var fs = m_FileSystem.File.OpenRead(archiveFilenameIn); 29 | zf = new ZipFile(fs); 30 | if (!string.IsNullOrEmpty(password)) 31 | { 32 | zf.Password = password; // AES encrypted entries are handled automatically 33 | } 34 | var fileList = new List(); 35 | foreach (ZipEntry zipEntry in zf) 36 | { 37 | if (!zipEntry.IsFile) 38 | { 39 | continue; // Ignore directories 40 | } 41 | var entryFileName = zipEntry.Name; 42 | // to remove the folder from the entry:- entryFileName = Path.GetFileName(entryFileName); 43 | // Optionally match entrynames against a selection list here to skip as desired. 44 | // The unpacked length is available in the zipEntry.Size property. 45 | 46 | var buffer = new byte[4096]; // 4K is optimum 47 | var zipStream = zf.GetInputStream(zipEntry); 48 | 49 | // Manipulate the output filename here as desired. 50 | var fullZipToPath = Path.Combine(outFolder, entryFileName); 51 | fileList.Add(fullZipToPath); 52 | var directoryName = Path.GetDirectoryName(fullZipToPath); 53 | if (directoryName.Length > 0) 54 | m_FileSystem.Directory.CreateDirectory(directoryName); 55 | 56 | if (m_FileSystem.File.Exists(fullZipToPath)) 57 | RemoveReadOnly(fullZipToPath); 58 | 59 | // Unzip file in buffered chunks. This is just as fast as unpacking to a buffer the full size 60 | // of the file, but does not waste memory. 61 | // The "using" will close the stream even if an exception occurs. 62 | using (var streamWriter = m_FileSystem.File.Create(fullZipToPath)) 63 | { 64 | StreamUtils.Copy(zipStream, streamWriter, buffer); 65 | } 66 | } 67 | return fileList; 68 | } 69 | finally 70 | { 71 | if (zf != null) 72 | { 73 | zf.IsStreamOwner = true; // Makes close also shut the underlying stream 74 | zf.Close(); // Ensure we release resources 75 | } 76 | } 77 | } 78 | 79 | private void RemoveReadOnly(string filePath) 80 | { 81 | var fileAttributes = m_FileSystem.File.GetAttributes(filePath); 82 | 83 | if ((fileAttributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly) 84 | m_FileSystem.File.SetAttributes(filePath, fileAttributes ^ (FileAttributes.ReadOnly)); 85 | } 86 | } 87 | } -------------------------------------------------------------------------------- /FluentTc/Exceptions/AgentNotFoundException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.Serialization; 3 | 4 | namespace FluentTc.Exceptions 5 | { 6 | [Serializable] 7 | public class AgentNotFoundException : Exception 8 | { 9 | public AgentNotFoundException() 10 | { 11 | } 12 | 13 | public AgentNotFoundException(string message) : base(message) 14 | { 15 | } 16 | 17 | public AgentNotFoundException(string message, Exception innerException) : base(message, innerException) 18 | { 19 | } 20 | 21 | protected AgentNotFoundException(SerializationInfo info, StreamingContext context) : base(info, context) 22 | { 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /FluentTc/Exceptions/BuildConfigurationNotFoundException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.Serialization; 3 | 4 | namespace FluentTc.Exceptions 5 | { 6 | [Serializable] 7 | public class BuildConfigurationNotFoundException : Exception 8 | { 9 | public BuildConfigurationNotFoundException() 10 | { 11 | } 12 | 13 | public BuildConfigurationNotFoundException(string message) : base(message) 14 | { 15 | } 16 | 17 | public BuildConfigurationNotFoundException(string message, Exception innerException) : base(message, innerException) 18 | { 19 | } 20 | 21 | protected BuildConfigurationNotFoundException(SerializationInfo info, StreamingContext context) : base(info, context) 22 | { 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /FluentTc/Exceptions/BuildNotFoundException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.Serialization; 3 | 4 | namespace FluentTc.Exceptions 5 | { 6 | [Serializable] 7 | public class BuildNotFoundException : Exception 8 | { 9 | public BuildNotFoundException() 10 | { 11 | } 12 | 13 | public BuildNotFoundException(string message) : base(message) 14 | { 15 | } 16 | 17 | public BuildNotFoundException(string message, Exception innerException) : base(message, innerException) 18 | { 19 | } 20 | 21 | protected BuildNotFoundException(SerializationInfo info, StreamingContext context) : base(info, context) 22 | { 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /FluentTc/Exceptions/MissingBuildParameterException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.Serialization; 3 | 4 | namespace FluentTc.Exceptions 5 | { 6 | [Serializable] 7 | public class MissingBuildParameterException : Exception 8 | { 9 | private readonly string m_ParameterName; 10 | 11 | public MissingBuildParameterException() 12 | { 13 | } 14 | 15 | public MissingBuildParameterException(string parameterName) : base(string.Format("Build parameter {0} is missing. It needs to be added from TeamCity", parameterName)) 16 | { 17 | m_ParameterName = parameterName; 18 | } 19 | 20 | public MissingBuildParameterException(string parameterName, Exception innerException) 21 | : base(string.Format("Build parameter {0} is missing. It needs to be added from TeamCity", parameterName), innerException) 22 | { 23 | m_ParameterName = parameterName; 24 | } 25 | 26 | protected MissingBuildParameterException(SerializationInfo info, StreamingContext context) : base(info, context) 27 | { 28 | } 29 | 30 | public string ParameterName 31 | { 32 | get { return m_ParameterName; } 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /FluentTc/Exceptions/MoreThanOneAgentFoundException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.Serialization; 3 | 4 | namespace FluentTc.Exceptions 5 | { 6 | [Serializable] 7 | public class MoreThanOneAgentFoundException : Exception 8 | { 9 | public MoreThanOneAgentFoundException() 10 | { 11 | } 12 | 13 | public MoreThanOneAgentFoundException(string message) : base(message) 14 | { 15 | } 16 | 17 | public MoreThanOneAgentFoundException(string message, Exception innerException) : base(message, innerException) 18 | { 19 | } 20 | 21 | protected MoreThanOneAgentFoundException(SerializationInfo info, StreamingContext context) : base(info, context) 22 | { 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /FluentTc/Exceptions/MoreThanOneBuildConfigurationFoundException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.Serialization; 3 | 4 | namespace FluentTc.Exceptions 5 | { 6 | [Serializable] 7 | public class MoreThanOneBuildConfigurationFoundException : Exception 8 | { 9 | public MoreThanOneBuildConfigurationFoundException() 10 | { 11 | } 12 | 13 | public MoreThanOneBuildConfigurationFoundException(string message) : base(message) 14 | { 15 | } 16 | 17 | public MoreThanOneBuildConfigurationFoundException(string message, Exception innerException) : base(message, innerException) 18 | { 19 | } 20 | 21 | protected MoreThanOneBuildConfigurationFoundException(SerializationInfo info, StreamingContext context) : base(info, context) 22 | { 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /FluentTc/Exceptions/MoreThanOneBuildFoundException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.Serialization; 3 | 4 | namespace FluentTc.Exceptions 5 | { 6 | [Serializable] 7 | public class MoreThanOneBuildFoundException : Exception 8 | { 9 | public MoreThanOneBuildFoundException() 10 | { 11 | } 12 | 13 | public MoreThanOneBuildFoundException(string message) : base(message) 14 | { 15 | } 16 | 17 | public MoreThanOneBuildFoundException(string message, Exception innerException) : base(message, innerException) 18 | { 19 | } 20 | 21 | protected MoreThanOneBuildFoundException(SerializationInfo info, StreamingContext context) : base(info, context) 22 | { 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /FluentTc/Extensions/StringExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.Text; 2 | 3 | namespace FluentTc.Extensions 4 | { 5 | public static class StringExtensions 6 | { 7 | public static string FromPascalToCapitalizedCase(this string value) 8 | { 9 | StringBuilder sb = new StringBuilder(value.Length); 10 | 11 | int charCount = 0; 12 | foreach (char c in value) 13 | { 14 | charCount++; 15 | if (char.IsUpper(c) && charCount != value.Length && charCount != 1) 16 | { 17 | sb.Append("_"); 18 | } 19 | sb.Append(char.ToUpper(c)); 20 | } 21 | return sb.ToString(); 22 | } 23 | 24 | public static string FromPascalToCamelCase(this string value) 25 | { 26 | var len = value.Length; 27 | if (len > 0) 28 | { 29 | var sb = new StringBuilder(value.Length); 30 | sb.Append(char.ToLower(value[0])); 31 | if (len > 1) 32 | sb.Append(value.Substring(1, len - 1)); 33 | return sb.ToString(); 34 | } 35 | else 36 | return ""; 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /FluentTc/FluentTc.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | FluentTc 5 | $version$ 6 | Boris Modylevsky, Igor Olikh, Tomer Cohen 7 | Boris Modylevsky 8 | https://github.com/borismod/FluentTc/blob/master/LICENSE 9 | https://github.com/borismod/FluentTc 10 | false 11 | Easy-to-use, readable and comprehensive library for consuming TeamCity REST API. Written using real scenarios in mind, enables variuos range of queries and operation on TeamCity 12 | Copyright © 2015 13 | TeamCity API REST HTTP 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /FluentTc/InvestigationRetriever.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using FluentTc.Domain; 4 | using FluentTc.Engine; 5 | using FluentTc.Locators; 6 | 7 | namespace FluentTc 8 | { 9 | public interface IInvestigationRetriever 10 | { 11 | Investigation GetInvestigation(Action having); 12 | Investigation GetTestInvestigationByTestNameId(string testNameId); 13 | } 14 | 15 | internal class InvestigationRetriever : IInvestigationRetriever 16 | { 17 | private readonly ITeamCityCaller m_TeamCityCaller; 18 | private readonly IBuildConfigurationRetriever m_BuildConfigurationRetriever; 19 | 20 | public InvestigationRetriever(ITeamCityCaller teamCityCaller, 21 | IBuildConfigurationRetriever buildConfigurationRetriever) 22 | { 23 | m_TeamCityCaller = teamCityCaller; 24 | m_BuildConfigurationRetriever = buildConfigurationRetriever; 25 | } 26 | 27 | public Investigation GetInvestigation(Action having) 28 | { 29 | var buildConfiguration = m_BuildConfigurationRetriever.GetSingleBuildConfiguration(having); 30 | var investigations = m_TeamCityCaller.GetFormat("/app/rest/investigations?locator=buildType:(id:{0})", buildConfiguration.Id).Investigation; 31 | if(investigations != null) 32 | return investigations.First(); 33 | 34 | return null; 35 | } 36 | 37 | public Investigation GetTestInvestigationByTestNameId(string testNameId) 38 | { 39 | var investigations = m_TeamCityCaller.GetFormat("/app/rest/investigations?locator=test:(id:{0})", testNameId).Investigation; 40 | if (investigations != null) 41 | return investigations.First(); 42 | 43 | return null; 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /FluentTc/Locators/AgentHavingBuilder.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace FluentTc.Locators 4 | { 5 | public interface IAgentHavingBuilder 6 | { 7 | IAgentHavingBuilder Id(int agentId); 8 | IAgentHavingBuilder Name(string agentName); 9 | IAgentHavingBuilder Connected(); 10 | IAgentHavingBuilder Disconnected(); 11 | IAgentHavingBuilder Enabled(); 12 | IAgentHavingBuilder Disabled(); 13 | IAgentHavingBuilder Authorized(); 14 | IAgentHavingBuilder NotAuthorized(); 15 | IAgentHavingBuilder Ip(string ip); 16 | } 17 | 18 | public class AgentHavingBuilder : IAgentHavingBuilder 19 | { 20 | private const string EnabledPrefix = "enabled:"; 21 | private const string AuthorizedPrefix = "authorized:"; 22 | private const string NamePrefix = "name:"; 23 | private const string ConnectedPrefix = "connected:"; 24 | private const string IdPrefix = "id:"; 25 | 26 | private readonly List m_Having = new List(); 27 | 28 | public IAgentHavingBuilder Name(string agentName) 29 | { 30 | m_Having.Add(NamePrefix + agentName); 31 | return this; 32 | } 33 | 34 | public IAgentHavingBuilder Connected() 35 | { 36 | m_Having.Add(ConnectedPrefix + bool.TrueString); 37 | return this; 38 | } 39 | 40 | public IAgentHavingBuilder Disconnected() 41 | { 42 | m_Having.Add(ConnectedPrefix + bool.FalseString); 43 | return this; 44 | } 45 | 46 | public IAgentHavingBuilder Disabled() 47 | { 48 | m_Having.Add(EnabledPrefix + bool.FalseString); 49 | return this; 50 | } 51 | 52 | public IAgentHavingBuilder Authorized() 53 | { 54 | m_Having.Add(AuthorizedPrefix + bool.TrueString); 55 | return this; 56 | } 57 | 58 | public IAgentHavingBuilder NotAuthorized() 59 | { 60 | m_Having.Add(AuthorizedPrefix + bool.FalseString); 61 | return this; 62 | } 63 | 64 | public IAgentHavingBuilder Ip(string ip) 65 | { 66 | m_Having.Add("ip:" + ip); 67 | return this; 68 | } 69 | 70 | public IAgentHavingBuilder Enabled() 71 | { 72 | m_Having.Add(EnabledPrefix + bool.TrueString); 73 | return this; 74 | } 75 | 76 | public IAgentHavingBuilder Id(int agentId) 77 | { 78 | m_Having.Add(IdPrefix + agentId); 79 | return this; 80 | } 81 | 82 | public string GetLocator() 83 | { 84 | return string.Join(",", m_Having); 85 | } 86 | } 87 | } -------------------------------------------------------------------------------- /FluentTc/Locators/BranchHavingBuilder.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace FluentTc.Locators 4 | { 5 | public interface IBranchHavingBuilder 6 | { 7 | IBranchHavingBuilder Name(string branchName); 8 | IBranchHavingBuilder Default(); 9 | IBranchHavingBuilder NotDefault(); 10 | IBranchHavingBuilder Unspecified(); 11 | IBranchHavingBuilder NotUnspecified(); 12 | IBranchHavingBuilder Branched(); 13 | IBranchHavingBuilder NotBranched(); 14 | } 15 | 16 | public class BranchHavingBuilder : IBranchHavingBuilder 17 | { 18 | private readonly List m_Having = new List(); 19 | 20 | public IBranchHavingBuilder Name(string branchName) 21 | { 22 | m_Having.Add("name:" + branchName); 23 | return this; 24 | } 25 | 26 | public IBranchHavingBuilder Default() 27 | { 28 | m_Having.Add("default:" + bool.TrueString); 29 | return this; 30 | } 31 | 32 | public IBranchHavingBuilder NotDefault() 33 | { 34 | m_Having.Add("default:" + bool.FalseString); 35 | return this; 36 | } 37 | 38 | public IBranchHavingBuilder Unspecified() 39 | { 40 | m_Having.Add("unspecified:" + bool.TrueString); 41 | return this; 42 | } 43 | 44 | public IBranchHavingBuilder NotUnspecified() 45 | { 46 | m_Having.Add("unspecified:" + bool.FalseString); 47 | return this; 48 | } 49 | 50 | public IBranchHavingBuilder Branched() 51 | { 52 | m_Having.Add("branched:" + bool.TrueString); 53 | return this; 54 | } 55 | 56 | public IBranchHavingBuilder NotBranched() 57 | { 58 | m_Having.Add("branched:" + bool.FalseString); 59 | return this; 60 | } 61 | 62 | public virtual string GetLocator() 63 | { 64 | return string.Join(",", m_Having); 65 | } 66 | } 67 | } -------------------------------------------------------------------------------- /FluentTc/Locators/BranchHavingBuilderFactory.cs: -------------------------------------------------------------------------------- 1 | namespace FluentTc.Locators 2 | { 3 | public interface IBranchHavingBuilderFactory 4 | { 5 | BranchHavingBuilder CreateBranchHavingBuilder(); 6 | } 7 | 8 | public class BranchHavingBuilderFactory : IBranchHavingBuilderFactory 9 | { 10 | public BranchHavingBuilder CreateBranchHavingBuilder() 11 | { 12 | return new BranchHavingBuilder(); 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /FluentTc/Locators/BuildAdditionalIncludeBuilder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace FluentTc.Locators 4 | { 5 | public interface IBuildAdditionalIncludeBuilder 6 | { 7 | IBuildAdditionalIncludeBuilder IncludeChanges(Action include); 8 | } 9 | 10 | public class BuildAdditionalIncludeBuilder : IBuildAdditionalIncludeBuilder 11 | { 12 | internal bool ShouldIncludeChanges { get; set; } 13 | 14 | internal Action ChangesInclude { get; set; } 15 | 16 | public BuildAdditionalIncludeBuilder() 17 | { 18 | ChangesInclude = delegate { }; 19 | } 20 | 21 | public IBuildAdditionalIncludeBuilder IncludeChanges(Action include) 22 | { 23 | ShouldIncludeChanges = true; 24 | ChangesInclude = include; 25 | 26 | return this; 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /FluentTc/Locators/BuildConfigurationHavingBuilder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace FluentTc.Locators 5 | { 6 | public interface IBuildConfigurationHavingBuilder 7 | { 8 | IBuildConfigurationHavingBuilder Id(string buildConfigurationId); 9 | IBuildConfigurationHavingBuilder Name(string buildConfigurationName); 10 | IBuildConfigurationHavingBuilder InternalId(string internalId); 11 | IBuildConfigurationHavingBuilder Project(Action projectHavingBuilderAction); 12 | IBuildConfigurationHavingBuilder ProjectRecursively(Action projectHavingBuilderAction); 13 | } 14 | 15 | public class BuildConfigurationHavingBuilder : IBuildConfigurationHavingBuilder 16 | { 17 | private readonly List m_Having = new List(); 18 | private readonly IBuildProjectHavingBuilderFactory m_BuildProjectHavingBuilderFactory; 19 | 20 | public BuildConfigurationHavingBuilder(IBuildProjectHavingBuilderFactory buildProjectHavingBuilderFactory) 21 | { 22 | m_BuildProjectHavingBuilderFactory = buildProjectHavingBuilderFactory; 23 | } 24 | 25 | public IBuildConfigurationHavingBuilder Id(string buildConfigurationId) 26 | { 27 | m_Having.Add("id:" + buildConfigurationId); 28 | return this; 29 | } 30 | 31 | public IBuildConfigurationHavingBuilder Name(string buildConfigurationName) 32 | { 33 | m_Having.Add("name:" + buildConfigurationName); 34 | return this; 35 | } 36 | 37 | public IBuildConfigurationHavingBuilder InternalId(string internalId) 38 | { 39 | m_Having.Add("internalId:" + internalId); 40 | return this; 41 | } 42 | 43 | public IBuildConfigurationHavingBuilder Project(Action projectHavingBuilderAction) 44 | { 45 | var buildProjectHavingBuilder = m_BuildProjectHavingBuilderFactory.CreateBuildProjectHavingBuilder(); 46 | projectHavingBuilderAction(buildProjectHavingBuilder); 47 | m_Having.Add("project:" + buildProjectHavingBuilder.GetLocator()); 48 | return this; 49 | } 50 | 51 | public IBuildConfigurationHavingBuilder ProjectRecursively(Action projectHavingBuilderAction) 52 | { 53 | var buildProjectHavingBuilder = m_BuildProjectHavingBuilderFactory.CreateBuildProjectHavingBuilder(); 54 | projectHavingBuilderAction(buildProjectHavingBuilder); 55 | m_Having.Add("affectedProject:" + buildProjectHavingBuilder.GetLocator()); 56 | return this; 57 | } 58 | 59 | public string GetLocator() 60 | { 61 | return string.Join(",", m_Having); 62 | } 63 | } 64 | } -------------------------------------------------------------------------------- /FluentTc/Locators/BuildConfigurationHavingBuilderFactory.cs: -------------------------------------------------------------------------------- 1 | namespace FluentTc.Locators 2 | { 3 | public interface IBuildConfigurationHavingBuilderFactory 4 | { 5 | BuildConfigurationHavingBuilder CreateBuildConfigurationHavingBuilder(); 6 | } 7 | 8 | public class BuildConfigurationHavingBuilderFactory : IBuildConfigurationHavingBuilderFactory 9 | { 10 | private readonly IBuildProjectHavingBuilderFactory m_BuildProjectHavingBuilderFactory; 11 | 12 | public BuildConfigurationHavingBuilderFactory(IBuildProjectHavingBuilderFactory buildProjectHavingBuilderFactory) 13 | { 14 | m_BuildProjectHavingBuilderFactory = buildProjectHavingBuilderFactory; 15 | } 16 | 17 | public BuildConfigurationHavingBuilder CreateBuildConfigurationHavingBuilder() 18 | { 19 | return new BuildConfigurationHavingBuilder(m_BuildProjectHavingBuilderFactory); 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /FluentTc/Locators/BuildConfigurationTemplateHavingBuilder.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace FluentTc.Locators 4 | { 5 | public interface IBuildConfigurationTemplateHavingBuilder 6 | { 7 | IBuildConfigurationTemplateHavingBuilder Id(string buildConfigurationId); 8 | IBuildConfigurationTemplateHavingBuilder Name(string buildConfigurationName); 9 | } 10 | 11 | internal class BuildConfigurationTemplateHavingBuilder : IBuildConfigurationTemplateHavingBuilder 12 | { 13 | private readonly List m_Having = new List(); 14 | 15 | public IBuildConfigurationTemplateHavingBuilder Id(string buildConfigurationId) 16 | { 17 | m_Having.Add("id:" + buildConfigurationId); 18 | return this; 19 | } 20 | 21 | public IBuildConfigurationTemplateHavingBuilder Name(string buildConfigurationName) 22 | { 23 | m_Having.Add("name:" + buildConfigurationName); 24 | return this; 25 | } 26 | 27 | public string GetLocator() 28 | { 29 | return string.Join(",", m_Having); 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /FluentTc/Locators/BuildFieldValueBuilder.cs: -------------------------------------------------------------------------------- 1 | using FluentTc.Domain; 2 | using System.Collections.Generic; 3 | using System.Globalization; 4 | 5 | namespace FluentTc.Locators 6 | { 7 | public interface IBuildFieldValueBuilder 8 | { 9 | IBuildFieldValueBuilder Name(string value); 10 | IBuildFieldValueBuilder Description(string value); 11 | IBuildFieldValueBuilder Paused(); 12 | IBuildFieldValueBuilder NotPaused(); 13 | } 14 | 15 | public class BuildFieldValueBuilder: IBuildFieldValueBuilder 16 | { 17 | readonly List m_Properties = new List(); 18 | 19 | public IBuildFieldValueBuilder Description(string value) 20 | { 21 | m_Properties.Add(new Property { Name = "description", Value = value, Type = null }); 22 | return this; 23 | } 24 | 25 | public IBuildFieldValueBuilder Paused() 26 | { 27 | m_Properties.Add(new Property 28 | { 29 | Name = "paused", 30 | Value = "true", 31 | Type = null }); 32 | return this; 33 | } 34 | public IBuildFieldValueBuilder NotPaused() 35 | { 36 | m_Properties.Add(new Property 37 | { 38 | Name = "paused", 39 | Value = "false", 40 | Type = null 41 | }); 42 | return this; 43 | } 44 | 45 | public IBuildFieldValueBuilder Name(string value) 46 | { 47 | m_Properties.Add(new Property { Name = "name", Value = value, Type = null }); 48 | return this; 49 | } 50 | 51 | public List GetFields() 52 | { 53 | return m_Properties; 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /FluentTc/Locators/BuildHavingBuilderFactory.cs: -------------------------------------------------------------------------------- 1 | namespace FluentTc.Locators 2 | { 3 | internal interface IBuildHavingBuilderFactory 4 | { 5 | BuildHavingBuilder CreateBuildHavingBuilder(); 6 | } 7 | 8 | internal class BuildHavingBuilderFactory : IBuildHavingBuilderFactory 9 | { 10 | private readonly IUserHavingBuilderFactory m_UserHavingBuilderFactory; 11 | private readonly IBranchHavingBuilderFactory m_BranchHavingBuilderFactory; 12 | private readonly IBuildProjectHavingBuilderFactory m_BuildProjectHavingBuilderFactory; 13 | private readonly ILocatorBuilder m_LocatorBuilder; 14 | 15 | public BuildHavingBuilderFactory(IUserHavingBuilderFactory userHavingBuilderFactory, IBranchHavingBuilderFactory branchHavingBuilderFactory, IBuildProjectHavingBuilderFactory buildProjectHavingBuilderFactory, ILocatorBuilder locatorBuilder) 16 | { 17 | m_UserHavingBuilderFactory = userHavingBuilderFactory; 18 | m_BranchHavingBuilderFactory = branchHavingBuilderFactory; 19 | m_BuildProjectHavingBuilderFactory = buildProjectHavingBuilderFactory; 20 | m_LocatorBuilder = locatorBuilder; 21 | } 22 | 23 | public BuildHavingBuilder CreateBuildHavingBuilder() 24 | { 25 | return new BuildHavingBuilder(this, m_UserHavingBuilderFactory, m_BranchHavingBuilderFactory, m_BuildProjectHavingBuilderFactory, m_LocatorBuilder); 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /FluentTc/Locators/BuildIncludeBuilder.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace FluentTc.Locators 4 | { 5 | public interface IBuildIncludeBuilder 6 | { 7 | IBuildIncludeBuilder IncludeStartDate(); 8 | IBuildIncludeBuilder IncludeFinishDate(); 9 | IBuildIncludeBuilder IncludeStatusText(); 10 | IBuildIncludeBuilder IncludeDefaults(); 11 | IBuildIncludeBuilder IncludeRevisions(); 12 | } 13 | 14 | public class BuildIncludeBuilder : IBuildIncludeBuilder 15 | { 16 | readonly IList m_Properties = new List(new[] 17 | { 18 | "buildTypeId", "href", "id", "number", "state", "status","webUrl" 19 | }); 20 | 21 | public IBuildIncludeBuilder IncludeStartDate() 22 | { 23 | m_Properties.Add("startDate"); 24 | return this; 25 | } 26 | 27 | public IBuildIncludeBuilder IncludeFinishDate() 28 | { 29 | m_Properties.Add("finishDate"); 30 | return this; 31 | } 32 | 33 | public IBuildIncludeBuilder IncludeStatusText() 34 | { 35 | m_Properties.Add("statusText"); 36 | return this; 37 | } 38 | 39 | public IBuildIncludeBuilder IncludeDefaults() 40 | { 41 | return this; 42 | } 43 | 44 | public IBuildIncludeBuilder IncludeRevisions() 45 | { 46 | m_Properties.Add("revisions"); 47 | return this; 48 | } 49 | 50 | public virtual string GetColumns() 51 | { 52 | return string.Join(",", m_Properties); 53 | } 54 | } 55 | } -------------------------------------------------------------------------------- /FluentTc/Locators/BuildParameterCheckboxTypeBuilder.cs: -------------------------------------------------------------------------------- 1 | using System.Text; 2 | 3 | namespace FluentTc.Locators 4 | { 5 | public interface IBuildParameterCheckboxTypeBuilder 6 | { 7 | IBuildParameterCheckboxTypeBuilder WithCheckedValue(string checkedValue); 8 | IBuildParameterCheckboxTypeBuilder WithUncheckedValue(string uncheckedValue); 9 | } 10 | 11 | internal class BuildParameterCheckboxTypeBuilder : IBuildParameterCheckboxTypeBuilder 12 | { 13 | private string m_checkedValue; 14 | private string m_uncheckedValue; 15 | 16 | public IBuildParameterCheckboxTypeBuilder WithCheckedValue(string checkedValue) 17 | { 18 | m_checkedValue = checkedValue; 19 | return this; 20 | } 21 | 22 | public IBuildParameterCheckboxTypeBuilder WithUncheckedValue(string uncheckedValue) 23 | { 24 | m_uncheckedValue = uncheckedValue; 25 | return this; 26 | } 27 | 28 | public string Build() 29 | { 30 | var builder = new StringBuilder(); 31 | builder.Append("checkbox"); 32 | if (!string.IsNullOrEmpty(m_checkedValue)) 33 | builder.Append(" checkedValue='").Append(m_checkedValue).Append("'"); 34 | if (!string.IsNullOrEmpty(m_uncheckedValue)) 35 | builder.Append(" uncheckedValue='").Append(m_uncheckedValue).Append("'"); 36 | return builder.ToString(); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /FluentTc/Locators/BuildParameterSelectListTypeBuilder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace FluentTc.Locators 7 | { 8 | public interface IBuildParameterSelectListTypeBuilder 9 | { 10 | IBuildParameterSelectListTypeBuilder Value(string value); 11 | IBuildParameterSelectListTypeBuilder LabeledValue(string label, string value); 12 | IBuildParameterSelectListTypeBuilder AllowMultiple(bool allowMultiple); 13 | IBuildParameterSelectListTypeBuilder WithSeparator(string separator); 14 | } 15 | 16 | internal class BuildParameterSelectListTypeBuilder : IBuildParameterSelectListTypeBuilder 17 | { 18 | private readonly List> m_values = new List>(); 19 | 20 | private string m_separator = null; 21 | private bool m_multiple; 22 | 23 | public IBuildParameterSelectListTypeBuilder Value(string value) 24 | { 25 | if (!string.IsNullOrEmpty(value)) 26 | m_values.Add(new Tuple(null, value)); 27 | return this; 28 | } 29 | 30 | public IBuildParameterSelectListTypeBuilder LabeledValue(string label, string value) 31 | { 32 | if (!string.IsNullOrEmpty(value)) 33 | m_values.Add(new Tuple(label, value)); 34 | return this; 35 | } 36 | 37 | public IBuildParameterSelectListTypeBuilder AllowMultiple(bool allowMultiple) 38 | { 39 | m_multiple = allowMultiple; 40 | return this; 41 | } 42 | 43 | public IBuildParameterSelectListTypeBuilder WithSeparator(string separator) 44 | { 45 | if (!string.IsNullOrEmpty(separator)) 46 | m_separator = separator; 47 | return this; 48 | } 49 | 50 | public string Build() 51 | { 52 | var builder = new StringBuilder(); 53 | if (!m_values.Any()) 54 | return string.Empty; 55 | builder.Append("select"); 56 | if (m_multiple) 57 | { 58 | builder.Append(" multiple='true'"); 59 | if (!string.IsNullOrEmpty(m_separator)) 60 | builder.Append(" valueSeparator='").Append(m_separator).Append("'"); 61 | } 62 | for (var i = 0; i < m_values.Count; i++) 63 | { 64 | if (!string.IsNullOrEmpty(m_values[i].Item1)) 65 | builder.Append(" label_").Append(i + 1).Append("='").Append(m_values[i].Item1).Append("'"); 66 | builder.Append(" data_").Append(i + 1).Append("='").Append(m_values[i].Item2).Append("'"); 67 | } 68 | return builder.ToString(); 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /FluentTc/Locators/BuildParameterTextTypeBuilder.cs: -------------------------------------------------------------------------------- 1 | using System.Text; 2 | 3 | namespace FluentTc.Locators 4 | { 5 | public interface IBuildParameterTextTypeBuilder 6 | { 7 | IBuildParameterTextTypeBuilder AsAny(); 8 | IBuildParameterTextTypeBuilder AsNotEmpty(); 9 | IBuildParameterTextTypeBuilder AsRegex(string regexp, string validationMessage); 10 | } 11 | 12 | internal class BuildParameterTextTypeBuilder : IBuildParameterTextTypeBuilder 13 | { 14 | private const string AnyValidation = "any"; 15 | private const string RegexValidation = "regex"; 16 | private const string NotEmptyValidation = "not_empty"; 17 | 18 | private const string DefaultValidation = AnyValidation; 19 | 20 | private string m_mode = DefaultValidation; 21 | private string m_regexp; 22 | private string m_message; 23 | 24 | public IBuildParameterTextTypeBuilder AsAny() 25 | { 26 | m_mode = AnyValidation; 27 | m_regexp = null; 28 | m_message = null; 29 | return this; 30 | } 31 | 32 | public IBuildParameterTextTypeBuilder AsNotEmpty() 33 | { 34 | m_mode = NotEmptyValidation; 35 | m_regexp = null; 36 | m_message = null; 37 | return this; 38 | } 39 | 40 | public IBuildParameterTextTypeBuilder AsRegex(string regexp, string validationMessage) 41 | { 42 | m_mode = RegexValidation; 43 | m_regexp = regexp; 44 | m_message = validationMessage; 45 | return this; 46 | } 47 | 48 | public string Build() 49 | { 50 | var builder = new StringBuilder(); 51 | builder.Append("text"); 52 | builder.Append(" validationMode='").Append(m_mode).Append("'"); 53 | if (!string.IsNullOrEmpty(m_regexp)) 54 | builder.Append(" regexp='").Append(m_regexp).Append("'"); 55 | if (!string.IsNullOrEmpty(m_message)) 56 | builder.Append(" validationMessage='").Append(m_message).Append("'"); 57 | return builder.ToString(); 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /FluentTc/Locators/BuildParameterValueBuilder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using FluentTc.Domain; 4 | 5 | namespace FluentTc.Locators 6 | { 7 | public interface IBuildParameterValueBuilder 8 | { 9 | IBuildParameterValueBuilder Parameter(string name, string value); 10 | IBuildParameterValueBuilder Parameter(string name, string value, Action type); 11 | } 12 | 13 | public class BuildParameterValueBuilder : IBuildParameterValueBuilder 14 | { 15 | readonly List m_Properties = new List(); 16 | 17 | public IBuildParameterValueBuilder Parameter(string name, string value) 18 | { 19 | m_Properties.Add(new Property { Name = name, Value = value, Type = null }); 20 | return this; 21 | } 22 | 23 | public IBuildParameterValueBuilder Parameter(string name, string value, Action typeBuilder) 24 | { 25 | var builder = new BuildParameterTypeBuilder(); 26 | typeBuilder(builder); 27 | var rawValue = builder.Build(); 28 | if (string.IsNullOrEmpty(rawValue)) 29 | return Parameter(name, value); 30 | m_Properties.Add(new Property { Name = name, Value = value, Type = new PropertyType { RawValue = rawValue } }); 31 | return this; 32 | } 33 | 34 | public List GetParameters() 35 | { 36 | return m_Properties; 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /FluentTc/Locators/BuildParametersBuilder.cs: -------------------------------------------------------------------------------- 1 | namespace FluentTc.Locators 2 | { 3 | public class BuildParametersBuilder 4 | { 5 | } 6 | } -------------------------------------------------------------------------------- /FluentTc/Locators/BuildProjectFieldValueBuilder.cs: -------------------------------------------------------------------------------- 1 | using FluentTc.Domain; 2 | using System.Collections.Generic; 3 | using System.Globalization; 4 | 5 | namespace FluentTc.Locators 6 | { 7 | public interface IBuildProjectFieldValueBuilder 8 | { 9 | IBuildProjectFieldValueBuilder Name(string value); 10 | IBuildProjectFieldValueBuilder Description(string value); 11 | IBuildProjectFieldValueBuilder Archived(); 12 | IBuildProjectFieldValueBuilder NotArchived(); 13 | } 14 | 15 | public class BuildProjectFieldValueBuilder: IBuildProjectFieldValueBuilder 16 | { 17 | readonly List m_Properties = new List(); 18 | 19 | public IBuildProjectFieldValueBuilder Description(string value) 20 | { 21 | m_Properties.Add(new Property { Name = "description", Value = value, Type = null }); 22 | return this; 23 | } 24 | 25 | public IBuildProjectFieldValueBuilder Archived() 26 | { 27 | m_Properties.Add(new Property 28 | { 29 | Name = "archived", 30 | Value = "true", 31 | Type = null }); 32 | return this; 33 | } 34 | 35 | public IBuildProjectFieldValueBuilder NotArchived() 36 | { 37 | m_Properties.Add(new Property 38 | { 39 | Name = "archived", 40 | Value = "false", 41 | Type = null 42 | }); 43 | return this; 44 | } 45 | 46 | public IBuildProjectFieldValueBuilder Name(string value) 47 | { 48 | m_Properties.Add(new Property { Name = "name", Value = value, Type = null }); 49 | return this; 50 | } 51 | 52 | public List GetFields() 53 | { 54 | return m_Properties; 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /FluentTc/Locators/BuildProjectHavingBuilder.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace FluentTc.Locators 4 | { 5 | public interface IBuildProjectHavingBuilder 6 | { 7 | void Id(string projectId); 8 | void Name(string projectName); 9 | } 10 | 11 | public class BuildProjectHavingBuilder : IBuildProjectHavingBuilder 12 | { 13 | readonly List m_Having = new List(); 14 | 15 | public void Id(string projectId) 16 | { 17 | m_Having.Add("id:" + projectId); 18 | } 19 | 20 | public void Name(string projectName) 21 | { 22 | m_Having.Add("name:" + projectName); 23 | } 24 | 25 | public string GetLocator() 26 | { 27 | return string.Join(",", m_Having); 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /FluentTc/Locators/BuildProjectHavingBuilderFactory.cs: -------------------------------------------------------------------------------- 1 | namespace FluentTc.Locators 2 | { 3 | public interface IBuildProjectHavingBuilderFactory 4 | { 5 | BuildProjectHavingBuilder CreateBuildProjectHavingBuilder(); 6 | } 7 | 8 | public class BuildProjectHavingBuilderFactory : IBuildProjectHavingBuilderFactory 9 | { 10 | public BuildProjectHavingBuilder CreateBuildProjectHavingBuilder() 11 | { 12 | return new BuildProjectHavingBuilder(); 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /FluentTc/Locators/BuildQueueIdHavingBuilder.cs: -------------------------------------------------------------------------------- 1 | namespace FluentTc.Locators 2 | { 3 | public interface IBuildQueueIdHavingBuilder 4 | { 5 | IBuildQueueIdHavingBuilder Id(int buildId); 6 | } 7 | 8 | public class BuildQueueIdHavingBuilder : IBuildQueueIdHavingBuilder 9 | { 10 | private string m_Locator = string.Empty; 11 | 12 | public IBuildQueueIdHavingBuilder Id(int buildId) 13 | { 14 | m_Locator = string.Format("id:{0}", buildId); 15 | return this; 16 | } 17 | 18 | public string GetLocator() 19 | { 20 | return m_Locator; 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /FluentTc/Locators/BuildState.cs: -------------------------------------------------------------------------------- 1 | namespace FluentTc.Locators 2 | { 3 | public enum BuildState 4 | { 5 | Queued, 6 | Running, 7 | Finished 8 | } 9 | } -------------------------------------------------------------------------------- /FluentTc/Locators/BuildStatus.cs: -------------------------------------------------------------------------------- 1 | namespace FluentTc.Locators 2 | { 3 | public enum BuildStatus 4 | { 5 | Success, 6 | Failure, 7 | Error 8 | } 9 | } -------------------------------------------------------------------------------- /FluentTc/Locators/ChangesHavingBuilder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using FluentTc.Engine; 4 | 5 | namespace FluentTc.Locators 6 | { 7 | internal interface IChangesHavingBuilder 8 | { 9 | IChangesHavingBuilder Build(Action build); 10 | } 11 | 12 | internal class ChangesHavingBuilder : IChangesHavingBuilder 13 | { 14 | private readonly List m_Having = new List(); 15 | 16 | private readonly IBuildHavingBuilderFactory m_BuildHavingBuilderFactory; 17 | 18 | public ChangesHavingBuilder(IBuildHavingBuilderFactory buildHavingBuilderFactory) 19 | { 20 | m_BuildHavingBuilderFactory = buildHavingBuilderFactory; 21 | } 22 | 23 | public IChangesHavingBuilder Build(Action build) 24 | { 25 | var buildHavingBuilder = m_BuildHavingBuilderFactory.CreateBuildHavingBuilder(); 26 | build(buildHavingBuilder); 27 | m_Having.Add("build:" + buildHavingBuilder.GetLocator()); 28 | return this; 29 | } 30 | 31 | public string GetLocator() 32 | { 33 | return string.Join(",", m_Having); 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /FluentTc/Locators/ChangesIncludeBuilder.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace FluentTc.Locators 4 | { 5 | public interface IChangesIncludeBuilder 6 | { 7 | IChangesIncludeBuilder IncludeComment(); 8 | IChangesIncludeBuilder IncludeFiles(); 9 | IChangesIncludeBuilder IncludeVcsRootInstance(); 10 | IChangesIncludeBuilder IncludeDefaults(); 11 | } 12 | 13 | internal class ChangesIncludeBuilder : IChangesIncludeBuilder 14 | { 15 | readonly IList m_Properties = new List(new[] 16 | { 17 | "id", "version", "href", "username", "date", "webUrl" 18 | }); 19 | 20 | public IChangesIncludeBuilder IncludeDefaults() 21 | { 22 | return this; 23 | } 24 | 25 | public IChangesIncludeBuilder IncludeComment() 26 | { 27 | m_Properties.Add("comment"); 28 | return this; 29 | } 30 | 31 | public IChangesIncludeBuilder IncludeFiles() 32 | { 33 | m_Properties.Add("files"); 34 | return this; 35 | } 36 | 37 | public IChangesIncludeBuilder IncludeVcsRootInstance() 38 | { 39 | m_Properties.Add("vcsRootInstance"); 40 | return this; 41 | } 42 | 43 | internal string GetColumns() 44 | { 45 | return string.Join(",", m_Properties); 46 | } 47 | } 48 | } -------------------------------------------------------------------------------- /FluentTc/Locators/CountBuilder.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace FluentTc.Locators 4 | { 5 | public interface ICountBuilder 6 | { 7 | /// 8 | /// Returns the default number of results 9 | /// 10 | /// 11 | ICountBuilder DefaultCount(); 12 | 13 | /// 14 | /// Return specified number of results 15 | /// 16 | /// 17 | /// 18 | ICountBuilder Count(int count); 19 | 20 | /// 21 | /// Retuns results starting from the position specified (zero-based) 22 | /// 23 | /// 24 | /// 25 | ICountBuilder Start(int start); 26 | 27 | /// 28 | /// Limits processing to the latest N builds only. If none of the latest N builds match the other specified criteria of the build locator, 404 response is returned. 29 | /// 30 | /// 31 | /// 32 | ICountBuilder LookupLimit(int lookupLimit); 33 | } 34 | 35 | public class CountBuilder : ICountBuilder 36 | { 37 | private const int AllRecords = -1; 38 | readonly List m_Counts = new List(); 39 | 40 | public ICountBuilder DefaultCount() 41 | { 42 | return this; 43 | } 44 | 45 | public ICountBuilder Count(int count) 46 | { 47 | m_Counts.Add("count:" + count); 48 | return this; 49 | } 50 | 51 | public ICountBuilder Start(int start) 52 | { 53 | m_Counts.Add("start:" + start); 54 | return this; 55 | } 56 | 57 | public ICountBuilder LookupLimit(int lookupLimit) 58 | { 59 | m_Counts.Add("lookupLimit:" + lookupLimit); 60 | return this; 61 | } 62 | 63 | public virtual string GetCount() 64 | { 65 | return string.Join(",", m_Counts); 66 | } 67 | } 68 | } -------------------------------------------------------------------------------- /FluentTc/Locators/LocatorBuilder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace FluentTc.Locators 4 | { 5 | public interface ILocatorBuilder 6 | { 7 | string GetBuildConfigurationLocator(Action havingBuildConfig); 8 | string GetProjectLocator(Action projectHavingBuilder); 9 | } 10 | 11 | public class LocatorBuilder : ILocatorBuilder 12 | { 13 | private readonly IBuildConfigurationHavingBuilderFactory m_BuildConfigurationHavingBuilderFactory; 14 | private readonly IBuildProjectHavingBuilderFactory m_BuildProjectHavingBuilderFactory; 15 | 16 | public LocatorBuilder(IBuildConfigurationHavingBuilderFactory buildConfigurationHavingBuilderFactory, IBuildProjectHavingBuilderFactory buildProjectHavingBuilderFactory) 17 | { 18 | m_BuildConfigurationHavingBuilderFactory = buildConfigurationHavingBuilderFactory; 19 | m_BuildProjectHavingBuilderFactory = buildProjectHavingBuilderFactory; 20 | } 21 | 22 | public string GetBuildConfigurationLocator(Action havingBuildConfig) 23 | { 24 | var buildConfigurationHavingBuilder = 25 | m_BuildConfigurationHavingBuilderFactory.CreateBuildConfigurationHavingBuilder(); 26 | havingBuildConfig.Invoke(buildConfigurationHavingBuilder); 27 | var locator = buildConfigurationHavingBuilder.GetLocator(); 28 | return locator; 29 | } 30 | 31 | public string GetProjectLocator(Action projectHavingBuilder) 32 | { 33 | var buildProjectHavingBuilder = m_BuildProjectHavingBuilderFactory.CreateBuildProjectHavingBuilder(); 34 | projectHavingBuilder(buildProjectHavingBuilder); 35 | var locator = buildProjectHavingBuilder.GetLocator(); 36 | return locator; 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /FluentTc/Locators/MoreOptionsHavingBuilder.cs: -------------------------------------------------------------------------------- 1 | namespace FluentTc.Locators 2 | { 3 | using System; 4 | 5 | public interface IMoreOptionsHavingBuilder 6 | { 7 | IMoreOptionsHavingBuilder WithCleanSources(); 8 | IMoreOptionsHavingBuilder RebuildAllDependencies(); 9 | IMoreOptionsHavingBuilder QueueAtTop(); 10 | IMoreOptionsHavingBuilder AsPersonal(); 11 | IMoreOptionsHavingBuilder WithComment(string comment); 12 | IMoreOptionsHavingBuilder OnBranch(string branchName); 13 | IMoreOptionsHavingBuilder OnChange(Action onChangeHavingBuilderAction); 14 | } 15 | 16 | internal class MoreOptionsHavingBuilder : IMoreOptionsHavingBuilder 17 | { 18 | private string m_Comment; 19 | private string m_BranchName; 20 | private readonly TriggeringOptions m_TriggeringOptions; 21 | private readonly OnChangeHavingBuilder m_OnChangeHavingBuilder; 22 | 23 | public MoreOptionsHavingBuilder() 24 | { 25 | m_TriggeringOptions = new TriggeringOptions(); 26 | m_OnChangeHavingBuilder = new OnChangeHavingBuilder(); 27 | } 28 | 29 | public IMoreOptionsHavingBuilder WithCleanSources() 30 | { 31 | // 32 | m_TriggeringOptions.CleanSources = true; 33 | return this; 34 | } 35 | 36 | public IMoreOptionsHavingBuilder RebuildAllDependencies() 37 | { 38 | // 39 | m_TriggeringOptions.RebuildAllDependencies = true; 40 | return this; 41 | } 42 | 43 | public IMoreOptionsHavingBuilder QueueAtTop() 44 | { 45 | // 46 | m_TriggeringOptions.QueueAtTop = true; 47 | return this; 48 | } 49 | 50 | public IMoreOptionsHavingBuilder AsPersonal() 51 | { 52 | m_TriggeringOptions.Personal = true; 53 | return this; 54 | } 55 | 56 | public IMoreOptionsHavingBuilder WithComment(string comment) 57 | { 58 | m_Comment = comment; 59 | return this; 60 | } 61 | 62 | public IMoreOptionsHavingBuilder OnBranch(string branchName) 63 | { 64 | m_BranchName = branchName; 65 | return this; 66 | } 67 | 68 | public IMoreOptionsHavingBuilder OnChange(Action onChangeHavingBuilderAction) 69 | { 70 | onChangeHavingBuilderAction(m_OnChangeHavingBuilder); 71 | return this; 72 | } 73 | 74 | public string GetComment() 75 | { 76 | return m_Comment; 77 | } 78 | 79 | public string GetBranchName() 80 | { 81 | return m_BranchName; 82 | } 83 | 84 | public bool HasBranch() 85 | { 86 | return !string.IsNullOrEmpty(m_BranchName); 87 | } 88 | 89 | public TriggeringOptions TriggeringOptions 90 | { 91 | get { return m_TriggeringOptions; } 92 | } 93 | 94 | public bool HasChangeId() 95 | { 96 | return m_OnChangeHavingBuilder.GetChangeId() != 0; 97 | } 98 | 99 | public long GetChangeId() 100 | { 101 | return m_OnChangeHavingBuilder.GetChangeId(); 102 | } 103 | } 104 | 105 | public class TriggeringOptions 106 | { 107 | public bool? QueueAtTop { get; set; } 108 | public bool? RebuildAllDependencies { get; set; } 109 | public bool? CleanSources { get; set; } 110 | public bool? Personal { get; set; } 111 | } 112 | } -------------------------------------------------------------------------------- /FluentTc/Locators/OnChangeHavingBuilder.cs: -------------------------------------------------------------------------------- 1 | namespace FluentTc.Locators 2 | { 3 | public interface IOnChangeHavingBuilder 4 | { 5 | IOnChangeHavingBuilder Id(long changeId); 6 | } 7 | 8 | internal class OnChangeHavingBuilder : IOnChangeHavingBuilder 9 | { 10 | private long m_ChangeId; 11 | 12 | public IOnChangeHavingBuilder Id(long changeId) 13 | { 14 | m_ChangeId = changeId; 15 | return this; 16 | } 17 | 18 | public long GetChangeId() 19 | { 20 | return m_ChangeId; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /FluentTc/Locators/QueueHavingBuilder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace FluentTc.Locators 5 | { 6 | public interface IQueueHavingBuilder 7 | { 8 | IQueueHavingBuilder BuildConfiguration(Action havingBuildConfig); 9 | IQueueHavingBuilder Project(Action projectHavingBuilder); 10 | } 11 | 12 | public class QueueHavingBuilder : IQueueHavingBuilder 13 | { 14 | private readonly List m_Having = new List(); 15 | private readonly ILocatorBuilder m_LocatorBuilder; 16 | 17 | public QueueHavingBuilder(ILocatorBuilder locatorBuilder) 18 | { 19 | m_LocatorBuilder = locatorBuilder; 20 | } 21 | 22 | public IQueueHavingBuilder BuildConfiguration(Action havingBuildConfig) 23 | { 24 | var locator = m_LocatorBuilder.GetBuildConfigurationLocator(havingBuildConfig); 25 | m_Having.Add("buildType:" + locator); 26 | return this; 27 | } 28 | 29 | public IQueueHavingBuilder Project(Action projectHavingBuilder) 30 | { 31 | var locator = m_LocatorBuilder.GetProjectLocator(projectHavingBuilder); 32 | m_Having.Add("project:" + locator); 33 | return this; 34 | } 35 | 36 | public string GetLocator() 37 | { 38 | return string.Join(",", m_Having); 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /FluentTc/Locators/TeamCityConfigurationBuilder.cs: -------------------------------------------------------------------------------- 1 | namespace FluentTc.Locators 2 | { 3 | public class TeamCityConfigurationBuilder 4 | { 5 | private string m_Password; 6 | private string m_TeamCityHost; 7 | private string m_Username; 8 | private bool m_UseSsl; 9 | 10 | public TeamCityConfigurationBuilder() 11 | { 12 | m_TeamCityHost = "localhost"; 13 | m_Username = "guest"; 14 | m_Password = string.Empty; 15 | } 16 | 17 | public TeamCityConfigurationBuilder ToHost(string teamCityHost) 18 | { 19 | m_TeamCityHost = teamCityHost; 20 | return this; 21 | } 22 | 23 | public TeamCityConfigurationBuilder AsGuest() 24 | { 25 | m_Username = "guest"; 26 | return this; 27 | } 28 | 29 | public TeamCityConfigurationBuilder AsUser(string username, string password) 30 | { 31 | m_Username = username; 32 | m_Password = password; 33 | return this; 34 | } 35 | 36 | public TeamCityConfigurationBuilder UseSsl() 37 | { 38 | m_UseSsl = true; 39 | return this; 40 | } 41 | 42 | public TeamCityConfigurationBuilder DoNotUseSsl() 43 | { 44 | m_UseSsl = false; 45 | return this; 46 | } 47 | 48 | internal ITeamCityConnectionDetails GetTeamCityConnectionDetails() 49 | { 50 | return new TeamCityConnectionDetails(m_TeamCityHost, m_Username, m_Password, m_Username.Equals("guest"), m_UseSsl); 51 | } 52 | } 53 | } -------------------------------------------------------------------------------- /FluentTc/Locators/TeamCityConnectionDetails.cs: -------------------------------------------------------------------------------- 1 | namespace FluentTc.Locators 2 | { 3 | internal interface ITeamCityConnectionDetails 4 | { 5 | string TeamCityHost { get; } 6 | string Username { get; } 7 | string Password { get; } 8 | bool ActAsGuest { get; } 9 | bool UseSSL { get; } 10 | } 11 | 12 | internal class TeamCityConnectionDetails : ITeamCityConnectionDetails 13 | { 14 | private readonly string m_Password; 15 | private readonly string m_TeamCityHost; 16 | private readonly string m_Username; 17 | private readonly bool m_ActAsGuest; 18 | private readonly bool m_UseSsl; 19 | 20 | public TeamCityConnectionDetails(string teamCityHost, string username, string password, bool actAsGuest, bool useSsl) 21 | { 22 | m_TeamCityHost = teamCityHost; 23 | m_Username = username; 24 | m_Password = password; 25 | m_ActAsGuest = actAsGuest; 26 | m_UseSsl = useSsl; 27 | } 28 | 29 | public string TeamCityHost 30 | { 31 | get { return m_TeamCityHost; } 32 | } 33 | 34 | public string Username 35 | { 36 | get { return m_Username; } 37 | } 38 | 39 | public string Password 40 | { 41 | get { return m_Password; } 42 | } 43 | 44 | public bool ActAsGuest 45 | { 46 | get { return m_ActAsGuest; } 47 | } 48 | 49 | public bool UseSSL 50 | { 51 | get { return m_UseSsl; } 52 | } 53 | } 54 | } -------------------------------------------------------------------------------- /FluentTc/Locators/UserHavingBuilder.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace FluentTc.Locators 4 | { 5 | public interface IUserHavingBuilder 6 | { 7 | UserHavingBuilder Id(string internalUserId); 8 | UserHavingBuilder Username(string username); 9 | string GetLocator(); 10 | } 11 | 12 | public class UserHavingBuilder : IUserHavingBuilder 13 | { 14 | private readonly List m_Havings = new List(); 15 | 16 | public UserHavingBuilder Id(string internalUserId) 17 | { 18 | m_Havings.Add("id:" + internalUserId); 19 | return this; 20 | } 21 | 22 | public UserHavingBuilder Username(string username) 23 | { 24 | m_Havings.Add("username:" + username); 25 | return this; 26 | } 27 | 28 | string IUserHavingBuilder.GetLocator() 29 | { 30 | return string.Join(",", m_Havings); 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /FluentTc/Locators/UserHavingBuilderFactory.cs: -------------------------------------------------------------------------------- 1 | namespace FluentTc.Locators 2 | { 3 | public interface IUserHavingBuilderFactory 4 | { 5 | IUserHavingBuilder CreateUserHavingBuilder(); 6 | } 7 | 8 | public class UserHavingBuilderFactory : IUserHavingBuilderFactory 9 | { 10 | public IUserHavingBuilder CreateUserHavingBuilder() 11 | { 12 | return new UserHavingBuilder(); 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /FluentTc/Locators/VCSRootEntryBuilder.cs: -------------------------------------------------------------------------------- 1 | using FluentTc.Domain; 2 | 3 | namespace FluentTc.Locators 4 | { 5 | public interface IVCSRootEntryBuilder 6 | { 7 | IVCSRootEntryBuilder Id(string value); 8 | 9 | IVCSRootEntryBuilder CheckoutRules(string value); 10 | } 11 | 12 | internal class VCSRootEntryBuilder: IVCSRootEntryBuilder 13 | { 14 | private VcsRootEntry m_VCSRootEntry = new VcsRootEntry(); 15 | 16 | public VCSRootEntryBuilder() 17 | { 18 | m_VCSRootEntry.VcsRoot = new VcsRoot(); 19 | } 20 | 21 | public IVCSRootEntryBuilder Id(string value) 22 | { 23 | m_VCSRootEntry.VcsRoot.Id = value; 24 | return this; 25 | } 26 | 27 | public IVCSRootEntryBuilder CheckoutRules(string value) 28 | { 29 | m_VCSRootEntry.CheckoutRules = value; 30 | return this; 31 | } 32 | 33 | internal VcsRootEntry GetVCSRootEntry() 34 | { 35 | return m_VCSRootEntry; 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /FluentTc/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("FluentTc")] 9 | [assembly: AssemblyDescription("Easy-to-use, readable and comprehensive library for consuming TeamCity REST API. " + 10 | "Written using real scenarios in mind, enables variuos range of queries and operation on TeamCity")] 11 | [assembly: AssemblyConfiguration("")] 12 | [assembly: AssemblyCompany("Boris Modylevsky, Igor Olikh, Tomer Cohen")] 13 | [assembly: AssemblyProduct("FluentTc")] 14 | [assembly: AssemblyCopyright("Copyright 2015 Boris Modylevsky")] 15 | [assembly: AssemblyTrademark("")] 16 | [assembly: AssemblyCulture("")] 17 | 18 | 19 | // Setting ComVisible to false makes the types in this assembly not visible 20 | // to COM components. If you need to access a type in this assembly from 21 | // COM, set the ComVisible attribute to true on that type. 22 | [assembly: ComVisible(false)] 23 | 24 | // The following GUID is for the ID of the typelib if this project is exposed to COM 25 | [assembly: Guid("908baf91-171f-40bc-ab7b-68a976549efe")] 26 | 27 | // Version information for an assembly consists of the following four values: 28 | // 29 | // Major Version 30 | // Minor Version 31 | // Build Number 32 | // Revision 33 | // 34 | // You can specify all the values or you can default the Build and Revision Numbers 35 | // by using the '*' as shown below: 36 | // [assembly: AssemblyVersion("1.0.*")] 37 | [assembly: AssemblyVersion("1.0.0.0")] 38 | [assembly: AssemblyFileVersion("1.0.0.0")] 39 | [assembly: InternalsVisibleTo("FluentTc.Tests")] 40 | [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] 41 | -------------------------------------------------------------------------------- /FluentTc/RemoteTc.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using FluentTc.Domain; 4 | using FluentTc.Engine; 5 | using FluentTc.Locators; 6 | 7 | namespace FluentTc 8 | { 9 | public interface IRemoteTc 10 | { 11 | IConnectedTc Connect(Action connect); 12 | } 13 | 14 | public class RemoteTc : IRemoteTc 15 | { 16 | public IConnectedTc Connect(Action connect) 17 | { 18 | return Connect(connect, null); 19 | } 20 | 21 | internal IConnectedTc Connect(Action connect, params object[] overrides) 22 | { 23 | var teamCityConfigurationBuilder = new TeamCityConfigurationBuilder(); 24 | connect(teamCityConfigurationBuilder); 25 | if (overrides == null) 26 | { 27 | overrides = new object[] {teamCityConfigurationBuilder.GetTeamCityConnectionDetails()}; 28 | } 29 | else 30 | { 31 | overrides = overrides.Concat(new[] { teamCityConfigurationBuilder.GetTeamCityConnectionDetails() }).ToArray(); 32 | } 33 | var bootstrapper = new Bootstrapper(overrides); 34 | return bootstrapper.GetConnectedTc(); 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /FluentTc/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | --------------------------------------------------------------------------------