diff --git a/.gitignore b/.gitignore
index 98498b3..253b9b9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,15 +1,108 @@
-*resharper.user
-[Dd]ebug/
-[Rr]elease/
-build/
-[Bb]in/
-[Oo]bj/
-Source/TestResults/
-*.sou
-*.sln.cache
-_ReSharper.*/
-*.user
-*.trx
-[Tt]est[Dd]ata/
-Thumbs.db
-TestResults
\ No newline at end of file
+# Build Folders (you can keep bin if you'd like, to store dlls and pdbs)
+[Bb]in/
+[Oo]bj/
+
+# mstest test results
+TestResults
+
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+
+# User-specific files
+*.suo
+*.user
+*.sln.docstates
+
+# Build results
+[Dd]ebug/
+[Rr]elease/
+x64/
+*_i.c
+*_p.c
+*.ilk
+*.meta
+*.obj
+*.pch
+*.pdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.log
+*.vspscc
+*.vssscc
+.builds
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opensdf
+*.sdf
+
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+
+# Guidance Automation Toolkit
+*.gpState
+
+# ReSharper is a .NET coding add-in
+_ReSharper*
+
+# NCrunch
+*.ncrunch*
+.*crunch*.local.xml
+
+# Installshield output folder
+[Ee]xpress
+
+# DocProject is a documentation generator add-in
+DocProject/buildhelp/
+DocProject/Help/*.HxT
+DocProject/Help/*.HxC
+DocProject/Help/*.hhc
+DocProject/Help/*.hhk
+DocProject/Help/*.hhp
+DocProject/Help/Html2
+DocProject/Help/html
+
+# Click-Once directory
+publish
+
+# Publish Web Output
+*.Publish.xml
+
+# NuGet Packages Directory
+packages
+
+# Windows Azure Build Output
+csx
+*.build.csdef
+
+# Windows Store app package directory
+AppPackages/
+
+# Others
+[Bb]in
+[Oo]bj
+sql
+TestResults
+[Tt]est[Rr]esult*
+*.Cache
+ClientBin
+[Ss]tyle[Cc]op.*
+~$*
+*.dbmdl
+Generated_Code #added for RIA/Silverlight projects
+
+# Backup & report files from converting an old project file to a newer
+# Visual Studio version. Backup files are not needed, because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
\ No newline at end of file
diff --git a/.nuget/NuGet.Config b/.nuget/NuGet.Config
new file mode 100644
index 0000000..bbc58bb
--- /dev/null
+++ b/.nuget/NuGet.Config
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.nuget/NuGet.exe b/.nuget/NuGet.exe
new file mode 100644
index 0000000..cb3ed03
Binary files /dev/null and b/.nuget/NuGet.exe differ
diff --git a/.nuget/NuGet.msbuild b/.nuget/NuGet.msbuild
new file mode 100644
index 0000000..ee85ca5
--- /dev/null
+++ b/.nuget/NuGet.msbuild
@@ -0,0 +1,19 @@
+
+
+
+ CBApi
+ $(MSBuildProjectDirectory)\..\NuPKG
+ NuGet.exe
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.nuget/NuGet.targets b/.nuget/NuGet.targets
new file mode 100644
index 0000000..46a1b6c
--- /dev/null
+++ b/.nuget/NuGet.targets
@@ -0,0 +1,133 @@
+
+
+
+ $(MSBuildProjectDirectory)\..\
+
+
+ false
+
+
+ false
+
+
+ true
+
+
+ false
+
+
+
+
+
+
+
+
+
+
+ $([System.IO.Path]::Combine($(SolutionDir), ".nuget"))
+ $([System.IO.Path]::Combine($(ProjectDir), "packages.config"))
+
+
+
+
+ $(SolutionDir).nuget
+ packages.config
+
+
+
+
+ $(NuGetToolsPath)\NuGet.exe
+ @(PackageSource)
+
+ "$(NuGetExePath)"
+ mono --runtime=v4.0.30319 $(NuGetExePath)
+
+ $(TargetDir.Trim('\\'))
+
+ -RequireConsent
+ -NonInteractive
+
+
+ $(NuGetCommand) install "$(PackagesConfig)" -source "$(PackageSources)" $(NonInteractiveSwitch) $(RequireConsentSwitch) -solutionDir "$(SolutionDir) "
+ $(NuGetCommand) pack "$(ProjectPath)" -Properties Configuration=$(Configuration) $(NonInteractiveSwitch) -OutputDirectory "$(PackageOutputDir)" -symbols
+
+
+
+ RestorePackages;
+ $(BuildDependsOn);
+
+
+
+
+ $(BuildDependsOn);
+ BuildPackage;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.nuget/README_NUGET_CONFIG b/.nuget/README_NUGET_CONFIG
new file mode 100644
index 0000000..27db37f
--- /dev/null
+++ b/.nuget/README_NUGET_CONFIG
@@ -0,0 +1,18 @@
+Setting a machine specific 'repositoryPath' override may be considered harmful for
+teams that collaborate on the same repository.
+
+Ticketed Bugs:
+http://nuget.codeplex.com/discussions/400870
+http://nuget.codeplex.com/discussions/431666
+
+NuGet supports a hierarchy of .Config files so that there may be different settings
+between the repository folder, the team folder, and the developer's machine. The
+one closest to the repository wins out. There is a bug with the implementation of
+package restore when the 'repositoryPath' setting is overwritten. One developer may
+set their "global packages" folder to be higher up in the directory tree. If the
+package is lost and it needs to be "restored", the HintPath for references in the
+project files will change. After that point, there will be a disconnect between
+different developer's machines for the location of a project's dlls.
+
+Until this bug is resolved, I am going to manually set the repositoryPath setting on
+all the CB GitHub repos.
\ No newline at end of file
diff --git a/CBApi.Tests/CBApi.Tests.csproj b/CBApi.Tests/CBApi.Tests.csproj
new file mode 100644
index 0000000..32ef353
--- /dev/null
+++ b/CBApi.Tests/CBApi.Tests.csproj
@@ -0,0 +1,185 @@
+
+
+
+ Debug
+ AnyCPU
+
+
+ 2.0
+ {563513D2-EDA6-417C-9111-CA0D7C9D6199}
+ Library
+ Properties
+ Tests.com.careerbuilder
+ CBApi.Tests
+ v4.0
+ 512
+ ..\
+ true
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+ testdata\AnonymousApplicationRequestData.xml
+
+
+
+ ..\packages\Moq.4.0.10827\lib\NET40\Moq.dll
+
+
+ ..\packages\NUnit.3.2.1\lib\net40\nunit.framework.dll
+ True
+
+
+ ..\packages\RestSharp.104.3.3\lib\net4\RestSharp.dll
+
+
+
+ 3.5
+
+
+
+
+
+
+
+ False
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {58C4C156-4095-4F29-AF07-72722D262261}
+ CBApi
+
+
+
+
+
+
+ Always
+
+
+
+
+
+
+
+ Always
+
+
+ Always
+
+
+ Always
+ Designer
+
+
+ Always
+
+
+ Always
+ Designer
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+ Always
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/CBApi.Tests/CBApi/CBApiTest.cs b/CBApi.Tests/CBApi/CBApiTest.cs
new file mode 100644
index 0000000..0552e33
--- /dev/null
+++ b/CBApi.Tests/CBApi/CBApiTest.cs
@@ -0,0 +1,67 @@
+using NUnit.Framework;
+using System.Collections.Specialized;
+using CBApi;
+using CBApi.Models;
+using CBApi.Models.Service;
+
+namespace Tests.CBApi
+{
+ [TestFixture]
+ public class CbApiTest
+ {
+ [Test]
+ public void Constructor_DefaultsToCareerbuilderCom()
+ {
+ var svc = new CBApiStub();
+ Assert.IsInstanceOf(svc.Site);
+ }
+
+ [Test]
+ public void GetCategories_ReturnsCategoriesRequest()
+ {
+ var svc = new CbApi();
+ Assert.IsInstanceOf(svc.GetCategories());
+ }
+
+ [Test]
+ public void GetEmployeeTypes_ReturnsEmpRequest()
+ {
+ var svc = new CbApi();
+ Assert.IsInstanceOf(svc.GetEmployeeTypes());
+ }
+
+ //[Test]
+ //public void GetBlankApplication_ReturnsBlankApplication() {
+ // ICBApi svc = new CbApi();
+ // Assert.IsInstanceOf(svc.GetBlankApplication(""));
+ //}
+
+ [Test]
+ public void Application_Link_Request_With_NameValueCollection_Returns_String()
+ {
+ var svc = new CbApi();
+ Assert.IsInstanceOf(svc.ApplyLink(new NameValueCollection()));
+ }
+
+ [Test]
+ public void Application_Link_Request_With_ApplyLink_Returns_String() {
+ var svc = new CbApi();
+ Assert.IsInstanceOf(svc.ApplyLink(new ApplyLink()));
+ }
+
+ [Test]
+ public void JobSearch_ReturnsJobSearchRequest()
+ {
+ var svc = new CbApi();
+ Assert.IsInstanceOf(svc.JobSearch());
+ }
+ }
+
+ public class CBApiStub : CbApi
+ {
+ public TargetSite Site
+ {
+ get { return _Settings.TargetSite; }
+ }
+ }
+}
\ No newline at end of file
diff --git a/CBApi.Tests/CBApi/Models/AnonymousApplicationTest.cs b/CBApi.Tests/CBApi/Models/AnonymousApplicationTest.cs
new file mode 100644
index 0000000..7f74585
--- /dev/null
+++ b/CBApi.Tests/CBApi/Models/AnonymousApplicationTest.cs
@@ -0,0 +1,67 @@
+using NUnit.Framework;
+using System;
+using RestSharp;
+using RestSharp.Deserializers;
+using System.Xml.Linq;
+using System.IO;
+using CBApi.Models;
+
+namespace Tests.com.careerbuilder.CBApi.models.service
+{
+ [TestFixture]
+ public class AnonymousApplicationTest
+ {
+ [Test]
+ public void DeserializationWorks_WhenPassedRightXML_Response()
+ {
+ var xmlpath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "testdata","AnonymousApplicationResponseData.xml");
+ var doc = XDocument.Load(xmlpath);
+
+ var xml = new XmlDeserializer();
+ var output = xml.Deserialize(new RestResponse() { Content = doc.ToString() });
+ Assert.IsNotNull(output, "no deserialization worked");
+ Assert.AreEqual("Complete", output.ApplicationStatus);
+ Assert.AreEqual(4, output.TimeElapsed);
+ DateTime time = new DateTime(2011, 1, 11, 13, 11, 11);
+ Assert.AreEqual(time, output.TimeResponseSent);
+ Assert.IsTrue(string.IsNullOrEmpty(output.Errors));
+ }
+
+ [Test]
+ public void DeserializationWorks_WhenPassedRightXML_Request()
+ {
+ var xmlpath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "testdata", "AnonymousApplicationRequestData.xml");
+ var doc = XDocument.Load(xmlpath);
+
+ var xml = new XmlDeserializer();
+ var output = xml.Deserialize(new RestResponse() { Content = doc.ToString() });
+
+ Assert.IsNotNull(output, "no serialization happened");
+ Assert.AreEqual(false, output.Test);
+ Assert.AreEqual("DevKey", output.DeveloperKey);
+ Assert.AreEqual("US", output.SiteID);
+ Assert.AreEqual("JobDID", output.JobDID);
+ Assert.AreEqual("TNDID", output.TNDID);
+ Assert.IsNotNull(output.Responses, "responses did not deserialize right");
+ Assert.IsTrue(output.Responses.Count > 0, "no single response in responses");
+ Assert.AreEqual("ApplicantName", output.Responses[0].QuestionID);
+ Assert.AreEqual("Freedom", output.Responses[0].ResponseText);
+ Assert.AreEqual("ApplicantEmail", output.Responses[1].QuestionID);
+ Assert.AreEqual("FreedomTacosCB@Live.com", output.Responses[1].ResponseText);
+ Assert.AreEqual("Resume", output.Responses[2].QuestionID);
+ Assert.AreEqual("no", output.Responses[2].ResponseText);
+ Assert.AreEqual("1189225", output.Responses[3].QuestionID);
+ Assert.AreEqual("2486710", output.Responses[3].ResponseText);
+ Assert.AreEqual("1193248", output.Responses[4].QuestionID);
+ Assert.AreEqual("2493730", output.Responses[4].ResponseText);
+ Assert.AreEqual("1475425", output.Responses[5].QuestionID);
+ Assert.AreEqual("350000", output.Responses[5].ResponseText);
+ Assert.AreEqual("1475428", output.Responses[6].QuestionID);
+ Assert.AreEqual("999999", output.Responses[6].ResponseText);
+ Assert.AreEqual("1616871", output.Responses[7].QuestionID);
+ Assert.AreEqual("3261961", output.Responses[7].ResponseText);
+ Assert.AreEqual("1616873", output.Responses[8].QuestionID);
+ Assert.AreEqual("explosions", output.Responses[8].ResponseText);
+ }
+ }
+}
diff --git a/CBApi.Tests/CBApi/Models/ApplicationRequirementsTest.cs b/CBApi.Tests/CBApi/Models/ApplicationRequirementsTest.cs
new file mode 100644
index 0000000..0fd6025
--- /dev/null
+++ b/CBApi.Tests/CBApi/Models/ApplicationRequirementsTest.cs
@@ -0,0 +1,26 @@
+using CBApi.Models;
+using NUnit.Framework;
+using RestSharp;
+using RestSharp.Deserializers;
+using System;
+using System.IO;
+using System.Xml.Linq;
+
+namespace Tests.CBApi.models {
+ [TestFixture]
+ public class ApplicationRequirementsTest {
+ [Test]
+ public void DeserializationWorks_WhenPassedRightXML() {
+ var xmlpath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "testdata","ResponseBlankApplication.xml");
+ var doc = XDocument.Load(xmlpath);
+
+ var xml = new XmlDeserializer();
+ var output = xml.Deserialize(new RestResponse() { Content = doc.ToString() });
+ Assert.IsNotNull(output.Requirements);
+ Assert.AreEqual("2 Year Degree", output.Requirements.DegreeRequired.Trim());
+ Assert.AreEqual("Not Specified", output.Requirements.TravelRequired.Trim());
+ Assert.AreEqual("At least 5 year(s)", output.Requirements.ExperienceRequired.Trim());
+ Assert.IsTrue(output.Requirements.RequirementsText.Contains("nstallation tech, field rep, HVAC, mechanic, installer, repairman, auto technician, service specialist, millwright, millright"));
+ }
+ }
+}
diff --git a/CBApi.Tests/CBApi/Models/ApplyLinkTest.cs b/CBApi.Tests/CBApi/Models/ApplyLinkTest.cs
new file mode 100644
index 0000000..d8a1d1e
--- /dev/null
+++ b/CBApi.Tests/CBApi/Models/ApplyLinkTest.cs
@@ -0,0 +1,70 @@
+using CBApi.Models;
+using NUnit.Framework;
+using System.Collections.Specialized;
+
+namespace Tests.com.careerbuilder.CBApi.models
+{
+ [TestFixture]
+ public class ApplyLinkFromNameValueCollectionTest
+ {
+ private static NameValueCollection args;
+ private static ApplyLink applyLink;
+
+ [SetUp]
+ public static void Before()
+ {
+ args = new NameValueCollection() {
+ {"JobDID", "Fake_DID"},
+ {"SiteID", "Fake_Site_ID"},
+ {"HostSite", "US"},
+ {"JApply", "Fake_JApply"},
+ {"ApplicationEmail", "bob@test.org"},
+ {"TrackingID", "Fake_TrackingID"},
+ {"Cobrand", "Fake_Cobrand"}
+ };
+ applyLink = new ApplyLink(args);
+ }
+
+ [Test]
+ public void ApplyLink_Gets_JobDID_From_NameValueCollection()
+ {
+ Assert.AreEqual("Fake_DID", applyLink.JobDID);
+ }
+
+ [Test]
+ public void ApplyLink_Gets_SiteID_From_NameValueCollection()
+ {
+ Assert.AreEqual("Fake_Site_ID", applyLink.SiteID);
+ }
+
+ [Test]
+ public void ApplyLink_Gets_HostStie_From_NameValueCollection()
+ {
+ Assert.AreEqual("US", applyLink.HostSite);
+ }
+
+ [Test]
+ public void ApplyLink_Gets_JApply_From_NameValueCollection()
+ {
+ Assert.AreEqual("Fake_JApply", applyLink.JApply);
+ }
+
+ [Test]
+ public void ApplyLink_Gets_ApplicationEmail_From_NameValueCollection()
+ {
+ Assert.AreEqual("bob@test.org", applyLink.ApplicationEmail);
+ }
+
+ [Test]
+ public void ApplyLink_Gets_TrackingID_From_NameValueCollection()
+ {
+ Assert.AreEqual("Fake_TrackingID", applyLink.TrackingID);
+ }
+
+ [Test]
+ public void ApplyLink_Gets_Cobrand_From_NameValueCollection()
+ {
+ Assert.AreEqual("Fake_Cobrand", applyLink.Cobrand);
+ }
+ }
+}
diff --git a/CBApi.Tests/CBApi/Models/BlankApplicationTest.cs b/CBApi.Tests/CBApi/Models/BlankApplicationTest.cs
new file mode 100644
index 0000000..431ae3b
--- /dev/null
+++ b/CBApi.Tests/CBApi/Models/BlankApplicationTest.cs
@@ -0,0 +1,32 @@
+using CBApi.Models;
+using NUnit.Framework;
+using RestSharp;
+using RestSharp.Deserializers;
+using System;
+using System.IO;
+using System.Xml.Linq;
+
+namespace Tests.CBApi.models {
+ [TestFixture]
+ public class BlankApplicationTest {
+ [Test]
+ public void DeserializationWorks_WhenPassedRightXML() {
+ var xmlpath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "testdata","ResponseBlankApplication.xml");
+ var doc = XDocument.Load(xmlpath);
+
+ var xml = new XmlDeserializer();
+ var output = xml.Deserialize(new RestResponse() { Content = doc.ToString() });
+
+ Assert.IsNotNull(output);
+ Assert.AreEqual("http://api.careerbuilder.com/v1/application/submit", output.ApplicationSubmitServiceURL);
+ Assert.AreEqual("http://api.careerbuilder.com/v1/application/applylink?TrackingID=V8YDVG7V&JobDID=JHP3GR6135GF0QC5Q5B", output.ApplyURL);
+ Assert.AreEqual("JHP3GR6135GF0QC5Q5B", output.JobDID);
+ Assert.AreEqual("Field Service Technician", output.JobTitle);
+ Assert.IsNotNull(output.Requirements);
+ Assert.AreEqual(4, output.TotalQuestions);
+ Assert.AreEqual(3, output.TotalRequiredQuestions);
+ Assert.IsNotNull(output.Questions);
+ Assert.AreEqual(4, output.Questions.Count);
+ }
+ }
+}
diff --git a/CBApi.Tests/CBApi/Models/JobSearchResultTest.cs b/CBApi.Tests/CBApi/Models/JobSearchResultTest.cs
new file mode 100644
index 0000000..4c97a20
--- /dev/null
+++ b/CBApi.Tests/CBApi/Models/JobSearchResultTest.cs
@@ -0,0 +1,100 @@
+using NUnit.Framework;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using RestSharp;
+using RestSharp.Deserializers;
+using System.Xml;
+using System.Xml.Linq;
+using CBApi.Models.Responses;
+using System.IO;
+
+namespace Tests.CBApi.models {
+ [TestFixture]
+ public class JobSearchResultTest {
+
+ [Test]
+ public void DeserializationWorks_WhenPassedRightXML() {
+ var xmlpath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "testdata","ResponseJobSearch.xml");
+ var doc = XDocument.Load(xmlpath);
+
+ var xml = new XmlDeserializer();
+ var output = xml.Deserialize(new RestResponse() { Content = doc.ToString() });
+
+ Assert.IsNotNull(output.Results);
+ Assert.AreEqual(25, output.Results.Count);
+ Assert.AreEqual("Direct Sales Recruiting, LLC", output.Results[0].Company);
+ Assert.AreEqual("c35x165rs82x1bnbbc", output.Results[0].CompanyDID);
+ Assert.AreEqual("http://www.careerbuilder.com/Jobs/Company/C35X165RS82X1BNBBC/Direct-Sales-Recruiting-LLC/?sc_cmp1=13_JobRes_ComDet", output.Results[0].CompanyDetailsURL);
+ Assert.AreEqual("JHM0LH6LPCGLF3FR3ZB", output.Results[0].DID);
+ Assert.AreEqual("Mars", output.Results[0].DisplayCity);
+ Assert.AreEqual("41-4011.00", output.Results[0].OnetCode);
+ Assert.AreEqual("Full-Time", output.Results[0].EmploymentType);
+ Assert.AreEqual("http://api.careerbuilder.com/v1/joblink?TrackingID=DLR0T71H&DID=JHM0LH6LPCGLF3FR3ZB", output.Results[0].JobDetailsURL);
+ Assert.AreEqual("http://api.careerbuilder.com/v1/job?DID=JHM0LH6LPCGLF3FR3ZB&DeveloperKey=WXXXXXXXXXXXXXXXXXX", output.Results[0].JobServiceURL);
+ Assert.AreEqual("TN - Chattanooga", output.Results[0].Location);
+ Assert.AreEqual(35.04644f, output.Results[0].LocationLatitude);
+ Assert.AreEqual(-85.30946f, output.Results[0].LocationLongitude);
+ Assert.AreEqual("10/28/2012", output.Results[0].PostedDate);
+ Assert.AreEqual("5/15/2014 7:19:36 AM", output.Results[0].PostedTime);
+ Assert.AreEqual("$70k - $80k/year", output.Results[0].Pay);
+ Assert.AreEqual("http://www.careerbuilder.com/jobseeker/jobs/recommendedjobs.aspx?ipath=JELO&job_did=JHM0LH6LPCGLF3FR3ZB", output.Results[0].SimilarJobsURL);
+ Assert.AreEqual("Medical Sales-Tissue Graft/Biologics-Wound Care", output.Results[0].JobTitle);
+ Assert.AreEqual("http://emj.icbdr.com/MediaManagement/QS/I8F50C63D7B6SGPDXQS.gif", output.Results[0].CompanyImageURL);
+ Assert.IsNotNull(output.Facets);
+ Assert.AreEqual(0, output.Facets.Count);
+ Assert.AreEqual("1895 Tully Rd", output.Results[0].StreetAddress1);
+ Assert.AreEqual("Suite 187", output.Results[0].StreetAddress2);
+ }
+
+ [Test]
+ public void DeserializationWorks_WhenPassedRightXML_WithFacets() {
+ var xmlpath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "testdata","ResponseJobSearchWithFacets.xml");
+ var doc = XDocument.Load(xmlpath);
+
+ var xml = new XmlDeserializer();
+ var output = xml.Deserialize(new RestResponse() { Content = doc.ToString() });
+
+ Assert.IsNotNull(output.Results);
+ Assert.AreEqual(9, output.Results.Count);
+
+ var job = output.Results[2];
+ Assert.AreEqual("Bartech Group", job.Company);
+ Assert.AreEqual("c8g5xl6rqnqy6pmmtkb", job.CompanyDID);
+ Assert.AreEqual("http://www.careerbuilder.com/Jobs/Company/C8G5XL6RQNQY6PMMTKB/Bartech-Group/?sc_cmp1=13_JobRes_ComDet", job.CompanyDetailsURL);
+ Assert.AreEqual("JB71S364NQ0X8VY51WD", job.DID);
+ Assert.AreEqual("15-1071.00", job.OnetCode);
+ Assert.AreEqual("Network and Computer Systems Administrators", job.ONetFriendlyTitle);
+ //DescriptionTeaser left out intentionally tl;dr
+ Assert.AreEqual("Nearby", job.Distance);
+ Assert.AreEqual("Full-Time", job.EmploymentType);
+ Assert.AreEqual("http://api.careerbuilder.com/v1/joblink?TrackingID=CBWG7KSY&DID=JB71S364NQ0X8VY51WD", job.JobDetailsURL);
+ Assert.AreEqual("https://api.careerbuilder.com/v1/job?DID=JB71S364NQ0X8VY51WD&DeveloperKey=WDRF81661JM5WPB63DGJ", job.JobServiceURL);
+ Assert.AreEqual("GA - Various US Locations", job.Location);
+ Assert.AreEqual(33.74831f, job.LocationLatitude);
+ Assert.AreEqual(-84.39111f, job.LocationLongitude);
+ Assert.AreEqual("N/A", job.Pay);
+ Assert.AreEqual("http://www.careerbuilder.com/Jobs/SimilarJobs.aspx?ipath=JELO&job_did=JB71S364NQ0X8VY51WD", job.SimilarJobsURL);
+ Assert.AreEqual("IT Network Engineer (Network Administrator)", job.JobTitle);
+ Assert.AreEqual("http://emj.icbdr.com/MediaManagement/7P/MVJ81466WSNX4T1SG7P.gif", job.CompanyImageURL);
+
+ Assert.IsNotNull(output.Facets);
+ Assert.AreEqual(7, output.Facets.Count);
+
+ var facetNoItems = output.Facets[6];
+ Assert.AreEqual("FacetNormalizedCompanyDID", facetNoItems.JobSearchRequestParameter);
+ Assert.IsNotNull(facetNoItems.Items);
+ Assert.AreEqual(0, facetNoItems.Items.Count);
+
+ var facetOneItem = output.Facets[3];
+ Assert.AreEqual("FacetState", facetOneItem.JobSearchRequestParameter);
+ Assert.IsNotNull(facetOneItem.Items);
+ Assert.AreEqual(1, facetOneItem.Items.Count);
+ Assert.AreEqual("\"GA\"", facetOneItem.Items[0].JobSearchRequestValue);
+ Assert.AreEqual("Georgia", facetOneItem.Items[0].DisplayValue);
+ Assert.AreEqual(1868, facetOneItem.Items[0].Count);
+ }
+
+ }
+}
diff --git a/CBApi.Tests/CBApi/Models/JsonResponseWrapperTest.cs b/CBApi.Tests/CBApi/Models/JsonResponseWrapperTest.cs
new file mode 100644
index 0000000..f8776a5
--- /dev/null
+++ b/CBApi.Tests/CBApi/Models/JsonResponseWrapperTest.cs
@@ -0,0 +1,32 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using CBApi.Models;
+using NUnit.Framework;
+using RestSharp;
+using RestSharp.Deserializers;
+
+namespace Tests.com.careerbuilder.CBApi.models {
+
+ [TestFixture]
+ public class JsonResponseWrapperTest {
+
+ [Test]
+ public void DeserializationWorks_WhenPassedRightJSON_Response() {
+ var jsonPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "testdata", "JsonResponseWrapper.json");
+ var streamReader = new StreamReader(jsonPath);
+ var json = new JsonDeserializer();
+
+ var output = json.Deserialize>(new RestResponse() { Content = streamReader.ReadToEnd() });
+ Assert.AreEqual(output.TotalResults, "1");
+ Assert.AreEqual(output.ReturnedResults, "1");
+ Assert.AreEqual(output.Results[0].Language, "Greek");
+ Assert.AreEqual(output.Results[0].Value, "GR");
+ CollectionAssert.AreEqual(output.Errors, new List());
+ Assert.AreEqual(output.Timestamp, "2015-06-10T14:56:37.3319476-04:00");
+ Assert.AreEqual(output.Status, "Success");
+ }
+ }
+}
diff --git a/CBApi.Tests/CBApi/Models/QuestionTest.cs b/CBApi.Tests/CBApi/Models/QuestionTest.cs
new file mode 100644
index 0000000..cb07467
--- /dev/null
+++ b/CBApi.Tests/CBApi/Models/QuestionTest.cs
@@ -0,0 +1,48 @@
+using CBApi.Models;
+using NUnit.Framework;
+using RestSharp;
+using RestSharp.Deserializers;
+using System;
+using System.IO;
+using System.Xml.Linq;
+
+namespace Tests.CBApi.models {
+ [TestFixture]
+ public class QuestionTest {
+ [Test]
+ public void DeserializationWorks_WhenPassedRightXML() {
+ var xmlpath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "testdata","ResponseBlankApplication.xml");
+ var doc = XDocument.Load(xmlpath);
+
+ var xml = new XmlDeserializer();
+ var output = xml.Deserialize(new RestResponse() { Content = doc.ToString() });
+ Assert.IsNotNull(output.Questions);
+ Assert.AreEqual(4,output.Questions.Count);
+
+ Assert.AreEqual("ApplicantName", output.Questions[0].QuestionID);
+ Assert.AreEqual("Basic", output.Questions[0].QuestionType);
+ Assert.AreEqual(true, output.Questions[0].IsRequired);
+ Assert.AreEqual("Text 50", output.Questions[0].ExpectedResponseFormat);
+ Assert.AreEqual("Your name", output.Questions[0].QuestionText);
+
+ Assert.AreEqual("ApplicantEmail", output.Questions[1].QuestionID);
+ Assert.AreEqual("Basic", output.Questions[1].QuestionType);
+ Assert.AreEqual(true, output.Questions[1].IsRequired);
+ Assert.AreEqual("Text 50", output.Questions[1].ExpectedResponseFormat);
+ Assert.AreEqual("Your email", output.Questions[1].QuestionText);
+
+
+ Assert.AreEqual("Resume", output.Questions[2].QuestionID);
+ Assert.AreEqual("Basic", output.Questions[2].QuestionType);
+ Assert.AreEqual(true, output.Questions[2].IsRequired);
+ Assert.AreEqual("Text 5000", output.Questions[2].ExpectedResponseFormat);
+ Assert.AreEqual("Your resume", output.Questions[2].QuestionText);
+
+ Assert.AreEqual("CoverLetter", output.Questions[3].QuestionID);
+ Assert.AreEqual("Basic", output.Questions[3].QuestionType);
+ Assert.AreEqual(false, output.Questions[3].IsRequired);
+ Assert.AreEqual("Text 5000", output.Questions[3].ExpectedResponseFormat);
+ Assert.AreEqual("Your cover letter", output.Questions[3].QuestionText);
+ }
+ }
+}
diff --git a/CBApi.Tests/CBApi/Models/RecommendJobResultTest.cs b/CBApi.Tests/CBApi/Models/RecommendJobResultTest.cs
new file mode 100644
index 0000000..3d6dfe9
--- /dev/null
+++ b/CBApi.Tests/CBApi/Models/RecommendJobResultTest.cs
@@ -0,0 +1,43 @@
+using System;
+using System.IO;
+using System.Xml.Linq;
+using CBApi.Models;
+using NUnit.Framework;
+using RestSharp;
+using RestSharp.Deserializers;
+
+namespace Tests.com.careerbuilder.CBApi.models
+{
+ [TestFixture]
+ public class RecommendJobResultTest
+ {
+ [Test]
+ public void VerifyCorrectXml_DeserializesAppropriately() {
+ var xmlpath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "testdata","RecommendJobResult.xml");
+ var doc = XDocument.Load(xmlpath);
+
+ var xml = new XmlDeserializer();
+ var output = xml.Deserialize(new RestResponse() { Content = doc.ToString() });
+
+ Assert.IsNotNull(output);
+ Assert.AreEqual("JHT3D8649TV74ZNK0GJ", output.JobDID);
+ Assert.AreEqual("CJ123_COMPANY_DID", output.Company.CompanyDID);
+ Assert.AreEqual("www.qualitystaffing.com", output.Company.CompanyDetailsURL);
+ Assert.AreEqual(1, output.Relevancy);
+ Assert.AreEqual("47-2211.00", output.ONet);
+ Assert.AreEqual("Sheet Metal Workers", output.ONetFriendlyTitle);
+ Assert.AreEqual("http://www.careerbuilder.com/jobseeker/jobs/recommendedjobs.aspx?ipath=JELO&job_did=JHT3D8649TV74ZNK0GJ", output.SimilarJobsURL);
+ Assert.AreEqual("http://api.careerbuilder.com/v1/job?DID=JHT3D8649TV74ZNK0GJ&DeveloperKey=XYZ_DEVKEY", output.JobServiceURL);
+ Assert.AreEqual("http://api.careerbuilder.com/v1/joblink?DID=JHT3D8649TV74ZNK0GJ&DeveloperKey=XYZ_DEVKEY", output.JobDetailsURL);
+ Assert.AreEqual("Georgetown", output.Location.City);
+ Assert.AreEqual("DE", output.Location.State);
+ Assert.AreEqual("Fabrication - Assembly - Sheet Metal", output.Title);
+ Assert.AreEqual(true, output.CanBeQuickApplied);
+ Assert.AreEqual("CX", output.MatcherType);
+ Assert.AreEqual("Not Specified", output.EducationRequired);
+ Assert.AreEqual("Full-Time", output.EmploymentType);
+ Assert.AreEqual("$20k - $30k/year", output.Pay);
+ Assert.AreEqual("CanBulkApply", output.ApplyRequirements[0]);
+ }
+ }
+}
diff --git a/CBApi.Tests/CBApi/Models/ResponseJobSearchTest.cs b/CBApi.Tests/CBApi/Models/ResponseJobSearchTest.cs
new file mode 100644
index 0000000..a4db6c2
--- /dev/null
+++ b/CBApi.Tests/CBApi/Models/ResponseJobSearchTest.cs
@@ -0,0 +1,35 @@
+using NUnit.Framework;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using RestSharp;
+using RestSharp.Deserializers;
+using System.Xml;
+using System.Xml.Linq;
+using CBApi.Models.Responses;
+using System.IO;
+
+namespace Tests.CBApi.models {
+ [TestFixture]
+ public class ResponseJobSearchTest {
+ [Test]
+ public void DeserializationWorks_WhenPassedRightXML() {
+ var xmlpath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "testdata","ResponseJobSearch.xml");
+ var doc = XDocument.Load(xmlpath);
+
+ var xml = new XmlDeserializer();
+ var output = xml.Deserialize(new RestResponse() { Content = doc.ToString() });
+
+ Assert.IsNotNull(output);
+ Assert.AreEqual(386163, output.TotalCount);
+ Assert.AreEqual(15447, output.TotalPages);
+ Assert.AreEqual(1, output.FirstItemIndex);
+ Assert.AreEqual(25, output.LastItemIndex);
+
+ Assert.IsNotNull(output.Results);
+ Assert.AreEqual(25, output.Results.Count);
+
+ }
+ }
+}
diff --git a/CBApi.Tests/CBApi/Models/SavedSearchCreateTest.cs b/CBApi.Tests/CBApi/Models/SavedSearchCreateTest.cs
new file mode 100644
index 0000000..b3ea55e
--- /dev/null
+++ b/CBApi.Tests/CBApi/Models/SavedSearchCreateTest.cs
@@ -0,0 +1,40 @@
+using NUnit.Framework;
+using System;
+using RestSharp;
+using RestSharp.Deserializers;
+using System.Xml.Linq;
+using System.IO;
+using CBApi.Models;
+
+namespace Tests.CBApi.models
+{
+ [TestFixture]
+ public class SavedSearchCreateTest
+ {
+ [Test]
+ public void DeserializationWorks_WhenPassedRightXML()
+ {
+ var xmlpath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "testdata","SaveSearchCreateData.xml");
+ var doc = XDocument.Load(xmlpath);
+
+ var xml = new XmlDeserializer();
+ var output = xml.Deserialize(new RestResponse() { Content = doc.ToString() });
+ Assert.IsNotNull(output, "no deserialization worked");
+ Assert.IsNotNull(output.SavedSearch.SavedSearchParameters, "SavedSearchParameters deserialization Did not work");
+ Assert.AreEqual("lotsloc", output.SavedSearch.SearchName, "search name did not dezerialize");
+ Assert.AreEqual("none", output.SavedSearch.IsDailyEmail.ToLower(), "IsDailyEmail did not dezerialize");
+ Assert.AreEqual("Chicago, Il, Atlanta, Ga, New York, Ny", output.SavedSearch.SavedSearchParameters.Location, "Location did not dezerialize");
+ Assert.AreEqual(false, output.SavedSearch.SavedSearchParameters.ExcludeNational, "ExcludeNational did not dezerialize");
+ Assert.AreEqual("DRNS", output.SavedSearch.SavedSearchParameters.EducationCode, "educationCode did not dezerialize");
+ Assert.AreEqual("AND", output.SavedSearch.SavedSearchParameters.BooleanOperator, "booleanoperator did not dezerialize");
+ Assert.AreEqual("Pay", output.SavedSearch.SavedSearchParameters.OrderBy, "OrderBy did not dezerialize");
+ Assert.AreEqual(70, output.SavedSearch.SavedSearchParameters.PayHigh, "pay high did not dezerialize");
+ Assert.AreEqual(40, output.SavedSearch.SavedSearchParameters.PayLow, "Pay Low did not dezerialize");
+ Assert.AreEqual(30, output.SavedSearch.SavedSearchParameters.PostedWithin, "posted within did not dezerialize");
+ Assert.AreEqual(30, output.SavedSearch.SavedSearchParameters.Radius, "radius did not dezerialize");
+ Assert.AreEqual(false, output.SavedSearch.SavedSearchParameters.PayInfoOnly, "pay info only did not dezerialize");
+ Assert.AreEqual(false, output.SavedSearch.SavedSearchParameters.SpecificEducation, "specific education did not dezerialize");
+ Assert.AreEqual("ascending", output.SavedSearch.SavedSearchParameters.OrderDirection, "order direction did not dezerialize");
+ }
+ }
+}
diff --git a/CBApi.Tests/CBApi/Models/SavedSearchDeleteTest.cs b/CBApi.Tests/CBApi/Models/SavedSearchDeleteTest.cs
new file mode 100644
index 0000000..5449163
--- /dev/null
+++ b/CBApi.Tests/CBApi/Models/SavedSearchDeleteTest.cs
@@ -0,0 +1,29 @@
+using System;
+using NUnit.Framework;
+using RestSharp;
+using RestSharp.Deserializers;
+using CBApi.Models;
+using System.IO;
+using System.Xml.Linq;
+
+namespace Tests.CBApi.models {
+ [TestFixture]
+ public class SavedSearchDeleteTest
+ {
+ [Test]
+ public void DeserializationWorks_WhenPassedRightXML() {
+ var xmlpath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "testdata","SavedSearchDeleteResult.xml");
+ var doc = XDocument.Load(xmlpath);
+
+ var xml = new XmlDeserializer();
+ var output = xml.Deserialize(new RestResponse() { Content = doc.ToString() });
+
+ Assert.IsNotNull(output);
+ Assert.AreEqual("WD******************", output.DeveloperKey);
+ Assert.AreEqual("b5**************************************************************", output.ExternalID);
+ Assert.AreEqual("ec**************************************************************", output.ExternalUserID);
+ Assert.AreEqual("US", output.HostSite);
+ Assert.AreEqual("Success", output.Status);
+ }
+ }
+}
diff --git a/CBApi.Tests/CBApi/Models/SavedSearchListResponseModelTest.cs b/CBApi.Tests/CBApi/Models/SavedSearchListResponseModelTest.cs
new file mode 100644
index 0000000..5ff75eb
--- /dev/null
+++ b/CBApi.Tests/CBApi/Models/SavedSearchListResponseModelTest.cs
@@ -0,0 +1,37 @@
+using System;
+using System.IO;
+using System.Xml.Linq;
+using CBApi.Models;
+using NUnit.Framework;
+using RestSharp;
+using RestSharp.Deserializers;
+
+namespace Tests.com.careerbuilder.CBApi.models {
+ [TestFixture]
+ public class SavedSearchListResponseModelTest {
+
+ [Test]
+ public void DeserializationWorks_WhenPassedRightXML() {
+ var xmlpath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "testdata","SavedSearchListResponseModel.xml");
+ var doc = XDocument.Load(xmlpath);
+
+ var xml = new XmlDeserializer();
+ var response = xml.Deserialize(new RestResponse() { Content = doc.ToString() });
+
+ Assert.IsNotNull(response);
+ Assert.IsNotNull(response.SavedSearches);
+ Assert.AreEqual(2, response.SavedSearches.Count, "The count of saved searches in the xml file should be 2");
+
+ SavedSearch search1 = response.SavedSearches[0];
+ Assert.AreEqual("software engineer", search1.SearchName);
+ Assert.AreEqual("US", search1.HostSite);
+ Assert.AreEqual("ea6c190017576af21724885aa7bde734130a06bbf32fd5e30f0ba814e2a68b2d", search1.ExternalID);
+
+ SavedSearch search2 = response.SavedSearches[1];
+ Assert.AreEqual("engineer in 30071", search2.SearchName);
+ Assert.AreEqual("US", search2.HostSite);
+ Assert.AreEqual("f28273259cf31cbd1c0d07bf727deb8447a54d7e1c59d32399b937d469cf0a54", search2.ExternalID);
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/CBApi.Tests/CBApi/Models/SavedSearchRetrieveTest.cs b/CBApi.Tests/CBApi/Models/SavedSearchRetrieveTest.cs
new file mode 100644
index 0000000..f67fa04
--- /dev/null
+++ b/CBApi.Tests/CBApi/Models/SavedSearchRetrieveTest.cs
@@ -0,0 +1,41 @@
+using NUnit.Framework;
+using System;
+using RestSharp;
+using RestSharp.Deserializers;
+using System.Xml.Linq;
+using System.IO;
+using CBApi.Models;
+
+namespace Tests.CBApi.models
+{
+ [TestFixture]
+ public class SavedSearchRetrieveTest
+ {
+ [Test]
+ public void DeserializationWorks_WhenPassedRightXML()
+ {
+ //using the same XML as SavedSearchCreate since they output the same
+ var xmlpath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "testdata","SaveSearchCreateData.xml");
+ var doc = XDocument.Load(xmlpath);
+
+ var xml = new XmlDeserializer();
+ var output = xml.Deserialize(new RestResponse() { Content = doc.ToString() });
+ Assert.IsNotNull(output, "no deserialization worked");
+ Assert.IsNotNull(output.SavedSearch.SavedSearchParameters, "SavedSearchParameters deserialization Did not work");
+ Assert.AreEqual("lotsloc", output.SavedSearch.SearchName, "search name did not dezerialize");
+ Assert.AreEqual("none", output.SavedSearch.IsDailyEmail.ToLower(), "IsDailyEmail did not dezerialize");
+ Assert.AreEqual("Chicago, Il, Atlanta, Ga, New York, Ny", output.SavedSearch.SavedSearchParameters.Location, "Location did not dezerialize");
+ Assert.AreEqual(false, output.SavedSearch.SavedSearchParameters.ExcludeNational, "ExcludeNational did not dezerialize");
+ Assert.AreEqual("DRNS", output.SavedSearch.SavedSearchParameters.EducationCode, "educationCode did not dezerialize");
+ Assert.AreEqual("AND", output.SavedSearch.SavedSearchParameters.BooleanOperator, "booleanoperator did not dezerialize");
+ Assert.AreEqual("Pay", output.SavedSearch.SavedSearchParameters.OrderBy, "OrderBy did not dezerialize");
+ Assert.AreEqual(70, output.SavedSearch.SavedSearchParameters.PayHigh, "pay high did not dezerialize");
+ Assert.AreEqual(40, output.SavedSearch.SavedSearchParameters.PayLow, "Pay Low did not dezerialize");
+ Assert.AreEqual(30, output.SavedSearch.SavedSearchParameters.PostedWithin, "posted within did not dezerialize");
+ Assert.AreEqual(30, output.SavedSearch.SavedSearchParameters.Radius, "radius did not dezerialize");
+ Assert.AreEqual(false, output.SavedSearch.SavedSearchParameters.PayInfoOnly, "pay info only did not dezerialize");
+ Assert.AreEqual(false, output.SavedSearch.SavedSearchParameters.SpecificEducation, "specific education did not dezerialize");
+ Assert.AreEqual("ascending", output.SavedSearch.SavedSearchParameters.OrderDirection, "order direction did not dezerialize");
+ }
+ }
+}
diff --git a/CBApi.Tests/CBApi/Models/SavedSearchUpdateTest.cs b/CBApi.Tests/CBApi/Models/SavedSearchUpdateTest.cs
new file mode 100644
index 0000000..9fc73e9
--- /dev/null
+++ b/CBApi.Tests/CBApi/Models/SavedSearchUpdateTest.cs
@@ -0,0 +1,40 @@
+using CBApi.Models;
+using NUnit.Framework;
+using RestSharp;
+using RestSharp.Deserializers;
+using System;
+using System.IO;
+using System.Xml.Linq;
+
+namespace Tests.CBApi.models
+{
+ [TestFixture]
+ public class SavedSearchUpdateTest
+ {
+ [Test]
+ public void DeserializationWorks_WhenPassedRightXML()
+ {
+ var xmlpath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "testdata","SaveSearchCreateData.xml");
+ var doc = XDocument.Load(xmlpath);
+
+ var xml = new XmlDeserializer();
+ var output = xml.Deserialize(new RestResponse() { Content = doc.ToString() });
+ Assert.IsNotNull(output, "no deserialization worked");
+ Assert.IsNotNull(output.SavedSearch.SavedSearchParameters, "SavedSearchParameters deserialization Did not work");
+ Assert.AreEqual("lotsloc", output.SavedSearch.SearchName, "search name did not dezerialize");
+ Assert.AreEqual("none", output.SavedSearch.IsDailyEmail.ToLower(), "IsDailyEmail did not dezerialize");
+ Assert.AreEqual("Chicago, Il, Atlanta, Ga, New York, Ny", output.SavedSearch.SavedSearchParameters.Location, "Location did not dezerialize");
+ Assert.AreEqual(false, output.SavedSearch.SavedSearchParameters.ExcludeNational, "ExcludeNational did not dezerialize");
+ Assert.AreEqual("DRNS", output.SavedSearch.SavedSearchParameters.EducationCode, "educationCode did not dezerialize");
+ Assert.AreEqual("AND", output.SavedSearch.SavedSearchParameters.BooleanOperator, "booleanoperator did not dezerialize");
+ Assert.AreEqual("Pay", output.SavedSearch.SavedSearchParameters.OrderBy, "OrderBy did not dezerialize");
+ Assert.AreEqual(70, output.SavedSearch.SavedSearchParameters.PayHigh, "pay high did not dezerialize");
+ Assert.AreEqual(40, output.SavedSearch.SavedSearchParameters.PayLow, "Pay Low did not dezerialize");
+ Assert.AreEqual(30, output.SavedSearch.SavedSearchParameters.PostedWithin, "posted within did not dezerialize");
+ Assert.AreEqual(30, output.SavedSearch.SavedSearchParameters.Radius, "radius did not dezerialize");
+ Assert.AreEqual(false, output.SavedSearch.SavedSearchParameters.PayInfoOnly, "pay info only did not dezerialize");
+ Assert.AreEqual(false, output.SavedSearch.SavedSearchParameters.SpecificEducation, "specific education did not dezerialize");
+ Assert.AreEqual("ascending", output.SavedSearch.SavedSearchParameters.OrderDirection, "order direction did not dezerialize");
+ }
+ }
+}
diff --git a/CBApi.Tests/CBApi/Models/service/TargetSiteMock.cs b/CBApi.Tests/CBApi/Models/service/TargetSiteMock.cs
new file mode 100644
index 0000000..46b5734
--- /dev/null
+++ b/CBApi.Tests/CBApi/Models/service/TargetSiteMock.cs
@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using CBApi.Models.Service;
+
+namespace Tests.CBApi.models.service {
+ public class TargetSiteMock : TargetSite {
+ public TargetSiteMock(string domain) {
+ _Domain = domain;
+ }
+
+ public string SetHost {
+ set { _HostOverride = value; }
+ }
+
+ public bool SetSecure {
+ set { _Secure = value; }
+ }
+
+ public Dictionary SetHeaders {
+ set { _AdditionalHeaders = value; }
+ get {return _AdditionalHeaders; }
+ }
+ }
+}
diff --git a/CBApi.Tests/CBApi/framework/ErrorParserTests.cs b/CBApi.Tests/CBApi/framework/ErrorParserTests.cs
new file mode 100644
index 0000000..5518cb5
--- /dev/null
+++ b/CBApi.Tests/CBApi/framework/ErrorParserTests.cs
@@ -0,0 +1,180 @@
+using NUnit.Framework;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using CBApi.Framework;
+using Moq;
+using RestSharp;
+using CBApi;
+
+namespace Tests.CBApi.framework {
+ [TestFixture]
+ public class ErrorParserTests {
+ [Test]
+ public void CheckForErrors_DoesNothing_WhenPassedNullResponse() {
+ try {
+ ErrorParser.CheckForErrors(null);
+ Assert.IsTrue(true);
+ } catch (Exception) {
+ Assert.Fail();
+ }
+ }
+
+ [Test]
+ public void CheckForErrors_DoesNothing_WhenNoErrorsArePresent() {
+ //Mock crap
+ var response = new Mock();
+ response.Setup(x => x.Content).Returns("");
+ response.Setup(x => x.ResponseStatus).Returns(ResponseStatus.Completed);
+
+ try {
+ ErrorParser.CheckForErrors(response.Object);
+ Assert.IsTrue(true);
+ } catch (Exception ex) {
+ Assert.Fail(ex.Message);
+ }
+ }
+
+ [Test]
+ public void CheckForErrors_ThrowsGenericException_WhenThereWasAConnectionError_WithNoErrorMessage() {
+ //Mock crap
+ var response = new Mock();
+ response.Setup(x => x.Content).Returns("");
+ response.Setup(x => x.ResponseStatus).Returns(ResponseStatus.Aborted);
+
+ try {
+ ErrorParser.CheckForErrors(response.Object);
+ Assert.Fail();
+ } catch (APIException ex) {
+ Assert.AreEqual("An unknown error occured while making the API call", ex.Message);
+ Assert.AreEqual(1, ex.APIErrors.Count);
+ }
+ }
+
+ [Test]
+ public void CheckForErrors_ThrowsAPIException_WhenThereWasAConnectionError() {
+ //Mock crap
+ var response = new Mock();
+ response.Setup(x => x.Content).Returns("");
+ response.Setup(x => x.ResponseStatus).Returns(ResponseStatus.None);
+ response.Setup(x => x.ErrorMessage).Returns("I AM A BANANA");
+
+ try {
+ ErrorParser.CheckForErrors(response.Object);
+ Assert.Fail();
+ } catch (APIException ex) {
+ Assert.AreEqual("I AM A BANANA", ex.Message);
+ Assert.AreEqual(1, ex.APIErrors.Count);
+ }
+ }
+
+ [Test]
+ public void CheckForErrors_ThrowsAPITimeoutException_WhenThereWasATimeout() {
+ //Mock crap
+ var response = new Mock();
+ response.Setup(x => x.Content).Returns("");
+ response.Setup(x => x.ResponseStatus).Returns(ResponseStatus.TimedOut);
+ response.Setup(x => x.ErrorMessage).Returns("I AM A BANANA");
+
+ try {
+ ErrorParser.CheckForErrors(response.Object);
+ Assert.Fail();
+ } catch (APITimeoutException ex) {
+ Assert.AreEqual("I AM A BANANA", ex.Message);
+ Assert.AreEqual(1, ex.APIErrors.Count);
+ }
+ }
+
+ [Test]
+ public void CheckForErrors_ThrowsAPIException_WhenThereWasAnErrorNode() {
+ //Mock crap
+ var response = new Mock();
+ response.Setup(x => x.Content).Returns("DeveloperKey is invalid or does not have permission to perform Categories requests.US10/26/2012 10:29:08 PM");
+ response.Setup(x => x.ResponseStatus).Returns(ResponseStatus.Completed);
+ response.Setup(x => x.ErrorMessage).Returns("");
+
+ try {
+ ErrorParser.CheckForErrors(response.Object);
+ Assert.Fail();
+ } catch (APIException ex) {
+ Assert.AreEqual("DeveloperKey is invalid or does not have permission to perform Categories requests.", ex.Message);
+ Assert.AreEqual(1, ex.APIErrors.Count);
+ }
+ }
+
+ [Test]
+ public void CheckForErrors_ThrowsAPIExceptionWithMultipleMessages_WhenThereAreErrorNodes() {
+ //Mock crap
+ var response = new Mock();
+ response.Setup(x => x.Content).Returns("DeveloperKey is invalid or does not have permission to perform Categories requests.You smell funnyUS10/26/2012 10:29:08 PM");
+ response.Setup(x => x.ResponseStatus).Returns(ResponseStatus.Completed);
+ response.Setup(x => x.ErrorMessage).Returns("");
+
+ try {
+ ErrorParser.CheckForErrors(response.Object);
+ Assert.Fail();
+ } catch (APIException ex) {
+ Assert.AreEqual("DeveloperKey is invalid or does not have permission to perform Categories requests.", ex.Message);
+ Assert.AreEqual(2, ex.APIErrors.Count);
+ }
+ }
+
+ [Test]
+ public void CheckForErrors_ThrowsAPIExceptionWithMultipleMessages_WhenThereAreAllKindsOfErrors() {
+ //Mock crap
+ var response = new Mock();
+ response.Setup(x => x.Content).Returns("DeveloperKey is invalid or does not have permission to perform Categories requests.You smell funnyUS10/26/2012 10:29:08 PM");
+ response.Setup(x => x.ResponseStatus).Returns(ResponseStatus.TimedOut);
+ response.Setup(x => x.ErrorMessage).Returns("I am on Fire, thanks now I am dead");
+
+ try {
+ ErrorParser.CheckForErrors(response.Object);
+ Assert.Fail();
+ } catch (APIException ex) {
+ Assert.AreEqual("DeveloperKey is invalid or does not have permission to perform Categories requests.", ex.Message);
+ Assert.AreEqual(2, ex.APIErrors.Count);
+ }
+ }
+
+ [Test]
+ public void CheckForErrors_ThrowsAPIException_WhenThereWasAnErrorNode_AndNamespaces() {
+ //Mock crap
+ var response = new Mock();
+ response.Setup(x => x.Content).Returns("The Developer key you have provided does not have permission to preform this request." +
+ "0Error2013-11-25T10:00:10.1547889-05:00" +
+ "0");
+ response.Setup(x => x.ResponseStatus).Returns(ResponseStatus.Error);
+ response.Setup(x => x.ErrorMessage).Returns("I am on Fire, thanks now I am dead");
+
+ try {
+ ErrorParser.CheckForErrors(response.Object);
+ Assert.Fail();
+ } catch (APIException ex) {
+ Assert.AreEqual("The Developer key you have provided does not have permission to preform this request.", ex.Message);
+ Assert.AreEqual(1, ex.APIErrors.Count);
+ }
+ }
+
+ [Test]
+ public void CheckForErrors_ThrowsAPIExceptionWithMultipleMessages_WhenThereAreAllKindsOfErrors_AndNamespaces() {
+ //Mock crap
+ var response = new Mock();
+ response.Setup(x => x.Content).Returns("The Developer key you have provided does not have permission to preform this request." +
+ "You smell funny." + "0Error" +
+ "2013-11-25T10:00:10.1547889-05:000");
+ response.Setup(x => x.ResponseStatus).Returns(ResponseStatus.Error);
+ response.Setup(x => x.ErrorMessage).Returns("I am on Fire, thanks now I am dead");
+
+ try {
+ ErrorParser.CheckForErrors(response.Object);
+ Assert.Fail();
+ } catch (APIException ex) {
+ Assert.AreEqual("The Developer key you have provided does not have permission to preform this request.", ex.Message);
+ Assert.AreEqual(2, ex.APIErrors.Count);
+ }
+ }
+ }
+}
diff --git a/CBApi.Tests/CBApi/framework/Requests/ApplicationFormRequestTest.cs b/CBApi.Tests/CBApi/framework/Requests/ApplicationFormRequestTest.cs
new file mode 100644
index 0000000..87556e9
--- /dev/null
+++ b/CBApi.Tests/CBApi/framework/Requests/ApplicationFormRequestTest.cs
@@ -0,0 +1,150 @@
+//using CBApi;
+//using CBApi.Framework.Requests;
+//using CBApi.Models;
+//using NUnit.Framework;
+//using Moq;
+//using RestSharp;
+//using System;
+//using Tests.CBApi.models.requests;
+//using Tests.CBApi.models.service;
+
+//namespace Tests.CBApi.framework.requests
+//{
+// [TestFixture]
+// public class ApplicationFormRequestTest
+// {
+// private APISettings _Settings = new APISettings();
+// [Test]
+// public void Constructor_SetsJobDID()
+// {
+// var request = new ApplicationFormRequest("JXXXXXXXXXXXXXXXXXX", _Settings);
+// Assert.AreEqual("JXXXXXXXXXXXXXXXXXX", request.JobDID);
+// }
+
+// [Test]
+// public void Constructor_ThrowsException_WhenPassedNullOrEmpty()
+// {
+// try
+// {
+// var request = new BlankAppStub(null, "DevKey", "api.careerbuilder.com", "", "");
+// Assert.Fail("Should have thrown exception");
+// }
+// catch (ArgumentNullException ex)
+// {
+// Assert.IsInstanceOfType(ex, typeof (ArgumentNullException));
+// }
+
+// try
+// {
+// var request = new BlankAppStub("", "DevKey", "api.careerbuilder.com", "", "");
+// Assert.Fail("Should have thrown exception");
+// }
+// catch (ArgumentNullException ex)
+// {
+// Assert.IsInstanceOfType(ex, typeof (ArgumentNullException));
+// }
+// }
+
+// [Test]
+// public void Constructor_ThrowsException_WhenPassedBadJobDID()
+// {
+// try
+// {
+// var request = new BlankAppStub("UXXXXXXXXXXXXXXXXXXX", "DevKey", "api.careerbuilder.com", "", "");
+// Assert.Fail("Should have thrown exception");
+// }
+// catch (ArgumentException ex)
+// {
+// Assert.IsInstanceOf(ex);
+// }
+
+// try
+// {
+// var request = new BlankAppStub("JXXXXXXXXXXX", "DevKey", "api.careerbuilder.com", "", "");
+// Assert.Fail("Should have thrown exception");
+// }
+// catch (ArgumentException ex)
+// {
+// Assert.IsInstanceOf(ex);
+// }
+// }
+
+// [Test]
+// public void GetRequestURL_BuildsCorrectEndpointAddress()
+// {
+// var request = new BlankAppStub("JXXXXXXXXXXXXXXXXXX", "DevKey", "api.careerbuilder.com", "", "");
+// Assert.AreEqual("https://api.careerbuilder.com/v1/application/blank", request.RequestURL);
+// }
+
+// [Test]
+// public void Retrieve_PerformsCorrectRequest()
+// {
+// //Setup
+// var request = new BlankAppStub("JXXXXXXXXXXXXXXXXXX", "DevKey", "api.careerbuilder.com", "", "");
+
+// //Mock crap
+// var response = new RestResponse {Data = new BlankApplication()};
+
+// var restReq = new Mock();
+// restReq.Setup(x => x.AddParameter("DeveloperKey", "DevKey"));
+// restReq.Setup(x => x.AddParameter("JobDID", "JXXXXXXXXXXXXXXXXXX"));
+// restReq.SetupSet(x => x.RootElement = "BlankApplication");
+
+// var restClient = new Mock();
+// restClient.SetupSet(x => x.BaseUrl = "https://api.careerbuilder.com/v1/application/blank");
+// restClient.Setup(x => x.Execute(It.IsAny())).Returns(response);
+
+// request.Request = restReq.Object;
+// request.Client = restClient.Object;
+
+// //Assert
+// BlankApplication resp = request.Retrieve();
+// restReq.VerifyAll();
+// restClient.VerifyAll();
+// }
+// }
+
+// internal class BlankAppStub : BlankApplicationRequest
+// {
+// public BlankAppStub(string jobDID, string key, string domain, string cobrand, string siteid)
+// : base(jobDID, new APISettings() { DevKey = key, CobrandCode = cobrand, SiteId = siteid, TargetSite = new TargetSiteMock(domain) })
+// {
+// }
+
+// public string JobDID
+// {
+// get { return JobDid; }
+// }
+
+// public string DevKey
+// {
+// get { return _Settings.DevKey; }
+// }
+
+// public string Domain
+// {
+// get { return _Settings.TargetSite.Domain; }
+// }
+
+// public string RequestURL
+// {
+// get { return base.GetRequestURL(); }
+// }
+
+// public IRestClient Client
+// {
+// get { return _client; }
+// set { _client = value; }
+// }
+
+// public IRestRequest Request
+// {
+// get { return _request; }
+// set { _request = value; }
+// }
+
+// protected override void CheckForErrors(IRestResponse response) {
+
+// }
+// }
+//}
\ No newline at end of file
diff --git a/CBApi.Tests/CBApi/framework/Requests/ApplyLinkRequestStub.cs b/CBApi.Tests/CBApi/framework/Requests/ApplyLinkRequestStub.cs
new file mode 100644
index 0000000..006c691
--- /dev/null
+++ b/CBApi.Tests/CBApi/framework/Requests/ApplyLinkRequestStub.cs
@@ -0,0 +1,23 @@
+using CBApi;
+using CBApi.Framework.Requests;
+using CBApi.Models;
+using RestSharp;
+using System.Collections.Specialized;
+
+namespace Tests.com.careerbuilder.CBApi.framework.requests {
+ internal class ApplyLinkRequestStub : ApplyLinkRequest {
+
+ public ApplyLinkRequestStub(NameValueCollection args, APISettings settings) :
+ base(new ApplyLink(args), settings) { }
+
+ public ApplyLinkRequestStub(ApplyLink args, APISettings settings) :
+ base(args, settings) { }
+
+ public IRestClient Client {
+ get { return _client; }
+ set { _client = value; }
+ }
+
+ public ApplyLink Model { get { return model; } }
+ }
+}
diff --git a/CBApi.Tests/CBApi/framework/Requests/ApplyLinkRequestTest.cs b/CBApi.Tests/CBApi/framework/Requests/ApplyLinkRequestTest.cs
new file mode 100644
index 0000000..87b9bde
--- /dev/null
+++ b/CBApi.Tests/CBApi/framework/Requests/ApplyLinkRequestTest.cs
@@ -0,0 +1,25 @@
+using CBApi;
+using NUnit.Framework;
+using Moq;
+using RestSharp;
+using System;
+using System.Collections.Specialized;
+
+namespace Tests.com.careerbuilder.CBApi.framework.requests {
+ [TestFixture]
+ public class ApplyLinkRequestTest {
+ [Test]
+ public void Retrieve_Returns_A_Uri_String_With_JobDID()
+ {
+ var request = new ApplyLinkRequestStub(new NameValueCollection() { { "JobDID", "J3H2GZ67DPGRQV8287H" } },
+ new APISettings() { DevKey = "DevKey" });
+ var restReq = new Mock();
+ var response = new RestResponse();
+ response.ResponseUri = new Uri("http://www.careerbuilder.com/jobseeker/applyonline/applybegin.aspx?JobDID=J3H2GZ67DPGRQV8287H&Job_DID=J3H2GZ67DPGRQV8287H&_ga=1.29579389.319760682.1459515366&IPath=CJR_AB");
+ restReq.Setup(x => x.Execute(It.IsAny())).Returns(response);
+ request.Client = restReq.Object;
+
+ Assert.AreEqual("http://www.careerbuilder.com/jobseeker/applyonline/applybegin.aspx?JobDID=J3H2GZ67DPGRQV8287H&Job_DID=J3H2GZ67DPGRQV8287H&_ga=1.29579389.319760682.1459515366&IPath=CJR_AB", request.Retrieve());
+ }
+ }
+}
diff --git a/CBApi.Tests/CBApi/framework/Requests/AuthTokenRequestTest.cs b/CBApi.Tests/CBApi/framework/Requests/AuthTokenRequestTest.cs
new file mode 100644
index 0000000..43e2f3c
--- /dev/null
+++ b/CBApi.Tests/CBApi/framework/Requests/AuthTokenRequestTest.cs
@@ -0,0 +1,137 @@
+using CBApi.Models;
+using NUnit.Framework;
+using Moq;
+using RestSharp;
+using System;
+using Tests.CBApi.models.requests;
+
+namespace Tests.CBApi.framework.requests {
+ [TestFixture]
+ public class AuthTokenRequestTest {
+ [Test]
+ public void Constructor_SetsClientID() {
+ var request = new AuthTokenRequestStub("ClientID", "ClientSecret", "Code","redirectURI", "DevKey", "api.careerbuilder.com", "", "");
+ Assert.AreEqual("ClientID", request.ClientId);
+ }
+
+ [Test]
+ public void Constructor_SetsClientSecret() {
+ var request = new AuthTokenRequestStub("ClientID", "ClientSecret", "Code", "redirectURI", "DevKey", "api.careerbuilder.com", "", "");
+ Assert.AreEqual("ClientSecret", request.ClientSecret);
+ }
+
+ [Test]
+ public void Constructor_SetsCode() {
+ var request = new AuthTokenRequestStub("ClientID", "ClientSecret", "Code", "redirectURI", "DevKey", "api.careerbuilder.com", "", "");
+ Assert.AreEqual("Code", request.Code);
+ }
+
+ [Test]
+ public void Constructor_RedirectURI() {
+ var request = new AuthTokenRequestStub("ClientID", "ClientSecret", "Code", "redirectURI", "DevKey", "api.careerbuilder.com", "", "");
+ Assert.AreEqual("redirectURI", request.RedirectUri);
+ }
+
+ [Test]
+ public void Constructor_ThrowsException_WhenPassedNullOrEmptyClientID() {
+ try {
+ var request = new AuthTokenRequestStub("", "ClientSecret", "Code", "redirectURI", "DevKey", "api.careerbuilder.com", "", "");
+ Assert.Fail("Should have thrown exception");
+ } catch (ArgumentNullException ex) {
+ Assert.IsInstanceOf(ex);
+ }
+
+ try {
+ var request = new AuthTokenRequestStub(null, "ClientSecret", "Code", "redirectURI", "DevKey", "api.careerbuilder.com", "", "");
+ Assert.Fail("Should have thrown exception");
+ } catch (ArgumentNullException ex) {
+ Assert.IsInstanceOf(ex);
+ }
+ }
+
+ [Test]
+ public void Constructor_ThrowsException_WhenPassedNullOrEmptyClientSecret() {
+ try {
+ var request = new AuthTokenRequestStub("ClientID", "", "Code", "redirectURI", "DevKey", "api.careerbuilder.com", "", "");
+ Assert.Fail("Should have thrown exception");
+ } catch (ArgumentNullException ex) {
+ Assert.IsInstanceOf(ex);
+ }
+
+ try {
+ var request = new AuthTokenRequestStub("ClientID", null, "Code", "redirectURI", "DevKey", "api.careerbuilder.com", "", "");
+ Assert.Fail("Should have thrown exception");
+ } catch (ArgumentNullException ex) {
+ Assert.IsInstanceOf(ex);
+ }
+ }
+
+ [Test]
+ public void Constructor_ThrowsException_WhenPassedNullOrEmptyCode() {
+ try {
+ var request = new AuthTokenRequestStub("ClientID", "asdas", "", "redirectURI", "DevKey", "api.careerbuilder.com", "", "");
+ Assert.Fail("Should have thrown exception");
+ } catch (ArgumentNullException ex) {
+ Assert.IsInstanceOf(ex);
+ }
+
+ try {
+ var request = new AuthTokenRequestStub("ClientID", "asdas", null, "redirectURI", "DevKey", "api.careerbuilder.com", "", "");
+ Assert.Fail("Should have thrown exception");
+ } catch (ArgumentNullException ex) {
+ Assert.IsInstanceOf(ex);
+ }
+ }
+
+ [Test]
+ public void Constructor_ThrowsException_WhenPassedNullOrEmptyRedirectUri() {
+ try {
+ var request = new AuthTokenRequestStub("ClientID", "asdas", "asdfasd", "", "DevKey", "api.careerbuilder.com", "", "");
+ Assert.Fail("Should have thrown exception");
+ } catch (ArgumentNullException ex) {
+ Assert.IsInstanceOf(ex);
+ }
+
+ try {
+ var request = new AuthTokenRequestStub("ClientID", "asdas", "asdfasd", null, "DevKey", "api.careerbuilder.com", "", "");
+ Assert.Fail("Should have thrown exception");
+ } catch (ArgumentNullException ex) {
+ Assert.IsInstanceOf(ex);
+ }
+ }
+
+ [Test]
+ public void GetRequestURL_BuildsCorrectEndpointAddress() {
+ var request = new AuthTokenRequestStub("ClientID", "ClientSecret", "Code", "redirectURI", "DevKey", "api.careerbuilder.com", "", "");
+ Assert.AreEqual("https://api.careerbuilder.com/auth/token", request.RequestURL);
+ }
+
+ [Test]
+ public void Retrieve_PerformsCorrectRequest() {
+ //Setup
+ var request = new AuthTokenRequestStub("ClientID", "ClientSecret", "Code", "redirectURI", "DevKey", "api.careerbuilder.com", "", "");
+
+ //Mock crap
+ var response = new RestResponse { Data = new AccessToken() };
+
+ var restReq = new Mock();
+ restReq.Setup(x => x.AddParameter("DeveloperKey", "DevKey"));
+ restReq.Setup(x => x.AddParameter("client_id", "ClientID"));
+ restReq.Setup(x => x.AddParameter("client_secret", "ClientSecret"));
+ restReq.Setup(x => x.AddParameter("redirect_uri", "redirectURI"));
+ restReq.Setup(x => x.AddParameter("code", "Code"));
+
+ var restClient = new Mock();
+ restClient.SetupSet(x => x.BaseUrl = "https://api.careerbuilder.com/auth/token");
+ restClient.Setup(x => x.Execute(It.IsAny())).Returns(response);
+
+ request.Request = restReq.Object;
+ request.Client = restClient.Object;
+
+ //Assert
+ AccessToken resp = request.GetAccessToken();
+ restReq.VerifyAll();
+ restClient.VerifyAll();
+ }
+ }
+}
\ No newline at end of file
diff --git a/CBApi.Tests/CBApi/framework/Requests/BlankAppStub.cs b/CBApi.Tests/CBApi/framework/Requests/BlankAppStub.cs
new file mode 100644
index 0000000..37bbc02
--- /dev/null
+++ b/CBApi.Tests/CBApi/framework/Requests/BlankAppStub.cs
@@ -0,0 +1,48 @@
+using CBApi;
+using CBApi.Framework.Requests;
+using RestSharp;
+using Tests.CBApi.models.service;
+
+namespace Tests.CBApi.framework.requests {
+ internal class BlankAppStub : BlankApplicationRequest {
+ public BlankAppStub(string jobDID, string key, string domain, string cobrand, string siteid)
+ : base(jobDID, new APISettings() { DevKey = key, CobrandCode = cobrand, SiteId = siteid, TargetSite = new TargetSiteMock(domain) }) {
+ }
+
+ public BlankAppStub(string jobDID, string key, string cobrand, string siteid, TargetSiteMock site)
+ : base(jobDID, new APISettings() { DevKey = key, CobrandCode = cobrand, SiteId = siteid, TargetSite = site }) {
+ }
+
+
+
+ public string JobDID {
+ get { return JobDid; }
+ }
+
+ public string DevKey {
+ get { return _Settings.DevKey; }
+ }
+
+ public string Domain {
+ get { return _Settings.TargetSite.Domain; }
+ }
+
+ public string RequestURL {
+ get { return base.GetRequestURL(); }
+ }
+
+ public IRestClient Client {
+ get { return _client; }
+ set { _client = value; }
+ }
+
+ public IRestRequest Request {
+ get { return _request; }
+ set { _request = value; }
+ }
+
+ protected override void CheckForErrors(IRestResponse response) {
+
+ }
+ }
+}
diff --git a/CBApi.Tests/CBApi/framework/Requests/BlankApplicationTest.cs b/CBApi.Tests/CBApi/framework/Requests/BlankApplicationTest.cs
new file mode 100644
index 0000000..e915569
--- /dev/null
+++ b/CBApi.Tests/CBApi/framework/Requests/BlankApplicationTest.cs
@@ -0,0 +1,105 @@
+using CBApi;
+using CBApi.Framework.Requests;
+using CBApi.Models;
+using NUnit.Framework;
+using Moq;
+using RestSharp;
+using System;
+using Tests.CBApi.models.requests;
+using Tests.CBApi.models.service;
+
+namespace Tests.CBApi.framework.requests
+{
+ [TestFixture]
+ public class BlankApplicationTest
+ {
+ [Test]
+ public void Constructor_SetsJobDID()
+ {
+ var request = new BlankAppStub("JXXXXXXXXXXXXXXXXXX", "DevKey", "api.careerbuilder.com", "", "");
+ Assert.AreEqual("JXXXXXXXXXXXXXXXXXX", request.JobDID);
+ }
+
+ [Test]
+ public void Constructor_ThrowsException_WhenPassedNullOrEmpty()
+ {
+ try
+ {
+ var request = new BlankAppStub(null, "DevKey", "api.careerbuilder.com", "", "");
+ Assert.Fail("Should have thrown exception");
+ }
+ catch (ArgumentNullException ex)
+ {
+ Assert.IsInstanceOf(ex);
+ }
+
+ try
+ {
+ var request = new BlankAppStub("", "DevKey", "api.careerbuilder.com", "", "");
+ Assert.Fail("Should have thrown exception");
+ }
+ catch (ArgumentNullException ex)
+ {
+ Assert.IsInstanceOf(ex);
+ }
+ }
+
+ [Test]
+ public void Constructor_ThrowsException_WhenPassedBadJobDID()
+ {
+ try
+ {
+ var request = new BlankAppStub("UXXXXXXXXXXXXXXXXXXX", "DevKey", "api.careerbuilder.com", "", "");
+ Assert.Fail("Should have thrown exception");
+ }
+ catch (ArgumentException ex)
+ {
+ Assert.IsInstanceOf(ex);
+ }
+
+ try
+ {
+ var request = new BlankAppStub("JXXXXXXXXXXX", "DevKey", "api.careerbuilder.com", "", "");
+ Assert.Fail("Should have thrown exception");
+ }
+ catch (ArgumentException ex)
+ {
+ Assert.IsInstanceOf(ex);
+ }
+ }
+
+ [Test]
+ public void GetRequestURL_BuildsCorrectEndpointAddress()
+ {
+ var request = new BlankAppStub("JXXXXXXXXXXXXXXXXXX", "DevKey", "api.careerbuilder.com", "", "");
+ Assert.AreEqual("https://api.careerbuilder.com/v1/application/blank", request.RequestURL);
+ }
+
+ [Test]
+ public void Retrieve_PerformsCorrectRequest()
+ {
+ //Setup
+ var request = new BlankAppStub("JXXXXXXXXXXXXXXXXXX", "DevKey", "api.careerbuilder.com", "", "");
+
+ //Mock crap
+ var response = new RestResponse {Data = new BlankApplication()};
+
+ var restReq = new Mock();
+ restReq.Setup(x => x.AddParameter("DeveloperKey", "DevKey"));
+ restReq.Setup(x => x.AddParameter("JobDID", "JXXXXXXXXXXXXXXXXXX"));
+ restReq.SetupSet(x => x.RootElement = "BlankApplication");
+
+ var restClient = new Mock();
+ restClient.SetupSet(x => x.BaseUrl = "https://api.careerbuilder.com/v1/application/blank");
+ restClient.Setup(x => x.Execute(It.IsAny())).Returns(response);
+
+ request.Request = restReq.Object;
+ request.Client = restClient.Object;
+
+ //Assert
+ BlankApplication resp = request.Retrieve();
+ restReq.VerifyAll();
+ restClient.VerifyAll();
+ }
+ }
+}
\ No newline at end of file
diff --git a/CBApi.Tests/CBApi/framework/Requests/CategoriesRequestTest.cs b/CBApi.Tests/CBApi/framework/Requests/CategoriesRequestTest.cs
new file mode 100644
index 0000000..6453354
--- /dev/null
+++ b/CBApi.Tests/CBApi/framework/Requests/CategoriesRequestTest.cs
@@ -0,0 +1,86 @@
+using CBApi.Models;
+using CBApi.Models.Service;
+using NUnit.Framework;
+using Moq;
+using RestSharp;
+using System.Collections.Generic;
+using Tests.CBApi.models.requests;
+
+namespace Tests.CBApi.framework.requests
+{
+ [TestFixture]
+ public class CategoriesTest
+ {
+ [Test]
+ public void Constructor_DefaultsToUSCountryCode()
+ {
+ var request = new CategoriesStub("DevKey", "api.careerbuilder.com", "", "");
+ Assert.AreEqual("US", request.CountryCode);
+ }
+
+ [Test]
+ public void GetRequestURL_BuildsCorrectEndpointAddress()
+ {
+ var request = new CategoriesStub("DevKey", "api.careerbuilder.com", "", "");
+ Assert.AreEqual("https://api.careerbuilder.com/v1/categories", request.RequestURL);
+ }
+
+ [Test]
+ public void WhereCountryCode_ReturnsCategoryRequest()
+ {
+ var request = new CategoriesStub("DevKey", "api.careerbuilder.com", "", "");
+ Assert.IsInstanceOf(request.WhereCountryCode(CountryCode.SE));
+ }
+
+ [Test]
+ public void WhereCountryCode_SetsCountryCode()
+ {
+ var request = new CategoriesStub("DevKey", "api.careerbuilder.com", "", "");
+ request.WhereCountryCode(CountryCode.SE);
+ Assert.AreEqual("SE", request.CountryCode);
+ }
+
+ [Test]
+ public void WhereHostSite_ReturnsCategoryRequest()
+ {
+ var request = new CategoriesStub("DevKey", "api.careerbuilder.com", "", "");
+ Assert.IsInstanceOf(request.WhereHostSite(HostSite.EU));
+ }
+
+ [Test]
+ public void WhereHostSite_SetsCountryCode()
+ {
+ var request = new CategoriesStub("DevKey", "api.careerbuilder.com", "", "");
+ request.WhereHostSite(HostSite.EU);
+ Assert.AreEqual("EU", request.CountryCode);
+ }
+
+ [Test]
+ public void ListAll_PerformsCorrectRequest()
+ {
+ //Setup
+ var request = new CategoriesStub("DevKey", "api.careerbuilder.com", "", "");
+
+ //Mock crap
+ var response = new RestResponse> {Data = new List()};
+
+ var restReq = new Mock();
+ restReq.Setup(x => x.AddParameter("DeveloperKey", "DevKey"));
+ restReq.Setup(x => x.AddParameter("CountryCode", "NL"));
+ restReq.SetupSet(x => x.RootElement = "Categories");
+
+ var restClient = new Mock();
+ restClient.SetupSet(x => x.BaseUrl = "https://api.careerbuilder.com/v1/categories");
+ restClient.Setup(x => x.Execute>(It.IsAny())).Returns(response);
+
+ request.Request = restReq.Object;
+ request.Client = restClient.Object;
+
+ //Assert
+ List cats = request.WhereCountryCode(CountryCode.NL).ListAll();
+ Assert.IsTrue(cats.Count == 0);
+ restReq.VerifyAll();
+ restClient.VerifyAll();
+ }
+ }
+}
\ No newline at end of file
diff --git a/CBApi.Tests/CBApi/framework/Requests/EducationCodesRequestTest.cs b/CBApi.Tests/CBApi/framework/Requests/EducationCodesRequestTest.cs
new file mode 100644
index 0000000..c2cdb4e
--- /dev/null
+++ b/CBApi.Tests/CBApi/framework/Requests/EducationCodesRequestTest.cs
@@ -0,0 +1,76 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using CBApi;
+using CBApi.Framework.Requests;
+using CBApi.Models;
+using CBApi.Models.Service;
+using NUnit.Framework;
+using Moq;
+using RestSharp;
+using Tests.CBApi.models.requests;
+using Tests.CBApi.models.service;
+
+namespace Tests.CBApi.framework.requests
+{
+ [TestFixture]
+ public class EducationCodesRequestTest
+ {
+ [Test]
+ public void Constructor_DefaultsToUSCountryCode()
+ {
+ EducationCodesRequestStub target = new EducationCodesRequestStub("DevKey", "api.careerbuilder.com", "", "");
+ Assert.AreEqual("US", target.CountryCode);
+ }
+
+ [Test]
+ public void GetRequestURL_BuildsCorrectEndpointAddress()
+ {
+ EducationCodesRequestStub target = new EducationCodesRequestStub("DevKey", "api.careerbuilder.com", "", "");
+ Assert.AreEqual("https://api.careerbuilder.com/v1/educationcodes", target.RequestURL);
+ }
+
+ [Test]
+ public void WhereCountryCode_IsFluent()
+ {
+ IEducationCodesRequest target = new EducationCodesRequestStub("DevKey", "api.careerbuilder.com", "", "");
+
+ IEducationCodesRequest actual = target.WhereCountryCode(CountryCode.SE);
+
+ Assert.AreEqual(actual, target);
+ }
+
+ [Test]
+ public void WhereCountryCode_SetsCountryCode()
+ {
+ EducationCodesRequestStub request = new EducationCodesRequestStub("DevKey", "api.careerbuilder.com", "", "");
+
+ request.WhereCountryCode(CountryCode.SE);
+
+ Assert.AreEqual("SE", request.CountryCode);
+ }
+
+ [Test]
+ public void ListAll_PerformsCorrectRequest()
+ {
+ EducationCodesRequestStub target = new EducationCodesRequestStub("DevKey", "api.careerbuilder.com", "", "");
+ RestResponse> response = new RestResponse> { Data = new List() };
+ Mock request = new Mock();
+ request.Setup(x => x.AddParameter("DeveloperKey", "DevKey"));
+ request.Setup(x => x.AddParameter("CountryCode", "NL"));
+ request.SetupSet(x => x.RootElement = "EducationCodes");
+ Mock restClient = new Mock();
+ restClient.SetupSet(x => x.BaseUrl = "https://api.careerbuilder.com/v1/educationcodes");
+ restClient.Setup(x => x.Execute>(It.IsAny())).Returns(response);
+ target.Request = request.Object;
+ target.Client = restClient.Object;
+
+ List educationCodes = target.WhereCountryCode(CountryCode.NL).ListAll();
+
+ Assert.IsTrue(educationCodes.Count == 0);
+ request.VerifyAll();
+ restClient.VerifyAll();
+ }
+ }
+}
diff --git a/CBApi.Tests/CBApi/framework/Requests/EmployeeTypesRequestTest.cs b/CBApi.Tests/CBApi/framework/Requests/EmployeeTypesRequestTest.cs
new file mode 100644
index 0000000..d507446
--- /dev/null
+++ b/CBApi.Tests/CBApi/framework/Requests/EmployeeTypesRequestTest.cs
@@ -0,0 +1,79 @@
+using CBApi.Models;
+using CBApi.Models.Service;
+using NUnit.Framework;
+using Moq;
+using RestSharp;
+using System.Collections.Generic;
+using Tests.CBApi.models.requests;
+
+namespace Tests.CBApi.framework.requests
+{
+ [TestFixture]
+ public class EmployeeTypesTest
+ {
+ [Test]
+ public void GetRequestURL_BuildsCorrectEndpointAddress()
+ {
+ var request = new EmployeeTypesStub("DevKey", "api.careerbuilder.com");
+ Assert.AreEqual("https://api.careerbuilder.com/v1/employeetypes", request.RequestURL);
+ }
+
+ [Test]
+ public void WhereCountryCode_ReturnsCategoryRequest()
+ {
+ var request = new EmployeeTypesStub("DevKey", "api.careerbuilder.com");
+ Assert.IsInstanceOf(request.WhereCountryCode(CountryCode.SE));
+ }
+
+ [Test]
+ public void WhereCountryCode_SetsCountryCode()
+ {
+ var request = new EmployeeTypesStub("DevKey", "api.careerbuilder.com");
+ request.WhereCountryCode(CountryCode.SE);
+ Assert.AreEqual("SE", request.CountryCode);
+ }
+
+ [Test]
+ public void WhereHostSite_ReturnsCategoryRequest()
+ {
+ var request = new EmployeeTypesStub("DevKey", "api.careerbuilder.com");
+ Assert.IsInstanceOf(request.WhereHostSite(HostSite.EU));
+ }
+
+ [Test]
+ public void WhereHostSite_SetsCountryCode()
+ {
+ var request = new EmployeeTypesStub("DevKey", "api.careerbuilder.com");
+ request.WhereHostSite(HostSite.EU);
+ Assert.AreEqual("EU", request.CountryCode);
+ }
+
+ [Test]
+ public void ListAll_PerformsCorrectRequest()
+ {
+ //Setup
+ var request = new EmployeeTypesStub("DevKey", "api.careerbuilder.com");
+
+ //Mock crap
+ var response = new RestResponse> {Data = new List()};
+
+ var restReq = new Mock();
+ restReq.Setup(x => x.AddParameter("DeveloperKey", "DevKey"));
+ restReq.Setup(x => x.AddParameter("CountryCode", "NL"));
+ restReq.SetupSet(x => x.RootElement = "EmployeeTypes");
+
+ var restClient = new Mock();
+ restClient.SetupSet(x => x.BaseUrl = "https://api.careerbuilder.com/v1/employeetypes");
+ restClient.Setup(x => x.Execute>(It.IsAny())).Returns(response);
+
+ request.Request = restReq.Object;
+ request.Client = restClient.Object;
+
+ //Assert
+ List cats = request.WhereCountryCode(CountryCode.NL).ListAll();
+ Assert.IsTrue(cats.Count == 0);
+ restReq.VerifyAll();
+ restClient.VerifyAll();
+ }
+ }
+}
\ No newline at end of file
diff --git a/CBApi.Tests/CBApi/framework/Requests/GetRequestTest.cs b/CBApi.Tests/CBApi/framework/Requests/GetRequestTest.cs
new file mode 100644
index 0000000..a21d612
--- /dev/null
+++ b/CBApi.Tests/CBApi/framework/Requests/GetRequestTest.cs
@@ -0,0 +1,165 @@
+using CBApi;
+using NUnit.Framework;
+using Moq;
+using RestSharp;
+using System;
+using Tests.CBApi.models.requests;
+using Tests.CBApi.models.service;
+
+namespace Tests.CBApi.framework.requests {
+ [TestFixture]
+ public class GetRequestTest {
+ private APISettings _Settings = new APISettings(){DevKey="DevKey", CobrandCode="this is a cobrand",SiteId="this is a siteid",TimeoutMS=12345};
+ private bool _HasEventFired = false;
+
+ [Test]
+ public void Constructor_ThrowsException_OnEmptyDevKey() {
+ try {
+ var request = new GetRequestStub("", "api.careerbuilder.com", "", "");
+ Assert.Fail();
+ } catch (ArgumentNullException ex) {
+ Assert.IsInstanceOf(ex);
+ }
+ }
+
+ [Test]
+ public void Constructor_ThrowsException_OnNullDevKey() {
+ try {
+ var request = new GetRequestStub(null, "api.careerbuilder.com", "", "");
+ Assert.Fail();
+ } catch (ArgumentNullException ex) {
+ Assert.IsInstanceOf(ex);
+ }
+ }
+
+ [Test]
+ public void Constructor_ThrowsException_OnEmptyDomain() {
+ try {
+ var request = new GetRequestStub("DevKey", "", "", "");
+ Assert.Fail();
+ } catch (ArgumentNullException ex) {
+ Assert.IsInstanceOf(ex);
+ }
+ }
+
+ [Test]
+ public void Constructor_ThrowsException_OnNullDomain() {
+ try {
+ var request = new GetRequestStub("DevKey", null, "", "");
+ Assert.Fail();
+ } catch (ArgumentNullException ex) {
+ Assert.IsInstanceOf(ex);
+ }
+ }
+
+ [Test]
+ public void Constructor_SetsDevKey() {
+ var request = new GetRequestStub("DevKey", "api.careerbuilder.com", "", "");
+ Assert.AreEqual("DevKey", request.DevKey);
+ }
+
+ [Test]
+ public void Constructor_SetsDomain() {
+ var request = new GetRequestStub("DevKey", "api.careerbuilder.com", "", "");
+ Assert.AreEqual("api.careerbuilder.com", request.Domain);
+ }
+
+ [Test]
+ public void Constructor_SetsCobrand() {
+ var request = new GetRequestStub("DevKey", "api.careerbuilder.com", "cobrandcode", "");
+ Assert.AreEqual("cobrandcode", request.CobrandCode);
+ }
+
+ [Test]
+ public void Constructor_SetsSiteID() {
+ var request = new GetRequestStub("DevKey", "api.careerbuilder.com", "", "SiteID");
+ Assert.AreEqual("SiteID", request.SiteID);
+ }
+
+ [Test]
+ public void BaseURL_IsNotSecure_WhenTargetSiteIsntSecure() {
+ //Setup
+ var newSite = new TargetSiteMock("127.0.0.1") { SetHost = "www.google.com", SetSecure=false };
+ var settings = new APISettings() { DevKey = "DevKey", CobrandCode = "this is a cobrand", SiteId = "this is a siteid", TimeoutMS = 12345, TargetSite = newSite };
+ var request = new GetRequestStub(settings);
+ Assert.AreEqual("http://127.0.0.1/Exammple", request.GetRequestURL);
+ }
+
+ [Test]
+ public void BaseURL_IsSecure_WhenTargetSiteIsSecure() {
+ //Setup
+ var newSite = new TargetSiteMock("127.0.0.1") { SetHost = "www.google.com", SetSecure = true };
+ var settings = new APISettings() { DevKey = "DevKey", CobrandCode = "this is a cobrand", SiteId = "this is a siteid", TimeoutMS = 12345, TargetSite = newSite };
+ var request = new GetRequestStub(settings);
+ Assert.AreEqual("https://127.0.0.1/Exammple", request.GetRequestURL);
+ }
+
+ [Test]
+ public void BeforeRequest_SetsDevKey_AndDomain_AndCobrand_AndSiteID_AndTimeout() {
+ //Setup
+ var request = new GetRequestStub(_Settings);
+
+ //Mock crap
+ var restReq = new Mock();
+ restReq.Setup(x => x.AddParameter("DeveloperKey", "DevKey"));
+ restReq.Setup(x => x.AddParameter("CoBrand", "this is a cobrand"));
+ restReq.Setup(x => x.AddParameter("SiteID", "this is a siteid"));
+ restReq.SetupSet(x => x.Timeout = 12345);
+
+ var restClient = new Mock();
+ request.Request = restReq.Object;
+ request.Client = restClient.Object;
+
+ //Assert
+ request.RunBeforeGet();
+ restReq.VerifyAll();
+ }
+
+ [Test]
+ public void BeforeRequest_AddsHostParameter() {
+ //Setup
+ var newSite = new TargetSiteMock("127.0.0.1") { SetHost = "www.google.com" };
+ var settings = new APISettings() { DevKey = "DevKey", CobrandCode = "this is a cobrand", SiteId = "this is a siteid", TimeoutMS = 12345, TargetSite = newSite };
+ var request = new GetRequestStub(settings);
+
+ //Mock crap
+ var restReq = new Mock();
+ restReq.Setup(x => x.AddHeader("Host", "www.google.com"));
+
+ var restClient = new Mock();
+ request.Request = restReq.Object;
+ request.Client = restClient.Object;
+
+ //Assert
+ request.RunBeforeGet();
+ restReq.VerifyAll();
+ }
+
+ [Test]
+ public void BeforeRequest_RaisesBeforeRequestEvent() {
+ //Setup
+ var newSite = new TargetSiteMock("127.0.0.1") { SetHost = "www.google.com" };
+ var settings = new APISettings() { DevKey = "DevKey", CobrandCode = "this is a cobrand", SiteId = "this is a siteid", TimeoutMS = 12345, TargetSite = newSite };
+ var request = new GetRequestStub(settings);
+
+ //Mock crap
+ var restReq = new Mock();
+ var restClient = new Mock();
+ restClient.Setup(x => x.BaseUrl).Returns("https://127.0.0.1/Exammple");
+ request.Request = restReq.Object;
+ request.Client = restClient.Object;
+
+ //Assert
+ request.OnBeforeRequest += (HandleBeforeRequest);
+ request.RunBeforeGet();
+ Assert.AreEqual(true, _HasEventFired);
+ request.OnBeforeRequest -= (HandleBeforeRequest);
+ }
+
+ private void HandleBeforeRequest(IRequestEventData data) {
+ _HasEventFired = true;
+ Assert.AreEqual("https://127.0.0.1/Exammple", data.BaseURL);
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/CBApi.Tests/CBApi/framework/Requests/JobRecommendationsRequestTest.cs b/CBApi.Tests/CBApi/framework/Requests/JobRecommendationsRequestTest.cs
new file mode 100644
index 0000000..d68778a
--- /dev/null
+++ b/CBApi.Tests/CBApi/framework/Requests/JobRecommendationsRequestTest.cs
@@ -0,0 +1,74 @@
+using System;
+using System.Collections.Generic;
+using CBApi.Models;
+using NUnit.Framework;
+using Moq;
+using RestSharp;
+using Tests.CBApi.models.requests;
+
+namespace Tests.CBApi.framework.requests {
+ [TestFixture]
+ public class JobRecommendationsRequestTest {
+ [Test]
+ public void Constructor_SetsExternalID() {
+ var request = new JobRecRequestStub("J1234567890123456789", "DevKey", "api.careerbuilder.com", "", "");
+ Assert.AreEqual("J1234567890123456789", request.JobDid);
+ }
+
+ [Test]
+ public void Constructor_ThrowsException_WhenPassedNullOrEmpty() {
+ try {
+ var request = new JobRecRequestStub(null, "DevKey", "api.careerbuilder.com", "", "");
+ Assert.Fail("Should have thrown exception");
+ } catch (ArgumentNullException ex) {
+ Assert.IsInstanceOf(ex);
+ }
+
+ try {
+ var request2 = new JobRecRequestStub("", "DevKey", "api.careerbuilder.com", "", "");
+ Assert.Fail("Should have thrown exception");
+ } catch (ArgumentNullException ex) {
+ Assert.IsInstanceOf(ex);
+ }
+
+ try {
+ var request3 = new JobRecRequestStub("NotAValidJobDid", "DevKey", "api.careerbuilder.com", "", "");
+ Assert.Fail("Should have thrown exception");
+ } catch (ArgumentException ex) {
+ Assert.IsInstanceOf(ex);
+ }
+ }
+
+ [Test]
+ public void GetRequestURL_BuildsCorrectEndpointAddress() {
+ var request = new JobRecRequestStub("J1234567890123456789", "DevKey", "api.careerbuilder.com", "", "");
+ Assert.AreEqual("https://api.careerbuilder.com/v2/recommendations/forjob", request.RequestURL);
+ }
+
+ [Test]
+ public void GetRecommendations_PerformsCorrectRequest() {
+ //Setup
+ var request = new JobRecRequestStub("J1234567890123456789", "DevKey", "api.careerbuilder.com", "", "");
+
+ //Mock crap
+ var response = new RestResponse> { Data = new List() };
+
+ var restReq = new Mock();
+ restReq.Setup(x => x.AddParameter("DeveloperKey", "DevKey"));
+ restReq.Setup(x => x.AddParameter("JobDID", "J1234567890123456789"));
+ restReq.SetupSet(x => x.RootElement = "RecommendJobResults");
+
+ var restClient = new Mock();
+ restClient.SetupSet(x => x.BaseUrl = "https://api.careerbuilder.com/v2/recommendations/forjob");
+ restClient.Setup(x => x.Execute>(It.IsAny())).Returns(response);
+
+ request.Request = restReq.Object;
+ request.Client = restClient.Object;
+
+ //Assert
+ List resp = request.GetRecommendations();
+ restReq.VerifyAll();
+ restClient.VerifyAll();
+ }
+ }
+}
diff --git a/CBApi.Tests/CBApi/framework/Requests/JobRecommendationsWithUserPreferencesRequestTest.cs b/CBApi.Tests/CBApi/framework/Requests/JobRecommendationsWithUserPreferencesRequestTest.cs
new file mode 100644
index 0000000..6757c8b
--- /dev/null
+++ b/CBApi.Tests/CBApi/framework/Requests/JobRecommendationsWithUserPreferencesRequestTest.cs
@@ -0,0 +1,104 @@
+using System;
+using System.Collections.Generic;
+using CBApi.Models;
+using NUnit.Framework;
+using Moq;
+using RestSharp;
+using Tests.CBApi.models.requests;
+
+namespace Tests.CBApi.framework.requests {
+ [TestFixture]
+ public class JobRecommendationsWithUserPreferencesRequestTest {
+ [Test]
+ public void Constructor_SetsExternalID() {
+ var request = new JobRecWithUserPrefRequestStub("J1234567890123456789", "U1234567890123456789",
+ "DevKey", "api.careerbuilder.com", "", "");
+ Assert.AreEqual("J1234567890123456789", request.JobDid);
+ Assert.AreEqual("U1234567890123456789", request.UserDid);
+ }
+
+ [Test]
+ public void Constructor_ThrowsException_WhenPassedNullOrEmpty_JobDid() {
+ try {
+ var request = new JobRecWithUserPrefRequestStub(null, null, "DevKey", "api.careerbuilder.com", "", "");
+ Assert.Fail("Should have thrown exception");
+ } catch (ArgumentNullException ex) {
+ Assert.IsInstanceOf(ex);
+ }
+
+ try {
+ var request2 = new JobRecWithUserPrefRequestStub("", null, "DevKey", "api.careerbuilder.com", "", "");
+ Assert.Fail("Should have thrown exception");
+ } catch (ArgumentNullException ex) {
+ Assert.IsInstanceOf(ex);
+ }
+
+ try {
+ var request3 = new JobRecWithUserPrefRequestStub("NotAValidJobDid", null, "DevKey", "api.careerbuilder.com", "", "");
+ Assert.Fail("Should have thrown exception");
+ } catch (ArgumentException ex) {
+ Assert.IsInstanceOf(ex);
+ }
+ }
+
+ [Test]
+ public void Constructor_ThrowsException_WhenPassedNullOrEmpty_UserDid() {
+ try {
+ var request = new JobRecWithUserPrefRequestStub("J1234567890123456789", null, "DevKey", "api.careerbuilder.com", "", "");
+ Assert.Fail("Should have thrown exception");
+ } catch (ArgumentNullException ex) {
+ Assert.IsInstanceOf(ex);
+ }
+
+ try {
+ var request2 = new JobRecWithUserPrefRequestStub("J1234567890123456789", "", "DevKey", "api.careerbuilder.com", "", "");
+ Assert.Fail("Should have thrown exception");
+ } catch (ArgumentNullException ex) {
+ Assert.IsInstanceOf(ex);
+ }
+
+ try {
+ var request3 = new JobRecWithUserPrefRequestStub("J1234567890123456789", "NotAValidUserDid",
+ "DevKey", "api.careerbuilder.com", "", "");
+ Assert.Fail("Should have thrown exception");
+ } catch (ArgumentException ex) {
+ Assert.IsInstanceOf(ex);
+ }
+ }
+
+ [Test]
+ public void GetRequestURL_BuildsCorrectEndpointAddress() {
+ var request = new JobRecWithUserPrefRequestStub("J1234567890123456789", "U1234567890123456789",
+ "DevKey", "api.careerbuilder.com", "", "");
+ Assert.AreEqual("https://api.careerbuilder.com/v1/recommendations/forjobwithuserprefs", request.RequestURL);
+ }
+
+ [Test]
+ public void GetRecommendations_PerformsCorrectRequest() {
+ //Setup
+ var request = new JobRecWithUserPrefRequestStub("J1234567890123456789", "U1234567890123456789",
+ "DevKey", "api.careerbuilder.com", "", "");
+
+ //Mock crap
+ var response = new RestResponse> { Data = new List() };
+
+ var restReq = new Mock();
+ restReq.Setup(x => x.AddParameter("DeveloperKey", "DevKey"));
+ restReq.Setup(x => x.AddParameter("JobDID", "J1234567890123456789"));
+ restReq.Setup(x => x.AddParameter("UserDID", "U1234567890123456789"));
+ restReq.SetupSet(x => x.RootElement = "RecommendJobResults");
+
+ var restClient = new Mock();
+ restClient.SetupSet(x => x.BaseUrl = "https://api.careerbuilder.com/v1/recommendations/forjobwithuserprefs");
+ restClient.Setup(x => x.Execute>(It.IsAny())).Returns(response);
+
+ request.Request = restReq.Object;
+ request.Client = restClient.Object;
+
+ //Assert
+ List resp = request.GetRecommendations();
+ restReq.VerifyAll();
+ restClient.VerifyAll();
+ }
+ }
+}
diff --git a/CBApi.Tests/CBApi/framework/Requests/JobRequestTest.cs b/CBApi.Tests/CBApi/framework/Requests/JobRequestTest.cs
new file mode 100644
index 0000000..5cfbb39
--- /dev/null
+++ b/CBApi.Tests/CBApi/framework/Requests/JobRequestTest.cs
@@ -0,0 +1,127 @@
+using CBApi.Models;
+using NUnit.Framework;
+using Moq;
+using RestSharp;
+using System;
+using Tests.CBApi.models.requests;
+
+namespace Tests.CBApi.framework.requests
+{
+ [TestFixture]
+ public class JobRequestTest
+ {
+ [Test]
+ public void Constructor_ThrowsException_WhenPassedBlankJobDID()
+ {
+ try
+ {
+ var request = new JobRequestStub("", "DevKey", "api.careerbuilder.com", "", "");
+ Assert.Fail();
+ }
+ catch (ArgumentNullException ex)
+ {
+ Assert.IsInstanceOf(ex);
+ }
+ }
+
+ [Test]
+ public void Constructor_ThrowsException_WhenPassedNullJobDID()
+ {
+ try
+ {
+ var request = new JobRequestStub(null, "DevKey", "api.careerbuilder.com", "", "");
+ Assert.Fail();
+ }
+ catch (ArgumentNullException ex)
+ {
+ Assert.IsInstanceOf(ex);
+ }
+ }
+
+ [Test]
+ public void Constructor_ThrowsException_WhenPassedShortJobDID()
+ {
+ try
+ {
+ var request = new JobRequestStub("J12345678910", "DevKey", "api.careerbuilder.com", "", "");
+ Assert.Fail();
+ }
+ catch (ArgumentException ex)
+ {
+ Assert.IsInstanceOf(ex);
+ }
+ }
+
+ [Test]
+ public void Constructor_ThrowsException_WhenPassedLongJobDID()
+ {
+ try
+ {
+ var request = new JobRequestStub("J12345678901234567890123456789", "DevKey", "api.careerbuilder.com", "",
+ "");
+ Assert.Fail();
+ }
+ catch (ArgumentException ex)
+ {
+ Assert.IsInstanceOf(ex);
+ }
+ }
+
+ [Test]
+ public void Constructor_ThrowsException_WhenPassedBadJobDID()
+ {
+ try
+ {
+ var request = new JobRequestStub("W3T1SK6PN85V725Z6Q3", "DevKey", "api.careerbuilder.com", "", "");
+ Assert.Fail();
+ }
+ catch (ArgumentException ex)
+ {
+ Assert.IsInstanceOf(ex);
+ }
+ }
+
+ [Test]
+ public void Constructor_SetsJobDID()
+ {
+ try
+ {
+ var request = new JobRequestStub("J3T1SK6PN85V725Z6Q3", "DevKey", "api.careerbuilder.com", "", "");
+ Assert.AreEqual("J3T1SK6PN85V725Z6Q3", request.JobDID);
+ }
+ catch (Exception)
+ {
+ Assert.Fail();
+ }
+ }
+
+
+ [Test]
+ public void Retrieve_PerformsCorrectRequest()
+ {
+ //Setup
+ var request = new JobRequestStub("J3T1SK6PN85V725Z6Q3", "DevKey", "api.careerbuilder.com", "", "");
+
+ //Mock crap
+ var response = new RestResponse {Data = new Job {JobTitle = "Jeff's crazy job imporieum"}};
+
+ var restReq = new Mock();
+ restReq.Setup(x => x.AddParameter("DeveloperKey", "DevKey"));
+ restReq.Setup(x => x.AddParameter("DID", "J3T1SK6PN85V725Z6Q3"));
+ restReq.SetupSet(x => x.RootElement = "Job");
+
+ var restClient = new Mock();
+ restClient.SetupSet(x => x.BaseUrl = "https://api.careerbuilder.com/v1/job");
+ restClient.Setup(x => x.Execute(It.IsAny())).Returns(response);
+
+ request.Request = restReq.Object;
+ request.Client = restClient.Object;
+
+ //Assert
+ Job myJob = request.Retrieve();
+ Assert.AreSame(response.Data, myJob);
+ restReq.VerifyAll();
+ restClient.VerifyAll();
+ }
+ }
+}
\ No newline at end of file
diff --git a/CBApi.Tests/CBApi/framework/Requests/JobSearchRequestTest.cs b/CBApi.Tests/CBApi/framework/Requests/JobSearchRequestTest.cs
new file mode 100644
index 0000000..a5817f4
--- /dev/null
+++ b/CBApi.Tests/CBApi/framework/Requests/JobSearchRequestTest.cs
@@ -0,0 +1,261 @@
+using CBApi.Models;
+using CBApi.Models.Responses;
+using CBApi.Models.Service;
+using NUnit.Framework;
+using Moq;
+using RestSharp;
+using Tests.CBApi.models.requests;
+
+namespace Tests.CBApi.framework.requests {
+ [TestFixture]
+ public class JobSearchRequestTest {
+
+ [Test]
+ public void Constructor_DoesNotDefaultUSCountryCode() {
+ var request = new JobSearchStub("DevKey", "api.careerbuilder.com", "", "");
+ Assert.AreEqual("", request.CountryCode);
+ }
+
+ [Test]
+ public void GetRequestURL_BuildsCorrectEndpointAddress() {
+ var request = new JobSearchStub("DevKey", "api.careerbuilder.com", "", "");
+ Assert.AreEqual("https://api.careerbuilder.com/v1/jobsearch", request.RequestURL);
+ }
+
+ [Test]
+ public void Search_PerformsCorrectRequest() {
+ //Setup
+ var request = new JobSearchStub("DevKey", "api.careerbuilder.com", "", "");
+
+ //Mock crap
+ var response = new RestResponse { Data = new ResponseJobSearch() };
+
+ var restReq = new Mock();
+ restReq.Setup(x => x.AddParameter("DeveloperKey", "DevKey"));
+ restReq.Setup(x => x.AddParameter("CountryCode", "NL"));
+ restReq.SetupSet(x => x.RootElement = "ResponseJobSearch");
+
+ var restClient = new Mock();
+ restClient.SetupSet(x => x.BaseUrl = "https://api.careerbuilder.com/v1/jobsearch");
+ restClient.Setup(x => x.Execute(It.IsAny())).Returns(response);
+
+ request.Request = restReq.Object;
+ request.Client = restClient.Object;
+
+ //Assert
+ ResponseJobSearch resp = request.WhereCountryCode("NL").Search();
+ restReq.Verify();
+ restClient.VerifyAll();
+ }
+
+ [Test]
+ public void WhereClause_OverridesExistingParam() {
+ //Setup
+ var request = new JobSearchStub("DevKey", "api.careerbuilder.com", "", "");
+
+ //Mock crap
+ var response = new RestResponse { Data = new ResponseJobSearch() };
+
+ var restReq = new Mock();
+ restReq.Setup(x => x.AddParameter("DeveloperKey", "DevKey"));
+ restReq.Setup(x => x.AddParameter("CountryCode", "SE"));
+ restReq.SetupSet(x => x.RootElement = "ResponseJobSearch");
+
+ var restClient = new Mock();
+ restClient.SetupSet(x => x.BaseUrl = "https://api.careerbuilder.com/v1/jobsearch");
+ restClient.Setup(x => x.Execute(It.IsAny())).Returns(response);
+
+ request.Request = restReq.Object;
+ request.Client = restClient.Object;
+
+ //Assert
+ ResponseJobSearch resp = request.WhereCountryCode("NL").Where("CountryCode","SE").Search();
+ restReq.Verify();
+ restClient.VerifyAll();
+ }
+
+ [Test]
+ public void WhereClause_AddsToOutgoingParams() {
+ //Setup
+ var request = new JobSearchStub("DevKey", "api.careerbuilder.com", "", "");
+
+ //Mock crap
+ var response = new RestResponse { Data = new ResponseJobSearch() };
+
+ var restReq = new Mock();
+ restReq.Setup(x => x.AddParameter("DeveloperKey", "DevKey"));
+ restReq.Setup(x => x.AddParameter("silly", "value"));
+ restReq.SetupSet(x => x.RootElement = "ResponseJobSearch");
+
+ var restClient = new Mock();
+ restClient.SetupSet(x => x.BaseUrl = "https://api.careerbuilder.com/v1/jobsearch");
+ restClient.Setup(x => x.Execute(It.IsAny())).Returns(response);
+
+ request.Request = restReq.Object;
+ request.Client = restClient.Object;
+
+ //Assert
+ ResponseJobSearch resp = request.Where("Silly", "value").Search();
+ restReq.Verify();
+ restClient.VerifyAll();
+ }
+
+
+
+ [Test]
+ public void WhereCountryCode_ReturnsCategoryRequest() {
+ var request = new JobSearchStub("DevKey", "api.careerbuilder.com", "", "");
+ Assert.IsInstanceOf(request.WhereCountryCode("SE"));
+ }
+
+ [Test]
+ public void WhereCountryCode_SetsCountryCode() {
+ var request = new JobSearchStub("DevKey", "api.careerbuilder.com", "", "");
+ request.WhereCountryCode("SE");
+ Assert.AreEqual("SE", request.CountryCode);
+ }
+
+ [Test]
+ public void WhereHostSite_ReturnsCategoryRequest() {
+ var request = new JobSearchStub("DevKey", "api.careerbuilder.com", "", "");
+ Assert.IsInstanceOf(request.WhereHostSite("EU"));
+ }
+
+ [Test]
+ public void WhereHostSite_SetsCountryCode() {
+ var request = new JobSearchStub("DevKey", "api.careerbuilder.com", "", "");
+ request.WhereHostSite(HostSite.EU);
+ Assert.AreEqual("EU", request.CountryCode);
+ }
+
+ [Test]
+ public void WhereNotCompanyName_SetsCorrectParameter() {
+ var jobSearch = new JobSearchStub("DevKey", "api.careerbuilder.com", "", "");
+ jobSearch.WhereNotCompanyName("Coca Cola");
+ jobSearch.AddParametersToRequest();
+ var param = jobSearch.Request.Parameters.Find(qs => qs.Name == "excludecompanynames");
+ Assert.IsNotNull(param, "ExcludeCompanyNames should exist.");
+ Assert.AreEqual("Coca Cola", param.Value, "ExcludeCompanyNames value should be 'Coca Cola'");
+ }
+
+ [Test]
+ public void WhereNotCompanyName_SetsCorrectParameter_Multiple() {
+ var jobSearch = new JobSearchStub("DevKey", "api.careerbuilder.com", "", "");
+ jobSearch.WhereNotCompanyName("Coca Cola", "Intel Rabbit Co");
+ jobSearch.AddParametersToRequest();
+ var param = jobSearch.Request.Parameters.Find(qs => qs.Name == "excludecompanynames");
+ Assert.IsNotNull(param, "ExcludeCompanyNames should exist.");
+ Assert.AreEqual("Coca Cola,Intel Rabbit Co", param.Value, "ExcludeCompanyNames value should be 'Coca Cola,Intel Rabbit Co'");
+ }
+
+ [Test]
+ public void WhereNotCompanyName_SetsCorrectParameter_Empty() {
+ var jobSearch = new JobSearchStub("DevKey", "api.careerbuilder.com", "", "");
+ jobSearch.WhereNotCompanyName(" ");
+ jobSearch.AddParametersToRequest();
+ var param = jobSearch.Request.Parameters.Find(qs => qs.Name == "excludecompanynames");
+ Assert.IsNull(param, "ExcludeCompanyNames should not exist.");
+ }
+
+ [Test]
+ public void WhereNotJobTitle_SetsCorrectParameter() {
+ var jobSearch = new JobSearchStub("DevKey", "api.careerbuilder.com", "", "");
+ jobSearch.WhereNotJobTitle("Coca Cola");
+ jobSearch.AddParametersToRequest();
+ var param = jobSearch.Request.Parameters.Find(qs => qs.Name == "excludejobtitles");
+ Assert.IsNotNull(param, "ExcludeJobTitles should exist.");
+ Assert.AreEqual("Coca Cola", param.Value, "ExcludeJobTitles value should be 'Coca Cola'");
+ }
+
+ [Test]
+ public void WhereNotJobTitle_SetsCorrectParameter_Multiple() {
+ var jobSearch = new JobSearchStub("DevKey", "api.careerbuilder.com", "", "");
+ jobSearch.WhereNotJobTitle("Coca Cola", "Intel Rabbit Co");
+ jobSearch.AddParametersToRequest();
+ var param = jobSearch.Request.Parameters.Find(qs => qs.Name == "excludejobtitles");
+ Assert.IsNotNull(param, "ExcludeJobTitles should exist.");
+ Assert.AreEqual("Coca Cola,Intel Rabbit Co", param.Value, "ExcludeJobTitles value should be 'Coca Cola,Intel Rabbit Co'");
+ }
+
+ [Test]
+ public void WhereNotJobTitle_SetsCorrectParameter_Empty() {
+ var jobSearch = new JobSearchStub("DevKey", "api.careerbuilder.com", "", "");
+ jobSearch.WhereNotJobTitle(" ");
+ jobSearch.AddParametersToRequest();
+ var param = jobSearch.Request.Parameters.Find(qs => qs.Name == "excludejobtitles");
+ Assert.IsNull(param, "ExcludeJobTitles should not exist.");
+ }
+
+ [Test]
+ public void WhereNotKeywords_SetsCorrectParameter() {
+ var jobSearch = new JobSearchStub("DevKey", "api.careerbuilder.com", "", "");
+ jobSearch.WhereNotKeywords("Coca Cola");
+ jobSearch.AddParametersToRequest();
+ var param = jobSearch.Request.Parameters.Find(qs => qs.Name == "excludekeywords");
+ Assert.IsNotNull(param, "ExcludeKeywords should exist.");
+ Assert.AreEqual("Coca Cola", param.Value, "ExcludeKeywords value should be 'Coca Cola'");
+ }
+
+ [Test]
+ public void WhereNotKeywords_SetsCorrectParameter_Multiple() {
+ var jobSearch = new JobSearchStub("DevKey", "api.careerbuilder.com", "", "");
+ jobSearch.WhereNotKeywords("Coca Cola", "Intel Rabbit Co");
+ jobSearch.AddParametersToRequest();
+ var param = jobSearch.Request.Parameters.Find(qs => qs.Name == "excludekeywords");
+ Assert.IsNotNull(param, "ExcludeKeywords should exist.");
+ Assert.AreEqual("Coca Cola,Intel Rabbit Co", param.Value, "ExcludeKeywords value should be 'Coca Cola,Intel Rabbit Co'");
+ }
+
+ [Test]
+ public void WhereNotKeywords_SetsCorrectParameter_Empty() {
+ var jobSearch = new JobSearchStub("DevKey", "api.careerbuilder.com", "", "");
+ jobSearch.WhereNotKeywords(" ");
+ jobSearch.AddParametersToRequest();
+ var param = jobSearch.Request.Parameters.Find(qs => qs.Name == "excludekeywords");
+ Assert.IsNull(param, "ExcludeKeywords should not exist.");
+ }
+
+ [Test]
+ public void WhereGroupValue_SetsCorrectParameters() {
+ var jobSearch = new JobSearchStub("DevKey", "api.careerbuilder.com", "", "");
+ jobSearch.WhereGroupingValue("grouping value");
+ jobSearch.AddParametersToRequest();
+ var param_grouping_value = jobSearch.Request.Parameters.Find(qs => qs.Name == "groupingvalue").Value;
+ var param_advanced_grouping = jobSearch.Request.Parameters.Find(qs => qs.Name == "advancedgroupingmode").Value;
+ var param_enable_company_job_title_collapse = jobSearch.Request.Parameters.Find(qs => qs.Name == "enablecompanyjobtitlecollapse").Value;
+ Assert.AreEqual("grouping value", param_grouping_value);
+ Assert.AreEqual(false, param_advanced_grouping);
+ Assert.AreEqual(false, param_enable_company_job_title_collapse);
+ }
+
+ [Test]
+ public void WhereGroupValue_SetsCorrectParameters_WhenNotSet() {
+ var jobSearch = new JobSearchStub("DevKey", "api.careerbuilder.com", "", "");
+ jobSearch.AddParametersToRequest();
+ var param_grouping_value = jobSearch.Request.Parameters.Find(qs => qs.Name == "groupingvalue");
+ var param_advanced_grouping = jobSearch.Request.Parameters.Find(qs => qs.Name == "advancedgroupingmode").Value;
+ var param_enable_company_job_title_collapse = jobSearch.Request.Parameters.Find(qs => qs.Name == "enablecompanyjobtitlecollapse").Value;
+ Assert.IsNull(param_grouping_value);
+ Assert.AreEqual(false,param_advanced_grouping);
+ Assert.AreEqual(false,param_enable_company_job_title_collapse);
+ }
+
+ [Test]
+ public void SetRecordsPerGroup() {
+ var jobSearch = new JobSearchStub("DevKey", "api.careerbuilder.com", "", "");
+ jobSearch.SetRecordsPerGroup(2);
+ jobSearch.AddParametersToRequest();
+ var param_records_per_group = jobSearch.Request.Parameters.Find(qs => qs.Name == "recordspergroup").Value;
+ Assert.AreEqual(2,param_records_per_group );
+ }
+
+ [Test]
+ public void SetRecordsPerGroup_NotSet() {
+ var jobSearch = new JobSearchStub("DevKey", "api.careerbuilder.com", "", "");
+ jobSearch.AddParametersToRequest();
+ var param_records_per_group = jobSearch.Request.Parameters.Find(qs => qs.Name == "recordspergroup");
+ Assert.IsNull(param_records_per_group);
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/CBApi.Tests/CBApi/framework/Requests/OAuthRedirectBuilderTest.cs b/CBApi.Tests/CBApi/framework/Requests/OAuthRedirectBuilderTest.cs
new file mode 100644
index 0000000..4927de1
--- /dev/null
+++ b/CBApi.Tests/CBApi/framework/Requests/OAuthRedirectBuilderTest.cs
@@ -0,0 +1,115 @@
+using CBApi.Framework.Requests;
+using NUnit.Framework;
+using System;
+using System.Web;
+
+namespace Tests.CBApi.framework.requests {
+ [TestFixture]
+ public class OAuthRedirectBuilderTest {
+ [Test]
+ public void Constructor_SetsClientID() {
+ var request = new OAuthRedirectBuilderStub("ClientID", "redirectURI","","api.careerbuilder.com");
+ Assert.AreEqual("ClientID", request.ClientId);
+ }
+
+ [Test]
+ public void Constructor_SetsRedirectUri() {
+ var request = new OAuthRedirectBuilderStub("ClientID", "redirectURI", "", "api.careerbuilder.com");
+ Assert.AreEqual("redirectURI", request.RedirectUri);
+ }
+
+ [Test]
+ public void Constructor_SetsDomain() {
+ var request = new OAuthRedirectBuilderStub("ClientID", "redirectURI", "", "api.careerbuilder.com");
+ Assert.AreEqual("api.careerbuilder.com", request.Domain);
+ }
+
+ [Test]
+ public void Constructor_ThrowsException_WhenPassedNullOrEmptyClientID() {
+ try {
+ var request = new OAuthRedirectBuilderStub("", "redirectURI", "", "api.careerbuilder.com");
+ Assert.Fail("Should have thrown exception");
+ } catch (ArgumentNullException ex) {
+ Assert.IsInstanceOf(ex);
+ }
+
+ try {
+ var request = new OAuthRedirectBuilderStub(null, "redirectURI", "", "api.careerbuilder.com");
+ Assert.Fail("Should have thrown exception");
+ } catch (ArgumentNullException ex) {
+ Assert.IsInstanceOf(ex);
+ }
+ }
+
+ [Test]
+ public void Constructor_ThrowsException_WhenPassedNullOrEmptyRedirectUri() {
+ try {
+ var request = new OAuthRedirectBuilderStub("ClientID", "", "", "api.careerbuilder.com");
+ Assert.Fail("Should have thrown exception");
+ } catch (ArgumentNullException ex) {
+ Assert.IsInstanceOf(ex);
+ }
+
+ try {
+ var request = new OAuthRedirectBuilderStub("ClientID", null, "", "api.careerbuilder.com");
+ Assert.Fail("Should have thrown exception");
+ } catch (ArgumentNullException ex) {
+ Assert.IsInstanceOf(ex);
+ }
+ }
+
+ [Test]
+ public void Constructor_ThrowsException_WhenPassedNullOrEmptyDomain() {
+ try {
+ var request = new OAuthRedirectBuilderStub("ClientID", "redirectURI", "", "");
+ Assert.Fail("Should have thrown exception");
+ } catch (ArgumentNullException ex) {
+ Assert.IsInstanceOf(ex);
+ }
+
+ try {
+ var request = new OAuthRedirectBuilderStub("ClientID", "redirectURI", "", null);
+ Assert.Fail("Should have thrown exception");
+ } catch (ArgumentNullException ex) {
+ Assert.IsInstanceOf(ex);
+ }
+ }
+
+ [Test]
+ public void OAuthUri_BuildsCorrectUriWithoutResources() {
+ var request = new OAuthRedirectBuilderStub("ClientID", HttpUtility.UrlEncode("https://jobseeker.careerbuilder.com/MyCareerBuilder"), "", "api.careerbuilder.com");
+ var uri = request.OAuthUri();
+ Assert.AreEqual("https://api.careerbuilder.com/auth/prompt?client_id=ClientID&redirect_uri=https%3a%2f%2fjobseeker.careerbuilder.com%2fMyCareerBuilder", uri.AbsoluteUri);
+ }
+
+ [Test]
+ public void OAuthUri_BuildsCorrectUriWithResources() {
+ var request = new OAuthRedirectBuilderStub("ClientID", HttpUtility.UrlEncode("https://jobseeker.careerbuilder.com/MyCareerBuilder"), "Resources", "api.careerbuilder.com");
+ var uri = request.OAuthUri();
+ Assert.AreEqual("https://api.careerbuilder.com/auth/prompt?client_id=ClientID&redirect_uri=https%3a%2f%2fjobseeker.careerbuilder.com%2fMyCareerBuilder&resources=Resources", uri.AbsoluteUri);
+ }
+
+
+ }
+
+ internal class OAuthRedirectBuilderStub : OAuthRedirectBuilder {
+ public OAuthRedirectBuilderStub(string clientId, string redirectUri, string additionalPermissions, string domain)
+ : base(clientId, redirectUri,additionalPermissions, domain) {
+ }
+
+ public string ClientId {
+ get { return _ClientId; }
+ set { _ClientId = value; }
+ }
+
+ public string Domain {
+ get { return _Domain; }
+ set { _Domain = value; }
+ }
+
+ public string RedirectUri {
+ get { return _RedirectURI; }
+ set { _RedirectURI = value; }
+ }
+ }
+}
\ No newline at end of file
diff --git a/CBApi.Tests/CBApi/framework/Requests/PostRequestTest.cs b/CBApi.Tests/CBApi/framework/Requests/PostRequestTest.cs
new file mode 100644
index 0000000..a9bf641
--- /dev/null
+++ b/CBApi.Tests/CBApi/framework/Requests/PostRequestTest.cs
@@ -0,0 +1,121 @@
+using CBApi;
+using NUnit.Framework;
+using Moq;
+using RestSharp;
+using System;
+using Tests.CBApi.models.requests;
+using Tests.CBApi.models.service;
+
+namespace Tests.CBApi.framework.requests {
+ [TestFixture]
+ public class PostRequestTest {
+ private bool _HasEventFired = false;
+
+ [Test]
+ public void BaseURL_IsNotSecure_WhenTargetSiteIsntSecure() {
+ //Setup
+ var newSite = new TargetSiteMock("127.0.0.1") { SetHost = "www.google.com", SetSecure = false };
+ var settings = new APISettings() { DevKey = "DevKey", CobrandCode = "this is a cobrand", SiteId = "this is a siteid", TimeoutMS = 12345, TargetSite = newSite };
+ var request = new PostRequestStub(settings);
+ Assert.AreEqual("http://127.0.0.1/Exammple", request.GetRequestURL);
+ }
+
+ [Test]
+ public void BaseURL_IsSecure_WhenTargetSiteIsSecure() {
+ //Setup
+ var newSite = new TargetSiteMock("127.0.0.1") { SetHost = "www.google.com", SetSecure = true };
+ var settings = new APISettings() { DevKey = "DevKey", CobrandCode = "this is a cobrand", SiteId = "this is a siteid", TimeoutMS = 12345, TargetSite = newSite };
+ var request = new PostRequestStub(settings);
+ Assert.AreEqual("https://127.0.0.1/Exammple", request.GetRequestURL);
+ }
+
+ [Test]
+ public void BeforeRequest_SetsURL_SetsFormat_SetsTimeout() {
+ //Setup
+ var request = new PostRequestStub("DevKey", "api.careerbuilder.com", "this is a cobrand", "this is a siteid",12345);
+
+ //Mock crap
+ var restClient = new Mock();
+ var restReq = new Mock();
+ restClient.SetupSet(x => x.BaseUrl = "https://api.careerbuilder.com/Exammple");
+
+ restReq.SetupSet(x => x.RequestFormat = DataFormat.Xml);
+ restReq.SetupSet(x => x.Timeout = 12345);
+
+
+ request.Request = restReq.Object;
+ request.Client = restClient.Object;
+
+ //Assert
+ request.RunBeforeRequest();
+ restReq.VerifyAll();
+ }
+
+ [Test]
+ public void BeforeRequest_AddsHostParameter() {
+ //Setup
+ var newSite = new TargetSiteMock("127.0.0.1") { SetHost = "www.google.com" };
+ var settings = new APISettings() { DevKey = "DevKey", CobrandCode = "this is a cobrand", SiteId = "this is a siteid", TimeoutMS = 12345, TargetSite = newSite };
+ var request = new GetRequestStub(settings);
+
+ //Mock crap
+ var restReq = new Mock();
+ restReq.Setup(x => x.AddHeader("Host", "www.google.com"));
+
+ var restClient = new Mock();
+ request.Request = restReq.Object;
+ request.Client = restClient.Object;
+
+ //Assert
+ request.RunBeforeGet();
+ restReq.VerifyAll();
+ }
+
+ [Test]
+ public void BeforeRequest_AddsDeveloperKeyParameter() {
+ //Setup
+ var newSite = new TargetSiteMock("127.0.0.1") { SetHost = "www.google.com" };
+ var settings = new APISettings() { DevKey = "DevKey", CobrandCode = "this is a cobrand", SiteId = "this is a siteid", TimeoutMS = 12345, TargetSite = newSite };
+ var request = new PostRequestStub(settings);
+
+ //Mock crap
+ var restReq = new Mock();
+ restReq.Setup(x => x.AddHeader("DeveloperKey", settings.DevKey));
+ restReq.Setup(x => x.AddHeader("Host", "www.google.com"));
+
+ var restClient = new Mock();
+ request.Request = restReq.Object;
+ request.Client = restClient.Object;
+
+ //Assert
+ request.RunBeforeRequest();
+ restReq.VerifyAll();
+ }
+
+ [Test]
+ public void BeforeRequest_RaisesBeforeRequestEvent() {
+ //Setup
+ var newSite = new TargetSiteMock("127.0.0.1") { SetHost = "www.google.com" };
+ var settings = new APISettings() { DevKey = "DevKey", CobrandCode = "this is a cobrand", SiteId = "this is a siteid", TimeoutMS = 12345, TargetSite = newSite };
+ var request = new PostRequestStub(settings);
+
+ //Mock crap
+ var restReq = new Mock();
+ var restClient = new Mock();
+ restClient.Setup(x => x.BaseUrl).Returns("https://127.0.0.1/Exammple");
+ request.Request = restReq.Object;
+ request.Client = restClient.Object;
+
+ //Assert
+ request.OnBeforeRequest += (HandleAfterRequest);
+ request.RunBeforeRequest();
+ Assert.AreEqual(true, _HasEventFired);
+ request.OnBeforeRequest -= (HandleAfterRequest);
+ }
+
+ private void HandleAfterRequest(IRequestEventData data) {
+ _HasEventFired = true;
+ Assert.AreEqual("https://127.0.0.1/Exammple", data.BaseURL);
+ }
+ }
+}
\ No newline at end of file
diff --git a/CBApi.Tests/CBApi/framework/Requests/RetrieveASavedSearchTests.cs b/CBApi.Tests/CBApi/framework/Requests/RetrieveASavedSearchTests.cs
new file mode 100644
index 0000000..2ce0a99
--- /dev/null
+++ b/CBApi.Tests/CBApi/framework/Requests/RetrieveASavedSearchTests.cs
@@ -0,0 +1,44 @@
+using CBApi.Models.WebAPIs.SavedSearch;
+using NUnit.Framework;
+using Moq;
+using RestSharp;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Tests.com.careerbuilder.CBApi.framework.stubrequests;
+
+namespace Tests.com.careerbuilder.CBApi.framework.requests
+{
+ [TestFixture]
+ public class RetrieveASavedSearchTests
+ {
+ [Test]
+ public void Submit_PerformsCorrectRequest()
+ {
+ //setup
+ var request = new RetrieveASavedSearchStub("DevKey", "api.careerbuilder.com", "", "", 12345, "savedSearchDID");
+
+ //mock
+ var response = new RestResponse
+ {
+ Data = new SavedSearches(),
+ ResponseStatus = ResponseStatus.Completed
+ };
+ var restReq = new Mock();
+
+ var restClient = new Mock();
+ restClient.SetupSet(x => x.BaseUrl = "https://api.careerbuilder.com/CBAPI/SavedSearches/savedSearchDID");
+ restClient.Setup(x=> x.Execute(It.IsAny())).Returns(response);
+
+ request.Request = restReq.Object;
+ request.Client = restClient.Object;
+
+ //assertions
+
+ SavedSearches rest = request.Submit("userOAuthToken");
+ restReq.VerifyAll();
+ restClient.VerifyAll();
+ }
+ }
+}
diff --git a/CBApi.Tests/CBApi/framework/Requests/SavedSearchCreateRequestTest.cs b/CBApi.Tests/CBApi/framework/Requests/SavedSearchCreateRequestTest.cs
new file mode 100644
index 0000000..a8e991c
--- /dev/null
+++ b/CBApi.Tests/CBApi/framework/Requests/SavedSearchCreateRequestTest.cs
@@ -0,0 +1,65 @@
+using CBApi;
+using CBApi.Framework.Requests;
+using CBApi.Models;
+using NUnit.Framework;
+using Moq;
+using RestSharp;
+using System;
+using Tests.CBApi.models.requests;
+using Tests.CBApi.models.service;
+
+namespace Tests.CBApi.framework.requests
+{
+ [TestFixture]
+ public class SavedSearchCreateRequestTest
+ {
+ [Test]
+ public void Submit_PerformsCorrectRequest()
+ {
+ //setup
+ var request = new SavedSearchCreateRequestStub("DevKey", "api.careerbuilder.com", "", "", 12345);
+ var dummyApp = new SavedSearchCreate();
+ dummyApp = SetUpApp(dummyApp);
+
+ //Mock
+ var response = new RestResponse { Data = new SavedSearchCreateResponse(), ResponseStatus = ResponseStatus.Completed };
+ var restReq = new Mock();
+ restReq.Setup(x => x.AddBody(dummyApp));
+
+
+
+ var restClient = new Mock();
+ restClient.SetupSet(x => x.BaseUrl = "https://api.careerbuilder.com/v2/SavedSearch/Create");
+ restClient.Setup(x => x.Execute(It.IsAny())).Returns(response);
+
+ request.Request = restReq.Object;
+ request.Client = restClient.Object;
+
+ //Assertions
+ SavedSearchCreateResponse rest = request.Submit(dummyApp);
+ restReq.VerifyAll();
+ restClient.VerifyAll();
+ }
+
+ private SavedSearchCreate SetUpApp(SavedSearchCreate dummyApp)
+ {
+ dummyApp.HostSite = "US";
+ dummyApp.SearchName = "lotsloc";
+ dummyApp.IsDailyEmail = "none";
+ dummyApp.ExternalUserID = "Nicholas.Busby.Test@CareerBuilder.com";
+ dummyApp.DeveloperKey = "WDJ16BN6CQB69FP18Y8F";
+ dummyApp.SearchParameters = new SearchParameters();
+ dummyApp.SearchParameters.Radius = 30;
+ dummyApp.SearchParameters.PayHigh = 70;
+ dummyApp.SearchParameters.PayLow = 40;
+ dummyApp.SearchParameters.PostedWithin = 30;
+ dummyApp.SearchParameters.PayInfoOnly = false;
+ dummyApp.SearchParameters.Location = "Chicago, Il, Atlanta, Ga, New York, Ny";
+ dummyApp.SearchParameters.OrderDirection = "ascending";
+ dummyApp.SearchParameters.SpecificEducation = false;
+ dummyApp.SearchParameters.ExcludeNational = false;
+ dummyApp.SearchParameters.OrderBy = "Pay";
+ return dummyApp;
+ }
+ }
+}
diff --git a/CBApi.Tests/CBApi/framework/Requests/SavedSearchDeleteRequestTest.cs b/CBApi.Tests/CBApi/framework/Requests/SavedSearchDeleteRequestTest.cs
new file mode 100644
index 0000000..bcce343
--- /dev/null
+++ b/CBApi.Tests/CBApi/framework/Requests/SavedSearchDeleteRequestTest.cs
@@ -0,0 +1,43 @@
+using System;
+using NUnit.Framework;
+using CBApi;
+using CBApi.Framework.Requests;
+using CBApi.Models;
+using Moq;
+using RestSharp;
+using Tests.CBApi.models.requests;
+using Tests.CBApi.models.service;
+
+namespace Tests.CBApi.framework.requests {
+
+ [TestFixture]
+ public class SavedSearchDeleteRequestTest
+ {
+ [Test]
+ public void Submit_DeleteSavedSearchRequest() {
+
+ var request = new SavedSearchDeleteRequestStub("DevKey", "api.careerbuilder.com", "", "", 12345);
+ var dummyDelete = new RequestSavedSearchDelete();
+ dummyDelete.HostSite = "US";
+ dummyDelete.ExternalUserID = "Nicholas.Busby.Test@CareerBuilder.com";
+ dummyDelete.DeveloperKey = "WDJ16BN6CQB69FP18Y8F";
+ dummyDelete.ExternalID = "test";
+
+ var response = new RestResponse { Data = new SavedSearchDeleteResponse(), ResponseStatus = ResponseStatus.Completed };
+
+ var restReq = new Mock();
+ restReq.Setup(x => x.AddBody(dummyDelete));
+
+ var restClient = new Mock();
+ restClient.SetupSet(x => x.BaseUrl = "https://api.careerbuilder.com/v1/savedsearch/delete.xml");
+ restClient.Setup(x => x.Execute(It.IsAny())).Returns(response);
+
+ request.Request = restReq.Object;
+ request.Client = restClient.Object;
+
+ SavedSearchDeleteResponse resp = request.Submit(dummyDelete);
+ restReq.VerifyAll();
+ restClient.VerifyAll();
+ }
+ }
+}
diff --git a/CBApi.Tests/CBApi/framework/Requests/SavedSearchListRequestTest.cs b/CBApi.Tests/CBApi/framework/Requests/SavedSearchListRequestTest.cs
new file mode 100644
index 0000000..87ff730
--- /dev/null
+++ b/CBApi.Tests/CBApi/framework/Requests/SavedSearchListRequestTest.cs
@@ -0,0 +1,36 @@
+using CBApi.Models;
+using NUnit.Framework;
+using Moq;
+using RestSharp;
+using Tests.CBApi.models.requests;
+
+namespace Tests.CBApi.framework.requests
+{
+ [TestFixture]
+ public class SavedSearchListRequestTest
+ {
+ [Test]
+ public void Submit_PerformsCorrectRequest()
+ {
+ //setup
+ var request = new SavedSearchListRequestStub("DevKey", "api.careerbuilder.com", "", "", 12345);
+ var dummyApp = new SavedSearchListRequestModel();
+
+ //Mock
+ var response = new RestResponse { Data = new SavedSearchListResponseModel(), ResponseStatus = ResponseStatus.Completed };
+ var restReq = new Mock();
+
+ var restClient = new Mock();
+ restClient.SetupSet(x => x.BaseUrl = "https://api.careerbuilder.com/v1/SavedSearch/List");
+ restClient.Setup(x => x.Execute(It.IsAny())).Returns(response);
+
+ request.Request = restReq.Object;
+ request.Client = restClient.Object;
+
+ //Assertions
+ SavedSearchListResponseModel rest = request.Submit(dummyApp);
+ restReq.VerifyAll();
+ restClient.VerifyAll();
+ }
+ }
+}
diff --git a/CBApi.Tests/CBApi/framework/Requests/SavedSearchRetrieveRequestTest.cs b/CBApi.Tests/CBApi/framework/Requests/SavedSearchRetrieveRequestTest.cs
new file mode 100644
index 0000000..0a58858
--- /dev/null
+++ b/CBApi.Tests/CBApi/framework/Requests/SavedSearchRetrieveRequestTest.cs
@@ -0,0 +1,36 @@
+using CBApi.Models;
+using NUnit.Framework;
+using Moq;
+using RestSharp;
+using Tests.CBApi.models.requests;
+
+namespace Tests.CBApi.framework.requests
+{
+ [TestFixture]
+ public class SavedSearchRetrieveRequestTest
+ {
+ [Test]
+ public void Submit_PerformsCorrectRequest()
+ {
+ //setup
+ var request = new SavedSearchRetrieveRequestStub("DevKey", "api.careerbuilder.com", "", "", 12345);
+ var dummyApp = new SavedSearchRetrieveRequestModel();
+
+ //Mock
+ var response = new RestResponse { Data = new SavedSearchRetrieveResponseModel(), ResponseStatus = ResponseStatus.Completed };
+ var restReq = new Mock();
+
+ var restClient = new Mock();
+ restClient.SetupSet(x => x.BaseUrl = "https://api.careerbuilder.com/v1/SavedSearch/retrieve");
+ restClient.Setup(x => x.Execute(It.IsAny())).Returns(response);
+
+ request.Request = restReq.Object;
+ request.Client = restClient.Object;
+
+ //Assertions
+ SavedSearchRetrieveResponseModel rest = request.Submit(dummyApp);
+ restReq.VerifyAll();
+ restClient.VerifyAll();
+ }
+ }
+}
diff --git a/CBApi.Tests/CBApi/framework/Requests/SavedSearchUpdateRequestTest.cs b/CBApi.Tests/CBApi/framework/Requests/SavedSearchUpdateRequestTest.cs
new file mode 100644
index 0000000..88aced9
--- /dev/null
+++ b/CBApi.Tests/CBApi/framework/Requests/SavedSearchUpdateRequestTest.cs
@@ -0,0 +1,39 @@
+using CBApi.Models;
+using NUnit.Framework;
+using Moq;
+using RestSharp;
+using Tests.CBApi.models.requests;
+
+namespace Tests.CBApi.framework.requests
+{
+ [TestFixture]
+ public class SavedSearchUpdateRequestTest
+ {
+ [Test]
+ public void Submit_PerformsCorrectRequest()
+ {
+ //setup
+ var request = new SavedSearchUpdateRequestStub("DevKey", "api.careerbuilder.com", "", "", 12345);
+ var dummyApp = new SavedSearchUpdateRequestModel();
+
+ //Mock
+ var response = new RestResponse { Data = new SavedSearchUpdateResponseModel(), ResponseStatus = ResponseStatus.Completed };
+ var restReq = new Mock();
+ restReq.Setup(x => x.AddBody(dummyApp));
+
+
+
+ var restClient = new Mock();
+ restClient.SetupSet(x => x.BaseUrl = "https://api.careerbuilder.com/v2/SavedSearch/Update");
+ restClient.Setup(x => x.Execute(It.IsAny())).Returns(response);
+
+ request.Request = restReq.Object;
+ request.Client = restClient.Object;
+
+ //Assertions
+ SavedSearchUpdateResponseModel rest = request.Submit(dummyApp);
+ restReq.VerifyAll();
+ restClient.VerifyAll();
+ }
+ }
+}
diff --git a/CBApi.Tests/CBApi/framework/Requests/SubmitApplicationRequestTest.cs b/CBApi.Tests/CBApi/framework/Requests/SubmitApplicationRequestTest.cs
new file mode 100644
index 0000000..a2d3096
--- /dev/null
+++ b/CBApi.Tests/CBApi/framework/Requests/SubmitApplicationRequestTest.cs
@@ -0,0 +1,40 @@
+using CBApi;
+using CBApi.Framework.Requests;
+using CBApi.Models;
+using NUnit.Framework;
+using Moq;
+using RestSharp;
+using System;
+using Tests.CBApi.models.requests;
+using Tests.CBApi.models.service;
+
+namespace Tests.CBApi.framework.requests {
+ [TestFixture]
+ public class SubmitApplicationRequestTest {
+
+ [Test]
+ public void Submit_PerformsCorrectRequest() {
+ //Setup
+ var request = new SubmitApplicationRequestStub("DevKey", "api.careerbuilder.com", "", "", 12345);
+ var dummyApp = new RequestApplication();
+
+ //Mock crap
+ var response = new RestResponse { Data = new ResponseApplication(),ResponseStatus = ResponseStatus.Completed };
+
+ var restReq = new Mock();
+ restReq.Setup(x => x.AddBody(dummyApp));
+
+ var restClient = new Mock();
+ restClient.SetupSet(x => x.BaseUrl = "https://api.careerbuilder.com/v1/application/submit");
+ restClient.Setup(x => x.Execute(It.IsAny())).Returns(response);
+
+ request.Request = restReq.Object;
+ request.Client = restClient.Object;
+
+ //Assert
+ ResponseApplication resp = request.Submit(dummyApp);
+ restReq.VerifyAll();
+ restClient.VerifyAll();
+ }
+ }
+}
\ No newline at end of file
diff --git a/CBApi.Tests/CBApi/framework/Requests/TargetSiteTest.cs b/CBApi.Tests/CBApi/framework/Requests/TargetSiteTest.cs
new file mode 100644
index 0000000..6db0284
--- /dev/null
+++ b/CBApi.Tests/CBApi/framework/Requests/TargetSiteTest.cs
@@ -0,0 +1,58 @@
+using CBApi;
+using CBApi.Framework.Requests;
+using CBApi.Models;
+using NUnit.Framework;
+using Moq;
+using RestSharp;
+using System;
+using Tests.CBApi.models.requests;
+using Tests.CBApi.models.service;
+
+namespace Tests.CBApi.framework.requests
+{
+ [TestFixture]
+ public class TargetSiteTest
+ {
+
+
+ [Test]
+ public void GetRequestURL_BuildsCorrectEndpointAddress()
+ {
+ var site = new TargetSiteMock("10.0.0.1") { SetHost = "api.koolkid.com", SetSecure = true };
+ var request = new BlankAppStub("JXXXXXXXXXXXXXXXXXX", "DevKey","","",site);
+ Assert.AreEqual("https://10.0.0.1/v1/application/blank", request.RequestURL);
+ }
+
+ [Test]
+ public void Retrieve_AddsProperHeaders()
+ {
+ //Setup
+ var site = new TargetSiteMock("10.0.0.1") { SetHost = "api.koolkid.com", SetSecure = true };
+ site.SetHeaders.Add("ILikeHeaders", "true");
+
+ var request = new BlankAppStub("JXXXXXXXXXXXXXXXXXX", "DevKey", "api.careerbuilder.com", "",site);
+
+ //Mock crap
+ var response = new RestResponse {Data = new BlankApplication()};
+
+ var restReq = new Mock();
+ restReq.Setup(x => x.AddHeader("Host", "api.koolkid.com"));
+ restReq.Setup(x => x.AddHeader("ILikeHeaders", "true"));
+ restReq.Setup(x => x.AddParameter("DeveloperKey", "DevKey"));
+ restReq.Setup(x => x.AddParameter("JobDID", "JXXXXXXXXXXXXXXXXXX"));
+ restReq.SetupSet(x => x.RootElement = "BlankApplication");
+
+ var restClient = new Mock();
+ restClient.SetupSet(x => x.BaseUrl = "https://10.0.0.1/v1/application/blank");
+ restClient.Setup(x => x.Execute(It.IsAny())).Returns(response);
+
+ request.Request = restReq.Object;
+ request.Client = restClient.Object;
+
+ //Assert
+ BlankApplication resp = request.Retrieve();
+ restReq.VerifyAll();
+ restClient.VerifyAll();
+ }
+ }
+}
\ No newline at end of file
diff --git a/CBApi.Tests/CBApi/framework/Requests/UserRecommendationsRequestTest.cs b/CBApi.Tests/CBApi/framework/Requests/UserRecommendationsRequestTest.cs
new file mode 100644
index 0000000..726a121
--- /dev/null
+++ b/CBApi.Tests/CBApi/framework/Requests/UserRecommendationsRequestTest.cs
@@ -0,0 +1,92 @@
+using CBApi.Models;
+using NUnit.Framework;
+using Moq;
+using RestSharp;
+using System;
+using System.Collections.Generic;
+using Tests.CBApi.models.requests;
+using CBApi.Framework.Requests;
+
+namespace Tests.CBApi.framework.requests
+{
+ [TestFixture]
+ public class UserRecommendationsRequestTest
+ {
+
+ [Test]
+ public void VerifyQueryStrings() {
+ List QueryStringList = new List();
+ QueryStringList.Add(new GenericParam("name", "value"));
+ QueryStringList.Add(new GenericParam("name2", "value2"));
+ var request = new UserReqStub(QueryStringList , "DevKey", "api.careerbuilder.com", "", "");
+ //add parameters and verify that both were added.
+ request.AddQueryStrings();
+ Assert.IsTrue(2 == request.Request.Parameters.Count);
+
+ }
+ [Test]
+ public void Constructor_SetsExternalID()
+ {
+ var request = new UserReqStub("ExternalID", "DevKey", "api.careerbuilder.com", "", "");
+ Assert.AreEqual("ExternalID", request.ExternalID);
+ }
+
+ [Test]
+ public void Constructor_ThrowsException_WhenPassedNullOrEmpty()
+ {
+ try
+ {
+ var request = new UserReqStub((string)null, "DevKey", "api.careerbuilder.com", "", "");
+ Assert.Fail("Should have thrown exception");
+ }
+ catch (ArgumentNullException ex)
+ {
+ Assert.IsInstanceOf(ex);
+ }
+
+ try
+ {
+ var request2 = new UserReqStub("", "DevKey", "api.careerbuilder.com", "", "");
+ Assert.Fail("Should have thrown exception");
+ }
+ catch (ArgumentNullException ex)
+ {
+ Assert.IsInstanceOf(ex);
+ }
+ }
+
+ [Test]
+ public void GetRequestURL_BuildsCorrectEndpointAddress()
+ {
+ var request = new UserReqStub("ExternalID", "DevKey", "api.careerbuilder.com", "", "");
+ Assert.AreEqual("https://api.careerbuilder.com/v1/recommendations/foruser", request.RequestURL);
+ }
+
+ [Test]
+ public void GetRecommendations_PerformsCorrectRequest()
+ {
+ //Setup
+ var request = new UserReqStub("ExternalID", "DevKey", "api.careerbuilder.com", "", "");
+
+ //Mock crap
+ var response = new RestResponse> {Data = new List()};
+
+ var restReq = new Mock();
+ restReq.Setup(x => x.AddParameter("DeveloperKey", "DevKey"));
+ restReq.Setup(x => x.AddParameter("ExternalID", "ExternalID"));
+ restReq.SetupSet(x => x.RootElement = "RecommendJobResults");
+
+ var restClient = new Mock();
+ restClient.SetupSet(x => x.BaseUrl = "https://api.careerbuilder.com/v1/recommendations/foruser");
+ restClient.Setup(x => x.Execute>(It.IsAny())).Returns(response);
+
+ request.Request = restReq.Object;
+ request.Client = restClient.Object;
+
+ //Assert
+ List resp = request.GetRecommendations();
+ restReq.VerifyAll();
+ restClient.VerifyAll();
+ }
+ }
+}
\ No newline at end of file
diff --git a/CBApi.Tests/CBApi/framework/stubrequests/AuthTokenRequestStub.cs b/CBApi.Tests/CBApi/framework/stubrequests/AuthTokenRequestStub.cs
new file mode 100644
index 0000000..9e12920
--- /dev/null
+++ b/CBApi.Tests/CBApi/framework/stubrequests/AuthTokenRequestStub.cs
@@ -0,0 +1,57 @@
+using CBApi;
+using CBApi.Framework.Requests;
+using RestSharp;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Tests.CBApi.models.service;
+
+namespace Tests.CBApi.models.requests {
+ internal class AuthTokenRequestStub : AuthTokenRequest {
+ public AuthTokenRequestStub(string clientId, string clientSecret, string code, string redirectUri, string key, string domain, string cobrand, string siteid)
+ : base(clientId, clientSecret, code, redirectUri, new APISettings() { DevKey = key, CobrandCode = cobrand, SiteId = siteid, TargetSite = new TargetSiteMock(domain) }) {
+ }
+
+ public string ClientId {
+ get { return _ClientId; }
+ set { _ClientId = value; }
+ }
+
+ public string ClientSecret {
+ get { return _ClientSecret; }
+ set { _ClientSecret = value; }
+ }
+
+
+ public string Code {
+ get { return _Code; }
+ set { _Code = value; }
+ }
+
+
+ public string RedirectUri {
+ get { return _RedirectUri; }
+ set { _RedirectUri = value; }
+ }
+
+
+ public string RequestURL {
+ get { return base.GetRequestURL(); }
+ }
+
+ public IRestClient Client {
+ get { return _client; }
+ set { _client = value; }
+ }
+
+ public IRestRequest Request {
+ get { return _request; }
+ set { _request = value; }
+ }
+
+ protected override void CheckForErrors(IRestResponse response) {
+
+ }
+ }
+}
diff --git a/CBApi.Tests/CBApi/framework/stubrequests/CategoriesStub.cs b/CBApi.Tests/CBApi/framework/stubrequests/CategoriesStub.cs
new file mode 100644
index 0000000..df56120
--- /dev/null
+++ b/CBApi.Tests/CBApi/framework/stubrequests/CategoriesStub.cs
@@ -0,0 +1,46 @@
+using CBApi;
+using CBApi.Framework.Requests;
+using RestSharp;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Tests.CBApi.models.service;
+
+namespace Tests.CBApi.models.requests {
+ internal class CategoriesStub : CategoriesRequest {
+ public CategoriesStub(string key, string domain, string cobrand, string siteid)
+ : base(new APISettings() { DevKey = key, CobrandCode = cobrand, SiteId = siteid, TargetSite = new TargetSiteMock(domain) }) {
+ }
+
+ public string DevKey {
+ get { return _Settings.DevKey; }
+ }
+
+ public string Domain {
+ get { return _Settings.TargetSite.Domain; }
+ }
+
+ public string CountryCode {
+ get { return _countryCode; }
+ }
+
+ public string RequestURL {
+ get { return base.GetRequestURL(); }
+ }
+
+ public IRestClient Client {
+ get { return _client; }
+ set { _client = value; }
+ }
+
+ public IRestRequest Request {
+ get { return _request; }
+ set { _request = value; }
+ }
+
+ protected override void CheckForErrors(IRestResponse response) {
+
+ }
+ }
+}
\ No newline at end of file
diff --git a/CBApi.Tests/CBApi/framework/stubrequests/EducationCodesRequestStub.cs b/CBApi.Tests/CBApi/framework/stubrequests/EducationCodesRequestStub.cs
new file mode 100644
index 0000000..aa1f4b8
--- /dev/null
+++ b/CBApi.Tests/CBApi/framework/stubrequests/EducationCodesRequestStub.cs
@@ -0,0 +1,54 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using CBApi;
+using CBApi.Framework.Requests;
+using RestSharp;
+using Tests.CBApi.models.service;
+
+namespace Tests.CBApi.models.requests
+{
+ internal class EducationCodesRequestStub : EducationCodesRequest
+ {
+ internal EducationCodesRequestStub(string key, string domain, string cobrand, string siteid)
+ : base(new APISettings() { DevKey = key, CobrandCode = cobrand, SiteId = siteid, TargetSite = new TargetSiteMock(domain) }) { }
+
+ public string DevKey
+ {
+ get { return _Settings.DevKey; }
+ }
+
+ public string Domain
+ {
+ get { return _Settings.TargetSite.Domain; }
+ }
+
+ public string CountryCode
+ {
+ get { return _countryCode; }
+ }
+
+ public string RequestURL
+ {
+ get { return base.GetRequestURL(); }
+ }
+
+ public IRestClient Client
+ {
+ get { return _client; }
+ set { _client = value; }
+ }
+
+ public IRestRequest Request
+ {
+ get { return _request; }
+ set { _request = value; }
+ }
+
+ protected override void CheckForErrors(IRestResponse response)
+ {
+
+ }
+ }
+}
diff --git a/CBApi.Tests/CBApi/framework/stubrequests/EmployeeTypesStub.cs b/CBApi.Tests/CBApi/framework/stubrequests/EmployeeTypesStub.cs
new file mode 100644
index 0000000..2f257c9
--- /dev/null
+++ b/CBApi.Tests/CBApi/framework/stubrequests/EmployeeTypesStub.cs
@@ -0,0 +1,46 @@
+using CBApi;
+using CBApi.Framework.Requests;
+using RestSharp;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Tests.CBApi.models.service;
+
+namespace Tests.CBApi.models.requests {
+ internal class EmployeeTypesStub : EmployeeTypesRequest {
+ public EmployeeTypesStub(string key, string domain)
+ : base(new APISettings() { DevKey = key, CobrandCode = "", SiteId = "", TargetSite = new TargetSiteMock(domain) }) {
+ }
+
+ public string DevKey {
+ get { return _Settings.DevKey; }
+ }
+
+ public string Domain {
+ get { return _Settings.TargetSite.Domain; }
+ }
+
+ public string CountryCode {
+ get { return _countryCode; }
+ }
+
+ public string RequestURL {
+ get { return base.GetRequestURL(); }
+ }
+
+ public IRestClient Client {
+ get { return _client; }
+ set { _client = value; }
+ }
+
+ public IRestRequest Request {
+ get { return _request; }
+ set { _request = value; }
+ }
+
+ protected override void CheckForErrors(IRestResponse response) {
+
+ }
+ }
+}
\ No newline at end of file
diff --git a/CBApi.Tests/CBApi/framework/stubrequests/GetRequestStub.cs b/CBApi.Tests/CBApi/framework/stubrequests/GetRequestStub.cs
new file mode 100644
index 0000000..39e248d
--- /dev/null
+++ b/CBApi.Tests/CBApi/framework/stubrequests/GetRequestStub.cs
@@ -0,0 +1,65 @@
+using CBApi;
+using CBApi.Framework.Requests;
+using RestSharp;
+using Tests.CBApi.models.service;
+
+namespace Tests.CBApi.models.requests {
+ internal class GetRequestStub : GetRequest {
+ private string _BaseURL = "/Exammple";
+ public GetRequestStub(string key, string domain, string cobrand, string siteid)
+ : base(new APISettings() { DevKey = key, CobrandCode = cobrand, SiteId = siteid, TargetSite = new TargetSiteMock(domain) }) {
+ }
+
+ public GetRequestStub(APISettings settings)
+ : base(settings) {
+
+ }
+
+ public new string GetRequestURL {
+ get { return GetRequestURL(); }
+ }
+
+ public override string BaseUrl {
+ get { return _BaseURL; }
+ }
+
+ public string SetBaseUrl {
+ set { _BaseURL = value; }
+ }
+
+
+ public string DevKey {
+ get { return _Settings.DevKey; }
+ }
+
+ public string Domain {
+ get { return _Settings.TargetSite.Domain; }
+ }
+
+ public string CobrandCode {
+ get { return _Settings.CobrandCode; }
+ }
+
+ public string SiteID {
+ get { return _Settings.SiteId; }
+ }
+
+ public string RequestURL {
+ get { return base.GetRequestURL(); }
+ }
+
+ public IRestClient Client {
+ get { return _client; }
+ set { _client = value; }
+ }
+
+ public IRestRequest Request {
+ get { return _request; }
+ set { _request = value; }
+ }
+
+ public void RunBeforeGet() {
+ BeforeRequest();
+ }
+ }
+}
diff --git a/CBApi.Tests/CBApi/framework/stubrequests/JobRecRequestStub.cs b/CBApi.Tests/CBApi/framework/stubrequests/JobRecRequestStub.cs
new file mode 100644
index 0000000..f8607e6
--- /dev/null
+++ b/CBApi.Tests/CBApi/framework/stubrequests/JobRecRequestStub.cs
@@ -0,0 +1,40 @@
+using CBApi;
+using CBApi.Framework.Requests;
+using RestSharp;
+using Tests.CBApi.models.service;
+
+namespace Tests.CBApi.models.requests {
+ internal class JobRecRequestStub : JobRecommendationsRequest {
+ public JobRecRequestStub(string jobDid, string key, string domain, string cobrand, string siteid)
+ : base(jobDid, new APISettings() { DevKey = key, CobrandCode = cobrand, SiteId = siteid, TargetSite = new TargetSiteMock(domain) }) {
+ }
+
+ public string JobDid {
+ get { return _jobDid; }
+ }
+
+ public string DevKey {
+ get { return _Settings.DevKey; }
+ }
+
+ public string Domain {
+ get { return _Settings.TargetSite.Domain; }
+ }
+
+ public string RequestURL {
+ get { return base.GetRequestURL(); }
+ }
+
+ public IRestClient Client {
+ get { return _client; }
+ set { _client = value; }
+ }
+
+ public IRestRequest Request {
+ get { return _request; }
+ set { _request = value; }
+ }
+
+ protected override void CheckForErrors(IRestResponse response) { }
+ }
+}
diff --git a/CBApi.Tests/CBApi/framework/stubrequests/JobRecWithUserPrefRequestStub.cs b/CBApi.Tests/CBApi/framework/stubrequests/JobRecWithUserPrefRequestStub.cs
new file mode 100644
index 0000000..b3807ba
--- /dev/null
+++ b/CBApi.Tests/CBApi/framework/stubrequests/JobRecWithUserPrefRequestStub.cs
@@ -0,0 +1,44 @@
+using CBApi;
+using CBApi.Framework.Requests;
+using RestSharp;
+using Tests.CBApi.models.service;
+
+namespace Tests.CBApi.models.requests {
+ internal class JobRecWithUserPrefRequestStub : JobRecommendationsWithUserPreferencesRequest {
+ public JobRecWithUserPrefRequestStub(string jobDid, string userDid, string key, string domain, string cobrand, string siteid)
+ : base(jobDid, userDid, new APISettings() { DevKey = key, CobrandCode = cobrand, SiteId = siteid, TargetSite = new TargetSiteMock(domain) }) {
+ }
+
+ public string JobDid {
+ get { return _jobDid; }
+ }
+
+ public string UserDid {
+ get { return _userDid; }
+ }
+
+ public string DevKey {
+ get { return _Settings.DevKey; }
+ }
+
+ public string Domain {
+ get { return _Settings.TargetSite.Domain; }
+ }
+
+ public string RequestURL {
+ get { return base.GetRequestURL(); }
+ }
+
+ public IRestClient Client {
+ get { return _client; }
+ set { _client = value; }
+ }
+
+ public IRestRequest Request {
+ get { return _request; }
+ set { _request = value; }
+ }
+
+ protected override void CheckForErrors(IRestResponse response) { }
+ }
+}
diff --git a/CBApi.Tests/CBApi/framework/stubrequests/JobRequestStub.cs b/CBApi.Tests/CBApi/framework/stubrequests/JobRequestStub.cs
new file mode 100644
index 0000000..1566c61
--- /dev/null
+++ b/CBApi.Tests/CBApi/framework/stubrequests/JobRequestStub.cs
@@ -0,0 +1,46 @@
+using CBApi;
+using CBApi.Framework.Requests;
+using RestSharp;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Tests.CBApi.models.service;
+
+namespace Tests.CBApi.models.requests {
+ internal class JobRequestStub : JobRequest {
+ public JobRequestStub(string jobdid, string key, string domain, string cobrand, string siteid)
+ : base(jobdid, new APISettings() { DevKey = key, CobrandCode = cobrand, SiteId = siteid, TargetSite = new TargetSiteMock(domain) }) {
+ }
+
+ public string DevKey {
+ get { return _Settings.DevKey; }
+ }
+
+ public string Domain {
+ get { return _Settings.TargetSite.Domain; }
+ }
+
+ public string JobDID {
+ get { return _jobDid; }
+ }
+
+ public string RequestURL {
+ get { return base.GetRequestURL(); }
+ }
+
+ public IRestClient Client {
+ get { return _client; }
+ set { _client = value; }
+ }
+
+ public IRestRequest Request {
+ get { return _request; }
+ set { _request = value; }
+ }
+
+ protected override void CheckForErrors(IRestResponse response) {
+
+ }
+ }
+}
diff --git a/CBApi.Tests/CBApi/framework/stubrequests/JobSearchStub.cs b/CBApi.Tests/CBApi/framework/stubrequests/JobSearchStub.cs
new file mode 100644
index 0000000..bb2e64e
--- /dev/null
+++ b/CBApi.Tests/CBApi/framework/stubrequests/JobSearchStub.cs
@@ -0,0 +1,47 @@
+using CBApi;
+using CBApi.Framework.Requests;
+using RestSharp;
+using Tests.CBApi.models.service;
+
+namespace Tests.CBApi.models.requests {
+ internal class JobSearchStub : JobSearchRequest {
+
+ public IRestClient Client {
+ get { return _client; }
+ set { _client = value; }
+ }
+
+ public string CountryCode {
+ get { return _CountryCode; }
+ }
+
+ public string DevKey {
+ get { return _Settings.DevKey; }
+ }
+
+ public string Domain {
+ get { return _Settings.TargetSite.Domain; }
+ }
+
+ public IRestRequest Request {
+ get { return _request; }
+ set { _request = value; }
+ }
+
+ public string RequestURL {
+ get { return base.GetRequestURL(); }
+ }
+
+ public JobSearchStub(string key, string domain, string cobrand, string siteid)
+ : base(new APISettings() { DevKey = key, CobrandCode = cobrand, SiteId = siteid, TargetSite = new TargetSiteMock(domain) }) {
+ }
+
+ protected override void CheckForErrors(IRestResponse response) {
+ }
+
+ public new void AddParametersToRequest() {
+ base.AddParametersToRequest();
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/CBApi.Tests/CBApi/framework/stubrequests/PostRequestStub.cs b/CBApi.Tests/CBApi/framework/stubrequests/PostRequestStub.cs
new file mode 100644
index 0000000..cff2d09
--- /dev/null
+++ b/CBApi.Tests/CBApi/framework/stubrequests/PostRequestStub.cs
@@ -0,0 +1,43 @@
+using CBApi;
+using CBApi.Framework.Requests;
+using RestSharp;
+using Tests.CBApi.models.service;
+
+namespace Tests.CBApi.models.requests {
+ internal class PostRequestStub : PostRequest {
+ private string _BaseURL = "/Exammple";
+ public PostRequestStub(string key, string domain, string cobrand, string siteid,int timeout)
+ : base(new APISettings() { DevKey = key, CobrandCode = cobrand, SiteId = siteid, TargetSite = new TargetSiteMock(domain),TimeoutMS = timeout }) {
+ }
+
+ public PostRequestStub(APISettings settings)
+ : base(settings) {
+ }
+
+ public override string BaseUrl {
+ get { return _BaseURL; }
+ }
+
+ public string SetBaseUrl {
+ set { _BaseURL = value; }
+ }
+
+ public string GetRequestURL {
+ get { return PostRequestURL(); }
+ }
+
+ public IRestClient Client {
+ get { return _client; }
+ set { _client = value; }
+ }
+
+ public IRestRequest Request {
+ get { return _request; }
+ set { _request = value; }
+ }
+
+ public void RunBeforeRequest() {
+ BeforeRequest();
+ }
+ }
+}
diff --git a/CBApi.Tests/CBApi/framework/stubrequests/RetrieveASavedSearchStub.cs b/CBApi.Tests/CBApi/framework/stubrequests/RetrieveASavedSearchStub.cs
new file mode 100644
index 0000000..d359a61
--- /dev/null
+++ b/CBApi.Tests/CBApi/framework/stubrequests/RetrieveASavedSearchStub.cs
@@ -0,0 +1,27 @@
+using CBApi;
+using CBApi.Framework.Requests;
+using RestSharp;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Tests.CBApi.models.service;
+
+namespace Tests.com.careerbuilder.CBApi.framework.stubrequests
+{
+ public class RetrieveASavedSearchStub:RetrieveASavedSearch
+ {
+ public RetrieveASavedSearchStub(string key, string domain, string cobrand, string siteid, int timeout, string savedSearchDID)
+ : base(new APISettings()
+ {
+ DevKey = key,
+ CobrandCode = cobrand,
+ SiteId = siteid,
+ TargetSite = new TargetSiteMock(domain),
+ TimeoutMS = timeout
+ }, savedSearchDID) { }
+
+ public IRestClient Client { get { return _client; } set { _client = value; } }
+ public IRestRequest Request { get { return _request; } set { _request = value; } }
+ }
+}
diff --git a/CBApi.Tests/CBApi/framework/stubrequests/SavedSearchCreateRequestStub.cs b/CBApi.Tests/CBApi/framework/stubrequests/SavedSearchCreateRequestStub.cs
new file mode 100644
index 0000000..cea3309
--- /dev/null
+++ b/CBApi.Tests/CBApi/framework/stubrequests/SavedSearchCreateRequestStub.cs
@@ -0,0 +1,19 @@
+using CBApi;
+using CBApi.Framework.Requests;
+using RestSharp;
+using Tests.CBApi.models.service;
+
+
+namespace Tests.CBApi.models.requests
+{
+ internal class SavedSearchCreateRequestStub :SavedSearchCreateRequest
+ {
+ public SavedSearchCreateRequestStub(string key, string domain, string cobrand, string siteid, int timeout)
+ : base(new APISettings() { DevKey = key, CobrandCode = cobrand, SiteId = siteid, TargetSite = new TargetSiteMock(domain), TimeoutMS = timeout })
+ {
+ }
+
+ public IRestClient Client { get { return _client; } set { _client = value; } }
+ public IRestRequest Request { get { return _request; } set { _request = value; } }
+ }
+}
diff --git a/CBApi.Tests/CBApi/framework/stubrequests/SavedSearchDeleteRequestStub.cs b/CBApi.Tests/CBApi/framework/stubrequests/SavedSearchDeleteRequestStub.cs
new file mode 100644
index 0000000..e616dc2
--- /dev/null
+++ b/CBApi.Tests/CBApi/framework/stubrequests/SavedSearchDeleteRequestStub.cs
@@ -0,0 +1,23 @@
+using CBApi;
+using CBApi.Framework.Requests;
+using RestSharp;
+using Tests.CBApi.models.service;
+
+namespace Tests.CBApi.models.requests {
+ internal class SavedSearchDeleteRequestStub : SavedSearchDeleteRequest {
+
+ public string DeveloperKey;
+ public SavedSearchDeleteRequestStub(string key, string domain, string cobrand, string siteid, int timeout)
+ : base(new APISettings() { DevKey = key, CobrandCode = cobrand, SiteId = siteid, TargetSite = new TargetSiteMock(domain), TimeoutMS = timeout }) {
+ }
+ public IRestClient Client {
+ get { return _client; }
+ set { _client = value; }
+ }
+
+ public IRestRequest Request {
+ get { return _request; }
+ set { _request = value; }
+ }
+ }
+}
diff --git a/CBApi.Tests/CBApi/framework/stubrequests/SavedSearchListRequestStub.cs b/CBApi.Tests/CBApi/framework/stubrequests/SavedSearchListRequestStub.cs
new file mode 100644
index 0000000..c5a90cb
--- /dev/null
+++ b/CBApi.Tests/CBApi/framework/stubrequests/SavedSearchListRequestStub.cs
@@ -0,0 +1,18 @@
+using CBApi;
+using CBApi.Framework.Requests;
+using RestSharp;
+using Tests.CBApi.models.service;
+
+namespace Tests.CBApi.models.requests
+{
+ class SavedSearchListRequestStub : SavedSearchListRequest
+ {
+ public SavedSearchListRequestStub(string key, string domain, string cobrand, string siteid, int timeout)
+ : base(new APISettings() { DevKey = key, CobrandCode = cobrand, SiteId = siteid, TargetSite = new TargetSiteMock(domain), TimeoutMS = timeout })
+ {
+ }
+
+ public IRestClient Client { get { return _client; } set { _client = value; } }
+ public IRestRequest Request { get { return _request; } set { _request = value; } }
+ }
+}
diff --git a/CBApi.Tests/CBApi/framework/stubrequests/SavedSearchRetrieveRequestStub.cs b/CBApi.Tests/CBApi/framework/stubrequests/SavedSearchRetrieveRequestStub.cs
new file mode 100644
index 0000000..32e886d
--- /dev/null
+++ b/CBApi.Tests/CBApi/framework/stubrequests/SavedSearchRetrieveRequestStub.cs
@@ -0,0 +1,18 @@
+using CBApi;
+using CBApi.Framework.Requests;
+using RestSharp;
+using Tests.CBApi.models.service;
+
+namespace Tests.CBApi.models.requests
+{
+ class SavedSearchRetrieveRequestStub:SavedSearchRetrieveRequest
+ {
+ public SavedSearchRetrieveRequestStub(string key, string domain, string cobrand, string siteid, int timeout)
+ : base(new APISettings() { DevKey = key, CobrandCode = cobrand, SiteId = siteid, TargetSite = new TargetSiteMock(domain), TimeoutMS = timeout })
+ {
+ }
+
+ public IRestClient Client { get { return _client; } set { _client = value; } }
+ public IRestRequest Request { get { return _request; } set { _request = value; } }
+ }
+}
diff --git a/CBApi.Tests/CBApi/framework/stubrequests/SavedSearchUpdateRequestStub.cs b/CBApi.Tests/CBApi/framework/stubrequests/SavedSearchUpdateRequestStub.cs
new file mode 100644
index 0000000..4000994
--- /dev/null
+++ b/CBApi.Tests/CBApi/framework/stubrequests/SavedSearchUpdateRequestStub.cs
@@ -0,0 +1,18 @@
+using CBApi;
+using CBApi.Framework.Requests;
+using RestSharp;
+using Tests.CBApi.models.service;
+
+namespace Tests.CBApi.models.requests
+{
+ class SavedSearchUpdateRequestStub : SavedSearchUpdateRequest
+ {
+ public SavedSearchUpdateRequestStub(string key, string domain, string cobrand, string siteid, int timeout)
+ : base(new APISettings() { DevKey = key, CobrandCode = cobrand, SiteId = siteid, TargetSite = new TargetSiteMock(domain), TimeoutMS = timeout })
+ {
+ }
+
+ public IRestClient Client { get { return _client; } set { _client = value; } }
+ public IRestRequest Request { get { return _request; } set { _request = value; } }
+ }
+}
diff --git a/CBApi.Tests/CBApi/framework/stubrequests/SubmitApplicationRequestStub.cs b/CBApi.Tests/CBApi/framework/stubrequests/SubmitApplicationRequestStub.cs
new file mode 100644
index 0000000..81b909a
--- /dev/null
+++ b/CBApi.Tests/CBApi/framework/stubrequests/SubmitApplicationRequestStub.cs
@@ -0,0 +1,22 @@
+using CBApi;
+using CBApi.Framework.Requests;
+using RestSharp;
+using Tests.CBApi.models.service;
+
+namespace Tests.CBApi.models.requests {
+ internal class SubmitApplicationRequestStub : SubmitApplicationRequest {
+
+ public SubmitApplicationRequestStub(string key, string domain, string cobrand, string siteid, int timeout)
+ : base(new APISettings() { DevKey = key, CobrandCode = cobrand, SiteId = siteid, TargetSite = new TargetSiteMock(domain),TimeoutMS = timeout }) {
+ }
+ public IRestClient Client {
+ get { return _client; }
+ set { _client = value; }
+ }
+
+ public IRestRequest Request {
+ get { return _request; }
+ set { _request = value; }
+ }
+ }
+}
diff --git a/CBApi.Tests/CBApi/framework/stubrequests/UserReqStub.cs b/CBApi.Tests/CBApi/framework/stubrequests/UserReqStub.cs
new file mode 100644
index 0000000..e5e4b46
--- /dev/null
+++ b/CBApi.Tests/CBApi/framework/stubrequests/UserReqStub.cs
@@ -0,0 +1,49 @@
+using System.Collections.Generic;
+using CBApi;
+using CBApi.Framework.Requests;
+using RestSharp;
+using Tests.CBApi.models.service;
+
+namespace Tests.CBApi.models.requests {
+ internal class UserReqStub : UserRecommendationsRequest {
+ public UserReqStub(string externalID, string key, string domain, string cobrand, string siteid)
+ : base(new ExternalID(externalID), new APISettings() { DevKey = key, CobrandCode = cobrand, SiteId = siteid, TargetSite = new TargetSiteMock(domain) }) {
+ }
+
+ public UserReqStub(List qsList, string key, string domain, string cobrand, string siteid)
+ : base(qsList, new APISettings() { DevKey = key, CobrandCode = cobrand, SiteId = siteid, TargetSite = new TargetSiteMock(domain) }) {
+ }
+
+ public string ExternalID {
+ get {
+ return this._QsParams.Find(x => x.GetType() == typeof(ExternalID)).value;
+ }
+ }
+
+ public string DevKey {
+ get { return _Settings.DevKey; }
+ }
+
+ public string Domain {
+ get { return _Settings.TargetSite.Domain; }
+ }
+
+ public string RequestURL {
+ get { return base.GetRequestURL(); }
+ }
+
+ public IRestClient Client {
+ get { return _client; }
+ set { _client = value; }
+ }
+
+ public IRestRequest Request {
+ get { return _request; }
+ set { _request = value; }
+ }
+
+ protected override void CheckForErrors(IRestResponse response) {
+
+ }
+ }
+}
diff --git a/Source/CBApi.Tests/Properties/AssemblyInfo.cs b/CBApi.Tests/Properties/AssemblyInfo.cs
similarity index 94%
rename from Source/CBApi.Tests/Properties/AssemblyInfo.cs
rename to CBApi.Tests/Properties/AssemblyInfo.cs
index b6c08be..65baa92 100644
--- a/Source/CBApi.Tests/Properties/AssemblyInfo.cs
+++ b/CBApi.Tests/Properties/AssemblyInfo.cs
@@ -1,10 +1,10 @@
using System.Reflection;
-using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
+
[assembly: AssemblyTitle("CBApi.Tests")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
@@ -17,9 +17,11 @@
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
+
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
+
[assembly: Guid("f47669ef-3596-42d8-8a0d-264db33135fc")]
// Version information for an assembly consists of the following four values:
@@ -31,5 +33,6 @@
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
+
[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
\ No newline at end of file
diff --git a/Source/CBApi.Tests/app.config b/CBApi.Tests/app.config
similarity index 100%
rename from Source/CBApi.Tests/app.config
rename to CBApi.Tests/app.config
diff --git a/CBApi.Tests/packages.config b/CBApi.Tests/packages.config
new file mode 100644
index 0000000..c011d0a
--- /dev/null
+++ b/CBApi.Tests/packages.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/CBApi.Tests/testdata/AnonymousApplicationRequestData.xml b/CBApi.Tests/testdata/AnonymousApplicationRequestData.xml
new file mode 100644
index 0000000..9a49021
--- /dev/null
+++ b/CBApi.Tests/testdata/AnonymousApplicationRequestData.xml
@@ -0,0 +1,45 @@
+
+ false
+ DevKey
+ US
+ JobDID
+ TNDID
+
+
+ ApplicantName
+ Freedom
+
+
+ ApplicantEmail
+ FreedomTacosCB@Live.com
+
+
+ Resume
+ no
+
+
+ 1189225
+ 2486710
+
+
+ 1193248
+ 2493730
+
+
+ 1475425
+ 350000
+
+
+ 1475428
+ 999999
+
+
+ 1616871
+ 3261961
+
+
+ 1616873
+ explosions
+
+
+
\ No newline at end of file
diff --git a/CBApi.Tests/testdata/AnonymousApplicationResponseData.xml b/CBApi.Tests/testdata/AnonymousApplicationResponseData.xml
new file mode 100644
index 0000000..8d58288
--- /dev/null
+++ b/CBApi.Tests/testdata/AnonymousApplicationResponseData.xml
@@ -0,0 +1,7 @@
+
+
+
+ 1/11/2011 1:11:11 PM
+ 4.0000000
+ Complete
+
\ No newline at end of file
diff --git a/CBApi.Tests/testdata/JsonResponseWrapper.json b/CBApi.Tests/testdata/JsonResponseWrapper.json
new file mode 100644
index 0000000..ceb4d9c
--- /dev/null
+++ b/CBApi.Tests/testdata/JsonResponseWrapper.json
@@ -0,0 +1,13 @@
+{
+ "TotalResults":1,
+ "ReturnedResults":1,
+ "Results":[
+ {
+ "Language":"Greek",
+ "Value":"GR"
+ }
+ ],
+ "Errors":[],
+ "Timestamp":"2015-06-10T14:56:37.3319476-04:00",
+ "Status":"Success"
+}
diff --git a/CBApi.Tests/testdata/RecommendJobResult.xml b/CBApi.Tests/testdata/RecommendJobResult.xml
new file mode 100644
index 0000000..fb3c863
--- /dev/null
+++ b/CBApi.Tests/testdata/RecommendJobResult.xml
@@ -0,0 +1,31 @@
+
+ JHT3D8649TV74ZNK0GJ
+ Fabrication - Assembly - Sheet Metal
+ 1
+
+ DE
+ Georgetown
+
+
+ Quality Staffing Services
+ www.qualitystaffing.com
+ CJ123_COMPANY_DID
+
+ http://api.careerbuilder.com/v1/joblink?DID=JHT3D8649TV74ZNK0GJ&DeveloperKey=XYZ_DEVKEY
+ http://api.careerbuilder.com/v1/job?DID=JHT3D8649TV74ZNK0GJ&DeveloperKey=XYZ_DEVKEY
+ http://www.careerbuilder.com/jobseeker/jobs/recommendedjobs.aspx?ipath=JELO&job_did=JHT3D8649TV74ZNK0GJ
+ 47-2211.00
+ Sheet Metal Workers
+ US
+ 12/9/2012 12:00:00 AM
+ True
+ CX
+ Not Specified
+
+ Full-Time
+ Not Specified
+ $20k - $30k/year
+
+ CanBulkApply
+
+
\ No newline at end of file
diff --git a/CBApi.Tests/testdata/ResponseBlankApplication.xml b/CBApi.Tests/testdata/ResponseBlankApplication.xml
new file mode 100644
index 0000000..d6c6b1c
--- /dev/null
+++ b/CBApi.Tests/testdata/ResponseBlankApplication.xml
@@ -0,0 +1,85 @@
+
+
+
+ 10/28/2012 10:19:01 PM
+ 0.0624004
+
+ http://api.careerbuilder.com/v1/application/submit
+ http://api.careerbuilder.com/v1/application/applylink?TrackingID=V8YDVG7V&JobDID=JHP3GR6135GF0QC5Q5B
+ JHP3GR6135GF0QC5Q5B
+ Field Service Technician
+
+
+ 2 Year Degree
+
+
+ Not Specified
+
+ At least 5 year(s)
+
+ Responsibilities of a <b>Service Technician</b>, under the guidance of the Field Service Manager include, but are not limited to:<br />
+ <br />
+ Performs quality service work on all vehicle wash equipment and accessories, including trouble shooting of electrical, electronic, and mechanical problems to provide customer satisfaction. <br />
+ <br />
+ Develops and maintains rapport with our customer base and partners with the customer to make beneficial recommendations regarding the technical maintenance of their state-of-the-art equipment.
+ <br />
+ <br />
+ Ensures all information is entered into Ryko's computer system per training specifications and follows all safety procedures and protocols according to Ryko's training curriculum. <br />
+ <br />
+ Technicians are trained on all aspects of the technical features of the equipment and will work with customers from installation, start-up, and ongoing maintenance to provide personalized service.
+ <br />
+ <p>Technicians' email, dispatching, timekeeping, recordkeeping, and billing functions are streamlined with the daily input and technical reference features provided by the company wireless laptop and industry-specific software. Ryko has also incorporated our safety program and training features on the laptop for easy access.<br />
+ <br />
+ Ryko was the first in our industry to attain ISO certification, therefore, Technicians are responsible for following all policies and procedures pertaining to Ryko’s Quality System. <br />
+ <br />
+ If you believe your skill set can meet the quality standards of our technical staff, please send your resume to: <a href="mailto:hr@ryko.com">hr@ryko.com</a> or fax to 515.986.7900. <br />
+ <br />
+ <br />
+ For additional information on our company, products and services - visit <a href="http://www.ryko.com">www.ryko.com</a> <br />
+ <br />
+ <hr>
+ <br />
+ <br />
+ <br />
+ <br />
+ <br />
+ <br />
+ <br />
+ <i>Careerbuilder Keywords:</i>car wash tech, service tech, service technician, field technician, tech, technician, field tech, installation tech, field rep, HVAC, mechanic, installer, repairman, auto technician, service specialist, millwright, millright
+ <p> </p>
+
+
+ 4
+ 3
+
+
+ ApplicantName
+ Basic
+ true
+ Text 50
+ Your name
+
+
+ ApplicantEmail
+ Basic
+ true
+ Text 50
+ Your email
+
+
+ Resume
+ Basic
+ true
+ Text 5000
+ Your resume
+
+
+ CoverLetter
+ Basic
+ false
+ Text 5000
+ Your cover letter
+
+
+
+
\ No newline at end of file
diff --git a/CBApi.Tests/testdata/ResponseJobSearch.xml b/CBApi.Tests/testdata/ResponseJobSearch.xml
new file mode 100644
index 0000000..4dde111
--- /dev/null
+++ b/CBApi.Tests/testdata/ResponseJobSearch.xml
@@ -0,0 +1,744 @@
+
+
+
+ 10/28/2012 8:53:37 PM
+ 0.3900025
+ 15447
+ 386163
+ 1
+ 25
+
+
+ Direct Sales Recruiting, LLC
+ c35x165rs82x1bnbbc
+ http://www.careerbuilder.com/Jobs/Company/C35X165RS82X1BNBBC/Direct-Sales-Recruiting-LLC/?sc_cmp1=13_JobRes_ComDet
+ JHM0LH6LPCGLF3FR3ZB
+ 41-4011.00
+ Mobile Heavy Equipment Mechanics
+ Medical Sales Reps: BiologicsTarget Hospital, Clinics & Long Term Care Facilities Seeking Top Ranked, Well Documented Medical Sales Reps My client...
+ Mars
+
+ Full-Time
+ High School Diploma
+ Not Specified
+ http://api.careerbuilder.com/v1/joblink?TrackingID=DLR0T71H&DID=JHM0LH6LPCGLF3FR3ZB
+ http://api.careerbuilder.com/v1/job?DID=JHM0LH6LPCGLF3FR3ZB&DeveloperKey=WXXXXXXXXXXXXXXXXXX
+ TN - Chattanooga
+ 35.04644
+ -85.30946
+ 10/28/2012
+ 5/15/2014 7:19:36 AM
+ $70k - $80k/year
+ http://www.careerbuilder.com/jobseeker/jobs/recommendedjobs.aspx?ipath=JELO&job_did=JHM0LH6LPCGLF3FR3ZB
+ Medical Sales-Tissue Graft/Biologics-Wound Care
+ http://emj.icbdr.com/MediaManagement/QS/I8F50C63D7B6SGPDXQS.gif
+ 1895 Tully Rd
+ Suite 187
+
+
+ Direct Sales Recruiting, LLC
+ c35x165rs82x1bnbbc
+ http://www.careerbuilder.com/Jobs/Company/C35X165RS82X1BNBBC/Direct-Sales-Recruiting-LLC/?sc_cmp1=13_JobRes_ComDet
+ JHL0BT77JF3QS95L0S0
+ 41-3011.00
+ Mobile Heavy Equipment Mechanics
+ Media & Online Interactive Sales Consultants - Inside Sales Account Executives Needed Work for A Leading Client ~Fortune 30 Company Year 1 $50,...
+
+ Full-Time
+ High School Diploma
+ Not Specified
+ http://api.careerbuilder.com/v1/joblink?TrackingID=DLR0T71H&DID=JHL0BT77JF3QS95L0S0
+ http://api.careerbuilder.com/v1/job?DID=JHL0BT77JF3QS95L0S0&DeveloperKey=WXXXXXXXXXXXXXXXXXX
+ NC - Charlotte
+ 35.227
+ -80.843
+ 10/28/2012
+ 5/15/2014 7:19:36 AM
+ $30k/year
+ http://www.careerbuilder.com/jobseeker/jobs/recommendedjobs.aspx?ipath=JELO&job_did=JHL0BT77JF3QS95L0S0
+ Inside Sales-Digital, Online, Mobile & Social Media
+ http://emj.icbdr.com/MediaManagement/QS/I8F50C63D7B6SGPDXQS.gif
+
+ microsoft excel
+ microsoft office
+ 3gpp long term evolution
+ 4g
+
+
+
+ Direct Sales Recruiting, LLC
+ c35x165rs82x1bnbbc
+ http://www.careerbuilder.com/Jobs/Company/C35X165RS82X1BNBBC/Direct-Sales-Recruiting-LLC/?sc_cmp1=13_JobRes_ComDet
+ JHL6BK6RZC2S3J4MW76
+ 41-1012.00
+ Mobile Heavy Equipment Mechanics
+ Inside Sales - Tele Sales Manager Work for an Upcoming Industry Leader in Reward Programs! Work Hard, Play Hard is their Motto! Be part of the...
+
+ Full-Time
+ High School Diploma
+ Not Specified
+ http://api.careerbuilder.com/v1/joblink?TrackingID=DLR0T71H&DID=JHL6BK6RZC2S3J4MW76
+ http://api.careerbuilder.com/v1/job?DID=JHL6BK6RZC2S3J4MW76&DeveloperKey=WXXXXXXXXXXXXXXXXXX
+ TX - Dallas
+ 32.77815
+ -96.7954
+ 10/28/2012
+ 5/15/2014 7:19:36 AM
+ $50k/year
+ http://www.careerbuilder.com/jobseeker/jobs/recommendedjobs.aspx?ipath=JELO&job_did=JHL6BK6RZC2S3J4MW76
+ Tele-Sales Manager- BTB Rewards, Bars, Restaurants, SMBs
+ http://emj.icbdr.com/MediaManagement/QS/I8F50C63D7B6SGPDXQS.gif
+
+
+ Ryko Solutions, Inc.
+
+
+ JHP3GR6135GF0QC5Q5B
+ 49-9042.00
+ Mobile Heavy Equipment Mechanics
+ Are you a self-starter who enjoys working independently within a team environment? Do you enjoy interacting with a variety of customers and derive...
+
+ Full-Time
+ High School Diploma
+ Not Specified
+ http://api.careerbuilder.com/v1/joblink?TrackingID=DLR0T71H&DID=JHP3GR6135GF0QC5Q5B
+ http://api.careerbuilder.com/v1/job?DID=JHP3GR6135GF0QC5Q5B&DeveloperKey=WXXXXXXXXXXXXXXXXXX
+ NY - Syracuse
+ 43.04999
+ -76.14739
+ 10/28/2012
+ 5/15/2014 7:19:36 AM
+ N/A
+ http://www.careerbuilder.com/jobseeker/jobs/recommendedjobs.aspx?ipath=JELO&job_did=JHP3GR6135GF0QC5Q5B
+ Field Service Technician
+
+
+
+ BNSF Railway
+ c389m6hj1cxh45748n
+ http://www.careerbuilder.com/Jobs/Company/C389M6HJ1CXH45748N/BNSF-Railway/?sc_cmp1=13_JobRes_ComDet
+ J3J1986DQ5ZZRHTFSSR
+ 47-4061.00
+ BNSF Railway operates one of the nation’s largest rail networks, with approximately 32,000 route miles in 28 states across the western two-thirds of...
+
+ Full-Time
+ High School Diploma
+ Not Specified
+ http://api.careerbuilder.com/v1/joblink?TrackingID=DLR0T71H&DID=J3J1986DQ5ZZRHTFSSR
+ http://api.careerbuilder.com/v1/job?DID=J3J1986DQ5ZZRHTFSSR&DeveloperKey=WXXXXXXXXXXXXXXXXXX
+ SD - Aberdeen
+ 45.4755
+ -98.5387
+ 10/28/2012
+ 5/15/2014 7:19:36 AM
+ N/A
+ http://www.careerbuilder.com/jobseeker/jobs/recommendedjobs.aspx?ipath=JELO&job_did=J3J1986DQ5ZZRHTFSSR
+ Track Maintenance (Laborer)
+ http://emj.icbdr.com/MediaManagement/S7/INA0CS6NKDDCB2MKSS7.gif
+
+ microsoft excel
+ microsoft office
+ 3gpp long term evolution
+ 4g
+
+
+
+ CT Transportation, LLC
+
+
+ JHL0KD62H1B6XX83R9B
+ 53-3032.00
+ Mobile Heavy Equipment Mechanics
+ CDL A TRUCK DRIVERS GET CONNECTED TO A CT TRUCK DRIVING CAREER! Regional Operating Terminal in MOCKSVILLE, NC ****GURANTEED WEEKEND HOME TIME...
+
+ Full-Time
+ High School Diploma
+ Not Specified
+ http://api.careerbuilder.com/v1/joblink?TrackingID=DLR0T71H&DID=JHL0KD62H1B6XX83R9B
+ http://api.careerbuilder.com/v1/job?DID=JHL0KD62H1B6XX83R9B&DeveloperKey=WXXXXXXXXXXXXXXXXXX
+ NC - Mocksville
+ 35.9339
+ -80.5455
+ 10/28/2012
+ 5/15/2014 7:19:36 AM
+ $35k - $44,800/year
+ http://www.careerbuilder.com/jobseeker/jobs/recommendedjobs.aspx?ipath=JELO&job_did=JHL0KD62H1B6XX83R9B
+ CDL A FLAT BED TRUCK DRIVER JOB
+
+
+ microsoft excel
+ microsoft office
+ 3gpp long term evolution
+ 4g
+
+
+
+ U. S. Silica Company
+ chl2jj776pc06hry39g
+ http://www.careerbuilder.com/Jobs/Company/CHL2JJ776PC06HRY39G/U-S-Silica-Company/?sc_cmp1=13_JobRes_ComDet
+ JHS3B465TJ4K7FWZ1FK
+ 15-1071.00
+ Mobile Heavy Equipment Mechanics
+ The Customer Relationship Management (CRM) System Administrator will report directly to the Director of Supply Chain Planning. The CRM System...
+
+ Full-Time
+ High School Diploma
+ Not Specified
+ http://api.careerbuilder.com/v1/joblink?TrackingID=DLR0T71H&DID=JHS3B465TJ4K7FWZ1FK
+ http://api.careerbuilder.com/v1/job?DID=JHS3B465TJ4K7FWZ1FK&DeveloperKey=WXXXXXXXXXXXXXXXXXX
+ MD - Frederick
+ 39.4393
+ -77.3428
+ 10/28/2012
+ 5/15/2014 7:19:36 AM
+ N/A
+ http://www.careerbuilder.com/jobseeker/jobs/recommendedjobs.aspx?ipath=JELO&job_did=JHS3B465TJ4K7FWZ1FK
+ Customer Relationship Management System Administrator
+ http://emj.icbdr.com/MediaManagement/P3/MRC3L662531CTWPXHP3.jpg
+
+ microsoft excel
+ microsoft office
+ 3gpp long term evolution
+ 4g
+
+
+
+ Nielsen
+ c35hg6g3lj1n2l5sch
+ http://www.careerbuilder.com/Jobs/Company/C35HG6G3LJ1N2L5SCH/Nielsen/?sc_cmp1=13_JobRes_ComDet
+ J3F45279FJQFBLJMGK9
+ 19-3021.00
+ Mobile Heavy Equipment Mechanics
+ Do you know what consumers buy? What consumers watch? Nielsen Knows! Nielsen is the world’s leading marketing and media information company. We’re...
+
+ Full-Time
+ High School Diploma
+ Not Specified
+ http://api.careerbuilder.com/v1/joblink?TrackingID=DLR0T71H&DID=J3F45279FJQFBLJMGK9
+ http://api.careerbuilder.com/v1/job?DID=J3F45279FJQFBLJMGK9&DeveloperKey=WXXXXXXXXXXXXXXXXXX
+ MI - Grand Rapids
+ 42.9663
+ -85.6552
+ 10/28/2012
+ 5/15/2014 7:19:36 AM
+ N/A
+ http://www.careerbuilder.com/jobseeker/jobs/recommendedjobs.aspx?ipath=JELO&job_did=J3F45279FJQFBLJMGK9
+ Retail Associate Client Manager
+ http://emj.icbdr.com/MediaManagement/8V/I8H3HX5WMZFMP71HG8V.gif
+
+ microsoft excel
+ microsoft office
+ 3gpp long term evolution
+ 4g
+
+
+
+ Nielsen
+ c35hg6g3lj1n2l5sch
+ http://www.careerbuilder.com/Jobs/Company/C35HG6G3LJ1N2L5SCH/Nielsen/?sc_cmp1=13_JobRes_ComDet
+ J3F3BD72N1GCJ9RCPG3
+ 11-2022.00
+ Mobile Heavy Equipment Mechanics
+ Do you know what consumers buy? What consumers watch? Nielsen Knows! Nielsen is the world’s leading marketing and media information company. We’re...
+
+ Full-Time
+ High School Diploma
+ Not Specified
+ http://api.careerbuilder.com/v1/joblink?TrackingID=DLR0T71H&DID=J3F3BD72N1GCJ9RCPG3
+ http://api.careerbuilder.com/v1/job?DID=J3F3BD72N1GCJ9RCPG3&DeveloperKey=WXXXXXXXXXXXXXXXXXX
+ AR - Bentonville
+ 36.3232
+ -94.2666
+ 10/28/2012
+ 5/15/2014 7:19:36 AM
+ N/A
+ http://www.careerbuilder.com/jobseeker/jobs/recommendedjobs.aspx?ipath=JELO&job_did=J3F3BD72N1GCJ9RCPG3
+ Retail Associate Client Director
+ http://emj.icbdr.com/MediaManagement/8V/I8H3HX5WMZFMP71HG8V.gif
+
+ microsoft excel
+ microsoft office
+ 3gpp long term evolution
+ 4g
+
+
+
+ Core Medical Group
+ cq243765rplpztr76hq
+ http://www.careerbuilder.com/Jobs/Company/CQ243765RPLPZTR76HQ/Core-Medical-Group/?sc_cmp1=13_JobRes_ComDet
+ JHL69Q6BXSM1C7FB1ZM
+ 29-1111.00
+ Mobile Heavy Equipment Mechanics
+ Nurse Manager - Endoscopy / Outpatient / PACU This is a fantastic opportunity for a motivated and experienced Manager or Supervisor to work for a...
+
+ Full-Time
+ High School Diploma
+ Not Specified
+ http://api.careerbuilder.com/v1/joblink?TrackingID=DLR0T71H&DID=JHL69Q6BXSM1C7FB1ZM
+ http://api.careerbuilder.com/v1/job?DID=JHL69Q6BXSM1C7FB1ZM&DeveloperKey=WXXXXXXXXXXXXXXXXXX
+ TX - Dallas
+ 32.77815
+ -96.7954
+ 10/28/2012
+ 5/15/2014 7:19:36 AM
+ N/A
+ http://www.careerbuilder.com/jobseeker/jobs/recommendedjobs.aspx?ipath=JELO&job_did=JHL69Q6BXSM1C7FB1ZM
+ Nurse Manager - Endoscopy / Outpatient / PACU
+ http://emj.icbdr.com/MediaManagement/LS/IN61646M0D04PL7XNLS.gif
+
+ microsoft excel
+ microsoft office
+ 3gpp long term evolution
+ 4g
+
+
+
+ Recon Inc.
+
+
+ JHL7CY6MJHJBS2JC16S
+ 13-1051.00
+ Mobile Heavy Equipment Mechanics
+ Metro Phoenix large-scale specialty landscape/ heavy civil/ reclamation/ erosion control contractor with projects throughout the Southwestern United...
+
+ Full-Time
+ High School Diploma
+ Not Specified
+ http://api.careerbuilder.com/v1/joblink?TrackingID=DLR0T71H&DID=JHL7CY6MJHJBS2JC16S
+ http://api.careerbuilder.com/v1/job?DID=JHL7CY6MJHJBS2JC16S&DeveloperKey=WXXXXXXXXXXXXXXXXXX
+ AZ - Phoenix
+ 33.4044
+ -112.028
+ 10/28/2012
+ 5/15/2014 7:19:36 AM
+ N/A
+ http://www.careerbuilder.com/jobseeker/jobs/recommendedjobs.aspx?ipath=JELO&job_did=JHL7CY6MJHJBS2JC16S
+ Construction Estimator
+
+
+ microsoft excel
+ microsoft office
+ 3gpp long term evolution
+ 4g
+
+
+
+ Aerotek
+ c7h8dq6z0khhhp0r05n
+ http://www.careerbuilder.com/Jobs/Company/C7H8DQ6Z0KHHHP0R05N/Aerotek/?sc_cmp1=13_JobRes_ComDet
+ J3G7VP76NLN7M7D271W
+ 43-5071.00
+ Job Classification: Contract A mid size warehouse in S. Seattle is looking to hire 15 seasonal hires to help package light weight boxes for a month...
+
+ Full-Time
+ High School Diploma
+ Not Specified
+ http://api.careerbuilder.com/v1/joblink?TrackingID=DLR0T71H&DID=J3G7VP76NLN7M7D271W
+ http://api.careerbuilder.com/v1/job?DID=J3G7VP76NLN7M7D271W&DeveloperKey=WXXXXXXXXXXXXXXXXXX
+ WA - Seattle
+ 47.6157
+ -122.3445
+ Mobile Heavy Equipment Mechanics
+ 10/28/2012
+ 5/15/2014 7:19:36 AM
+ $12.50/hour
+ http://www.careerbuilder.com/jobseeker/jobs/recommendedjobs.aspx?ipath=JELO&job_did=J3G7VP76NLN7M7D271W
+ Seasonal Shipping Clerk
+ http://emj.icbdr.com/MediaManagement/TS/MFT1YN6QZ5HQ4NR0XTS.gif
+
+ microsoft excel
+ microsoft office
+ 3gpp long term evolution
+ 4g
+
+
+
+ Zebra Technologies
+ c8b6dq66lqmblplg4hl
+ http://www.careerbuilder.com/Jobs/Company/C8B6DQ66LQMBLPLG4HL/Zebra-Technologies/?sc_cmp1=13_JobRes_ComDet
+ J3F3846V2MHRHN4FYP0
+ 43-3031.00
+ Mobile Heavy Equipment Mechanics
+ The Accounts Payable Specialist is responsible for processing invoices, check requests, expense reports, and check runs in a timely and accurate...
+
+ Full-Time
+ High School Diploma
+ Not Specified
+ http://api.careerbuilder.com/v1/joblink?TrackingID=DLR0T71H&DID=J3F3846V2MHRHN4FYP0
+ http://api.careerbuilder.com/v1/job?DID=J3F3846V2MHRHN4FYP0&DeveloperKey=WXXXXXXXXXXXXXXXXXX
+ IL - Lincolnshire
+ 42.1941
+ -87.9317
+ 10/28/2012
+ 5/15/2014 7:19:36 AM
+ N/A
+ http://www.careerbuilder.com/jobseeker/jobs/recommendedjobs.aspx?ipath=JELO&job_did=J3F3846V2MHRHN4FYP0
+ Accounts Payable Specialist
+ http://emj.icbdr.com/MediaManagement/N8/MRJ6PQ6N0H54LJYX8N8.jpg
+
+ microsoft excel
+ microsoft office
+ 3gpp long term evolution
+ 4g
+
+
+
+ confidential
+
+
+ JHM5YC70N9CBHM4C4YC
+ 43-9061.00
+ Accounting/ Office Support Clerk ... you won't be stuck behind a desk in this busy Chicago logistics company! Accounting/ Office Support Clerk will...
+
+ Full-Time
+ High School Diploma
+ Not Specified
+ http://api.careerbuilder.com/v1/joblink?TrackingID=DLR0T71H&DID=JHM5YC70N9CBHM4C4YC
+ http://api.careerbuilder.com/v1/job?DID=JHM5YC70N9CBHM4C4YC&DeveloperKey=WXXXXXXXXXXXXXXXXXX
+ IL - Chicago
+ 41.88415
+ -87.63241
+ 10/28/2012
+ 5/15/2014 7:19:36 AM
+ N/A
+ http://www.careerbuilder.com/jobseeker/jobs/recommendedjobs.aspx?ipath=JELO&job_did=JHM5YC70N9CBHM4C4YC
+ Accounting/ Office Support Clerk ... Up To $11/Hour
+
+
+ microsoft excel
+ microsoft office
+ 3gpp long term evolution
+ 4g
+
+
+
+ RCM Technologies
+ c8f1z86sswblbd1z96l
+ http://www.careerbuilder.com/Jobs/Company/C8F1Z86SSWBLBD1Z96L/RCM-Technologies/?sc_cmp1=13_JobRes_ComDet
+ JHV3D46LXDLJDR2S36H
+ 51-2022.00
+ Mobile Heavy Equipment Mechanics
+ Electrical Assembler: Job duties will include routing wires, assembles, and installs electrical and electronic components, such as main junction and...
+
+ Full-Time
+ High School Diploma
+ Not Specified
+ http://api.careerbuilder.com/v1/joblink?TrackingID=DLR0T71H&DID=JHV3D46LXDLJDR2S36H
+ http://api.careerbuilder.com/v1/job?DID=JHV3D46LXDLJDR2S36H&DeveloperKey=WXXXXXXXXXXXXXXXXXX
+ WI - Elm Grove
+ 43.0481
+ -88.0869
+ 10/28/2012
+ 5/15/2014 7:19:36 AM
+ N/A
+ http://www.careerbuilder.com/jobseeker/jobs/recommendedjobs.aspx?ipath=JELO&job_did=JHV3D46LXDLJDR2S36H
+ Electrical Assembler
+ http://emj.icbdr.com/MediaManagement/CV/I8B3V15X3W1703Y0BCV.gif
+
+ microsoft excel
+ microsoft office
+ 3gpp long term evolution
+ 4g
+
+
+
+ Creative Financial Staffing - Chicago
+ c7c46f764lfdyf1v3yg
+ http://www.careerbuilder.com/Jobs/Company/C7C46F764LFDYF1V3YG/Creative-Financial-Staffing-Chicago/?sc_cmp1=13_JobRes_ComDet
+ JHV4KJ6CCG4LSLG9TW2
+ 13-2011.01
+ Mobile Heavy Equipment Mechanics
+ Our client a strongly performing company is seeking a Manager of SEC reporting. This is an exciting opportunity to join a company that went public...
+
+ Full-Time
+ High School Diploma
+ Not Specified
+ http://api.careerbuilder.com/v1/joblink?TrackingID=DLR0T71H&DID=JHV4KJ6CCG4LSLG9TW2
+ http://api.careerbuilder.com/v1/job?DID=JHV4KJ6CCG4LSLG9TW2&DeveloperKey=WXXXXXXXXXXXXXXXXXX
+ IL - Chicago
+ 41.8818
+ -87.6367
+ 10/28/2012
+ 5/15/2014 7:19:36 AM
+ N/A
+ http://www.careerbuilder.com/jobseeker/jobs/recommendedjobs.aspx?ipath=JELO&job_did=JHV4KJ6CCG4LSLG9TW2
+ Manager of SEC Reporting
+ http://emj.icbdr.com/MediaManagement/4F/I8F1F16HW3L44NKYY4F.gif
+
+ microsoft excel
+ microsoft office
+ 3gpp long term evolution
+ 4g
+
+
+
+ Creative Financial Staffing - Chicago
+ c7c46f764lfdyf1v3yg
+ http://www.careerbuilder.com/Jobs/Company/C7C46F764LFDYF1V3YG/Creative-Financial-Staffing-Chicago/?sc_cmp1=13_JobRes_ComDet
+ JHS7R366H3WYGHJXGD1
+ 13-2011.01
+ Mobile Heavy Equipment Mechanics
+ Our client, a publicly traded company with revenues in the billions, is moving their office to the loop in Chicago. This is an exciting opportunity to...
+
+ Full-Time
+ High School Diploma
+ Not Specified
+ http://api.careerbuilder.com/v1/joblink?TrackingID=DLR0T71H&DID=JHS7R366H3WYGHJXGD1
+ http://api.careerbuilder.com/v1/job?DID=JHS7R366H3WYGHJXGD1&DeveloperKey=WXXXXXXXXXXXXXXXXXX
+ IL - Chicago
+ 41.8858
+ -87.6229
+ 10/28/2012
+ 5/15/2014 7:19:36 AM
+ N/A
+ http://www.careerbuilder.com/jobseeker/jobs/recommendedjobs.aspx?ipath=JELO&job_did=JHS7R366H3WYGHJXGD1
+ Senior Accountant
+ http://emj.icbdr.com/MediaManagement/4F/I8F1F16HW3L44NKYY4F.gif
+
+ microsoft excel
+ microsoft office
+ 3gpp long term evolution
+ 4g
+
+
+
+ Creative Financial Staffing - Chicago
+ c7c46f764lfdyf1v3yg
+ http://www.careerbuilder.com/Jobs/Company/C7C46F764LFDYF1V3YG/Creative-Financial-Staffing-Chicago/?sc_cmp1=13_JobRes_ComDet
+ JHT4VX6ST1S9RHFV0RD
+ 13-2011.01
+ Mobile Heavy Equipment Mechanics
+ Our client a Fortune 500 company with headquarters in Chicago, is seeking a Senior Financial Analyst. This is a phenomenal opportunity to work for a...
+
+ Full-Time
+ High School Diploma
+ Not Specified
+ http://api.careerbuilder.com/v1/joblink?TrackingID=DLR0T71H&DID=JHT4VX6ST1S9RHFV0RD
+ http://api.careerbuilder.com/v1/job?DID=JHT4VX6ST1S9RHFV0RD&DeveloperKey=WXXXXXXXXXXXXXXXXXX
+ IL - Chicago
+ 41.8805
+ -87.6247
+ 10/28/2012
+ 5/15/2014 7:19:36 AM
+ N/A
+ http://www.careerbuilder.com/jobseeker/jobs/recommendedjobs.aspx?ipath=JELO&job_did=JHT4VX6ST1S9RHFV0RD
+ Senior Financial Analyst
+ http://emj.icbdr.com/MediaManagement/4F/I8F1F16HW3L44NKYY4F.gif
+
+ microsoft excel
+ microsoft office
+ 3gpp long term evolution
+ 4g
+
+
+
+ Creative Financial Staffing - Chicago
+ c7c46f764lfdyf1v3yg
+ http://www.careerbuilder.com/Jobs/Company/C7C46F764LFDYF1V3YG/Creative-Financial-Staffing-Chicago/?sc_cmp1=13_JobRes_ComDet
+ JHR6746W906Z56ZSP51
+ 13-2011.02
+ Our client, a large company in the healthcare industry, is seeking a Sr Auditor. This is an exciting opportunity that offers total work life balance....
+
+ Full-Time
+ High School Diploma
+ Not Specified
+ http://api.careerbuilder.com/v1/joblink?TrackingID=DLR0T71H&DID=JHR6746W906Z56ZSP51
+ http://api.careerbuilder.com/v1/job?DID=JHR6746W906Z56ZSP51&DeveloperKey=WXXXXXXXXXXXXXXXXXX
+ IL - Chicago
+ 41.8818
+ -87.6367
+ 10/28/2012
+ 5/15/2014 7:19:36 AM
+ N/A
+ http://www.careerbuilder.com/jobseeker/jobs/recommendedjobs.aspx?ipath=JELO&job_did=JHR6746W906Z56ZSP51
+ SENIOR INTERNAL AUDITOR
+ http://emj.icbdr.com/MediaManagement/4F/I8F1F16HW3L44NKYY4F.gif
+
+ microsoft excel
+ microsoft office
+ 3gpp long term evolution
+ 4g
+
+
+
+ Creative Financial Staffing
+ c8c09365rrttn0kqzvh
+ http://www.careerbuilder.com/Jobs/Company/C8C09365RRTTN0KQZVH/Creative-Financial-Staffing/?sc_cmp1=13_JobRes_ComDet
+ JB75M073PW2M7H96YJD
+ 13-2011.01
+ Mobile Heavy Equipment Mechanics
+ Our client, a professional services firm located in Northbrook, IL, is looking to hire a Senior Financial Accountant within their Financial Reporting...
+
+ Full-Time
+ High School Diploma
+ Not Specified
+ http://api.careerbuilder.com/v1/joblink?TrackingID=DLR0T71H&DID=JB75M073PW2M7H96YJD
+ http://api.careerbuilder.com/v1/job?DID=JB75M073PW2M7H96YJD&DeveloperKey=WXXXXXXXXXXXXXXXXXX
+ IL - Northbrook
+ 42.12972
+ -87.83156
+ 10/28/2012
+ 5/15/2014 7:19:36 AM
+ N/A
+ http://www.careerbuilder.com/jobseeker/jobs/recommendedjobs.aspx?ipath=JELO&job_did=JB75M073PW2M7H96YJD
+ SENIOR FINANCIAL ACCOUNTANT
+ http://emj.icbdr.com/MediaManagement/7T/IN85CX7914S6B30127T.gif
+
+ microsoft excel
+ microsoft office
+ 3gpp long term evolution
+ 4g
+
+
+
+ Creative Financial Staffing
+ c8c09365rrttn0kqzvh
+ http://www.careerbuilder.com/Jobs/Company/C8C09365RRTTN0KQZVH/Creative-Financial-Staffing/?sc_cmp1=13_JobRes_ComDet
+ JB70NV6JV69MZQCFKNH
+ 13-2011.01
+ Mobile Heavy Equipment Mechanics
+ Our client, a professional services firm located in Northbrook, IL, is looking to hire a Senior Financial Accountant within their Financial Reporting...
+
+ Full-Time
+ High School Diploma
+ Not Specified
+ http://api.careerbuilder.com/v1/joblink?TrackingID=DLR0T71H&DID=JB70NV6JV69MZQCFKNH
+ http://api.careerbuilder.com/v1/job?DID=JB70NV6JV69MZQCFKNH&DeveloperKey=WXXXXXXXXXXXXXXXXXX
+ IL - Northbrook
+ 42.12972
+ -87.83156
+ 10/28/2012
+ 5/15/2014 7:19:36 AM
+ N/A
+ http://www.careerbuilder.com/jobseeker/jobs/recommendedjobs.aspx?ipath=JELO&job_did=JB70NV6JV69MZQCFKNH
+ SENIOR FINANCIAL ACCOUNTANT
+ http://emj.icbdr.com/MediaManagement/7T/IN85CX7914S6B30127T.gif
+
+ microsoft excel
+ microsoft office
+ 3gpp long term evolution
+ 4g
+
+
+
+ Creative Financial Staffing - Chicago
+ c7c46f764lfdyf1v3yg
+ http://www.careerbuilder.com/Jobs/Company/C7C46F764LFDYF1V3YG/Creative-Financial-Staffing-Chicago/?sc_cmp1=13_JobRes_ComDet
+ JHP7L36QD8W93YVQHSD
+ 13-2011.02
+ Mobile Heavy Equipment Mechanics
+ Our client, a Fortune 500 company in Chicago is seeking a Team lead Auditor. This is an exciting opportunity that is rotational in nature. This person...
+
+ Full-Time
+ High School Diploma
+ Not Specified
+ http://api.careerbuilder.com/v1/joblink?TrackingID=DLR0T71H&DID=JHP7L36QD8W93YVQHSD
+ http://api.careerbuilder.com/v1/job?DID=JHP7L36QD8W93YVQHSD&DeveloperKey=WXXXXXXXXXXXXXXXXXX
+ IL - Chicago
+ 41.8858
+ -87.6229
+ 10/28/2012
+ 5/15/2014 7:19:36 AM
+ N/A
+ http://www.careerbuilder.com/jobseeker/jobs/recommendedjobs.aspx?ipath=JELO&job_did=JHP7L36QD8W93YVQHSD
+ LEAD INTERNAL AUDITOR
+ http://emj.icbdr.com/MediaManagement/4F/I8F1F16HW3L44NKYY4F.gif
+
+ microsoft excel
+ microsoft office
+ 3gpp long term evolution
+ 4g
+
+
+
+ Creative Financial Staffing - Chicago
+ c7c46f764lfdyf1v3yg
+ http://www.careerbuilder.com/Jobs/Company/C7C46F764LFDYF1V3YG/Creative-Financial-Staffing-Chicago/?sc_cmp1=13_JobRes_ComDet
+ JHM0976ZHCNBZZ0H2JK
+ 11-3031.01
+ Mobile Heavy Equipment Mechanics
+ We are currently seeking candidates for one of our top clients in the Chicago Market-place for a newly created role of Manager FP &A. Our client has...
+
+ Full-Time
+ High School Diploma
+ Not Specified
+ http://api.careerbuilder.com/v1/joblink?TrackingID=DLR0T71H&DID=JHM0976ZHCNBZZ0H2JK
+ http://api.careerbuilder.com/v1/job?DID=JHM0976ZHCNBZZ0H2JK&DeveloperKey=WXXXXXXXXXXXXXXXXXX
+ IL - Schaumburg
+ 42.0253
+ -88.06771
+ 10/28/2012
+ 5/15/2014 7:19:36 AM
+ N/A
+ http://www.careerbuilder.com/jobseeker/jobs/recommendedjobs.aspx?ipath=JELO&job_did=JHM0976ZHCNBZZ0H2JK
+ Manager of Financial Planning & Analysis
+ http://emj.icbdr.com/MediaManagement/4F/I8F1F16HW3L44NKYY4F.gif
+
+ microsoft excel
+ microsoft office
+ 3gpp long term evolution
+ 4g
+
+
+
+
+
+
+ J8A76V68XV3TC4SYB11
+ 13-2011.01
+ Mobile Heavy Equipment Mechanics
+ Our client is a growing organization and quickly becoming a leader in their industry and are currently seeking a Senior Accountant to add to their...
+
+ Full-Time
+ High School Diploma
+ Not Specified
+ http://api.careerbuilder.com/v1/joblink?TrackingID=DLR0T71H&DID=J8A76V68XV3TC4SYB11
+ http://api.careerbuilder.com/v1/job?DID=J8A76V68XV3TC4SYB11&DeveloperKey=WXXXXXXXXXXXXXXXXXX
+ IL - Barrington
+ 42.1512
+ -88.1636
+ 10/28/2012
+ 5/15/2014 7:19:36 AM
+ N/A
+ http://www.careerbuilder.com/jobseeker/jobs/recommendedjobs.aspx?ipath=JELO&job_did=J8A76V68XV3TC4SYB11
+ Senior Accountant
+
+
+ microsoft excel
+ microsoft office
+ 3gpp long term evolution
+ 4g
+
+
+
+ Creative Financial Staffing
+ c8c09365rrttn0kqzvh
+ http://www.careerbuilder.com/Jobs/Company/C8C09365RRTTN0KQZVH/Creative-Financial-Staffing/?sc_cmp1=13_JobRes_ComDet
+ J8A4S76B8DKVW2MDMDX
+ 13-2011.01
+ Mobile Heavy Equipment Mechanics
+ Our client, a professional services firm located in Northbrook, IL, is looking to hire a Senior Financial Accountant within their Financial Reporting...
+
+ Full-Time
+ High School Diploma
+ Not Specified
+ http://api.careerbuilder.com/v1/joblink?TrackingID=DLR0T71H&DID=J8A4S76B8DKVW2MDMDX
+ http://api.careerbuilder.com/v1/job?DID=J8A4S76B8DKVW2MDMDX&DeveloperKey=WXXXXXXXXXXXXXXXXXX
+ IL - Northbrook
+ 42.1255
+ -87.8406
+ 10/28/2012
+ 5/15/2014 7:19:36 AM
+ N/A
+ http://www.careerbuilder.com/jobseeker/jobs/recommendedjobs.aspx?ipath=JELO&job_did=J8A4S76B8DKVW2MDMDX
+ Senior Financial Accountant
+ http://emj.icbdr.com/MediaManagement/7T/IN85CX7914S6B30127T.gif
+
+ microsoft excel
+ microsoft office
+ 3gpp long term evolution
+ 4g
+
+
+
+
\ No newline at end of file
diff --git a/CBApi.Tests/testdata/ResponseJobSearchWithFacets.xml b/CBApi.Tests/testdata/ResponseJobSearchWithFacets.xml
new file mode 100644
index 0000000..8273707
--- /dev/null
+++ b/CBApi.Tests/testdata/ResponseJobSearchWithFacets.xml
@@ -0,0 +1,1070 @@
+
+
+
+ 3/21/2013 3:26:06 PM
+ 0.3744288
+ 214
+ 1921
+ 1
+ 9
+
+
+ -
+ "JN004"
+ Engineering
+ 1143
+
+ -
+ "JN008"
+ Information Technology
+ 1013
+
+ -
+ "JN037"
+ Management
+ 361
+
+ -
+ "JN021"
+ Design
+ 303
+
+ -
+ "JN025"
+ QA - Quality Control
+ 164
+
+ -
+ "JN011"
+ Sales
+ 163
+
+ -
+ "JN013"
+ Skilled Labor - Trades
+ 159
+
+ -
+ "JN029"
+ Manufacturing
+ 133
+
+ -
+ "JN010"
+ Other
+ 109
+
+ -
+ "JN028"
+ Strategy - Planning
+ 85
+
+ -
+ "JN056"
+ Installation - Maint - Repair
+ 81
+
+ -
+ "JN048"
+ Telecommunications
+ 76
+
+ -
+ "JN022"
+ Entry Level
+ 75
+
+ -
+ "JN003"
+ Customer Service
+ 65
+
+ -
+ "JN005"
+ Finance
+ 65
+
+ -
+ "JN024"
+ Professional Services
+ 62
+
+ -
+ "JN020"
+ Consultant
+ 54
+
+ -
+ "JN001"
+ Accounting
+ 38
+
+ -
+ "JN009"
+ Marketing
+ 37
+
+ -
+ "JN006"
+ General Business
+ 36
+
+ -
+ "JN043"
+ Construction
+ 35
+
+ -
+ "JN054"
+ Automotive
+ 32
+
+ -
+ "JN012"
+ Science
+ 31
+
+ -
+ "JN019"
+ Business Development
+ 29
+
+ -
+ "JN032"
+ Training
+ 24
+
+ -
+ "JN051"
+ General Labor
+ 21
+
+ -
+ "JN030"
+ Legal
+ 20
+
+ -
+ "JN033"
+ Retail
+ 20
+
+ -
+ "JN002"
+ Admin - Clerical
+ 18
+
+ -
+ "JN016"
+ Purchasing - Procurement
+ 18
+
+ -
+ "JN023"
+ Health Care
+ 18
+
+ -
+ "JN031"
+ Education
+ 18
+
+ -
+ "JN007"
+ Human Resources
+ 17
+
+ -
+ "JN026"
+ Research
+ 17
+
+ -
+ "JN015"
+ Inventory
+ 16
+
+ -
+ "JN017"
+ Facilities
+ 16
+
+ -
+ "JN044"
+ Transportation
+ 13
+
+ -
+ "JN038"
+ Banking
+ 12
+
+ -
+ "JN034"
+ Insurance
+ 11
+
+ -
+ "JN057"
+ Real Estate
+ 11
+
+
+
+ -
+ "The Mathworks Inc"
+ The Mathworks Inc
+ 437
+
+ -
+ "AT&T IT/Engineering/Technology"
+ AT&T IT/Engineering/Technology
+ 47
+
+ -
+ "Adecco Technical"
+ Adecco Technical
+ 39
+
+ -
+ "Randstad Technologies"
+ Randstad Technologies
+ 29
+
+ -
+ "Visionaire Partners"
+ Visionaire Partners
+ 25
+
+ -
+ "Robert Half Technology"
+ Robert Half Technology
+ 22
+
+ -
+ "AT&T College"
+ AT&T College
+ 19
+
+ -
+ "Aerotek"
+ Aerotek
+ 19
+
+ -
+ "Collabera Inc."
+ Collabera Inc.
+ 18
+
+ -
+ "Kelly Engineering Resources"
+ Kelly Engineering Resources
+ 18
+
+ -
+ "Aptean"
+ Aptean
+ 17
+
+ -
+ "CareerBuilder-US"
+ CareerBuilder-US
+ 17
+
+ -
+ "L-3 Communications Display Systems"
+ L-3 Communications Display Systems
+ 17
+
+ -
+ "TEKsystems, Inc"
+ TEKsystems, Inc
+ 17
+
+ -
+ "ViaSat, Inc."
+ ViaSat, Inc.
+ 17
+
+ -
+ "Cox Communications"
+ Cox Communications
+ 16
+
+ -
+ "Randstad Engineering"
+ Randstad Engineering
+ 16
+
+ -
+ "EarthLink, Inc"
+ EarthLink, Inc
+ 15
+
+ -
+ "Hunter Technical Resources"
+ Hunter Technical Resources
+ 15
+
+ -
+ "NCR"
+ NCR
+ 15
+
+ -
+ "Rose International"
+ Rose International
+ 15
+
+ -
+ "The Intersect Group"
+ The Intersect Group
+ 14
+
+ -
+ "Dyson"
+ Dyson
+ 13
+
+ -
+ "CBRE"
+ CBRE
+ 12
+
+ -
+ "Experis"
+ Experis
+ 12
+
+ -
+ "Manhattan Associates"
+ Manhattan Associates
+ 12
+
+ -
+ "Bartech Group"
+ Bartech Group
+ 11
+
+ -
+ "DISYS"
+ DISYS
+ 11
+
+ -
+ "Kimberly Clark"
+ Kimberly Clark
+ 11
+
+ -
+ "MDI Group"
+ MDI Group
+ 10
+
+ -
+ "Tires Plus"
+ Tires Plus
+ 10
+
+ -
+ "AT&T Business Solutions"
+ AT&T Business Solutions
+ 9
+
+ -
+ "Artech Information Systems"
+ Artech Information Systems
+ 8
+
+ -
+ "BlueStream Professional Services"
+ BlueStream Professional Services
+ 8
+
+ -
+ "Confidential"
+ Confidential
+ 8
+
+ -
+ "Fiserv"
+ Fiserv
+ 8
+
+ -
+ "Intelsat Corporation"
+ Intelsat Corporation
+ 8
+
+ -
+ "Philips Electronics"
+ Philips Electronics
+ 8
+
+ -
+ "Verint"
+ Verint
+ 8
+
+ -
+ "Cbeyond"
+ Cbeyond
+ 7
+
+
+
+ -
+ "Atlanta"
+ Atlanta
+ 1266
+
+ -
+ "Alpharetta"
+ Alpharetta
+ 219
+
+ -
+ "Norcross"
+ Norcross
+ 99
+
+ -
+ "Duluth"
+ Duluth
+ 31
+
+ -
+ "Marietta"
+ Marietta
+ 27
+
+ -
+ "Kennesaw"
+ Kennesaw
+ 25
+
+ -
+ "Suwanee"
+ Suwanee
+ 19
+
+ -
+ "Lawrenceville"
+ Lawrenceville
+ 14
+
+ -
+ "Roswell"
+ Roswell
+ 14
+
+ -
+ "Peachtree City"
+ Peachtree City
+ 13
+
+ -
+ "Conyers"
+ Conyers
+ 12
+
+ -
+ "Johns Creek"
+ Johns Creek
+ 11
+
+ -
+ "Ellenwood"
+ Ellenwood
+ 9
+
+ -
+ "Sandy Springs"
+ Sandy Springs
+ 9
+
+ -
+ "East Point"
+ East Point
+ 8
+
+ -
+ "Tucker"
+ Tucker
+ 8
+
+ -
+ "Smyrna"
+ Smyrna
+ 6
+
+ -
+ "Decatur"
+ Decatur
+ 5
+
+ -
+ "Dunwoody"
+ Dunwoody
+ 5
+
+ -
+ "Newnan"
+ Newnan
+ 5
+
+ -
+ "Stone Mountain"
+ Stone Mountain
+ 5
+
+ -
+ "Chamblee"
+ Chamblee
+ 4
+
+ -
+ "College Park"
+ College Park
+ 4
+
+ -
+ "Cumming"
+ Cumming
+ 4
+
+ -
+ "Griffin"
+ Griffin
+ 4
+
+ -
+ "Austell"
+ Austell
+ 3
+
+ -
+ "Douglasville"
+ Douglasville
+ 3
+
+ -
+ "Snellville"
+ Snellville
+ 3
+
+ -
+ "Druid Hills"
+ Druid Hills
+ 2
+
+ -
+ "Forest Park"
+ Forest Park
+ 2
+
+ -
+ "Gresham Park"
+ Gresham Park
+ 2
+
+ -
+ "Lithia Springs"
+ Lithia Springs
+ 2
+
+ -
+ "Loganville"
+ Loganville
+ 2
+
+ -
+ "McDonough"
+ McDonough
+ 2
+
+ -
+ "Morrow"
+ Morrow
+ 2
+
+ -
+ "North Decatur"
+ North Decatur
+ 2
+
+ -
+ "Woodstock"
+ Woodstock
+ 2
+
+ -
+ "Acworth"
+ Acworth
+ 1
+
+ -
+ "Fair Oaks"
+ Fair Oaks
+ 1
+
+ -
+ "Fairburn"
+ Fairburn
+ 1
+
+
+
+ -
+ "GA"
+ Georgia
+ 1868
+
+
+
+ -
+ "Atlanta,GA"
+ Atlanta,GA
+ 1267
+
+ -
+ "Alpharetta,GA"
+ Alpharetta,GA
+ 219
+
+ -
+ "Norcross,GA"
+ Norcross,GA
+ 142
+
+ -
+ "Duluth,GA"
+ Duluth,GA
+ 31
+
+ -
+ "Marietta,GA"
+ Marietta,GA
+ 28
+
+ -
+ "Kennesaw,GA"
+ Kennesaw,GA
+ 25
+
+ -
+ "Suwanee,GA"
+ Suwanee,GA
+ 19
+
+ -
+ "Lawrenceville,GA"
+ Lawrenceville,GA
+ 14
+
+ -
+ "Roswell,GA"
+ Roswell,GA
+ 14
+
+ -
+ "Peachtree City,GA"
+ Peachtree City,GA
+ 13
+
+ -
+ "Conyers,GA"
+ Conyers,GA
+ 12
+
+ -
+ "Johns Creek,GA"
+ Johns Creek,GA
+ 11
+
+ -
+ "Ellenwood,GA"
+ Ellenwood,GA
+ 9
+
+ -
+ "Sandy Springs,GA"
+ Sandy Springs,GA
+ 9
+
+ -
+ "Tucker,GA"
+ Tucker,GA
+ 9
+
+ -
+ "East Point,GA"
+ East Point,GA
+ 8
+
+ -
+ "Smyrna,GA"
+ Smyrna,GA
+ 6
+
+ -
+ "Decatur,GA"
+ Decatur,GA
+ 5
+
+ -
+ "Dunwoody,GA"
+ Dunwoody,GA
+ 5
+
+ -
+ "Newnan,GA"
+ Newnan,GA
+ 5
+
+ -
+ "Stone Mountain,GA"
+ Stone Mountain,GA
+ 5
+
+ -
+ "Chamblee,GA"
+ Chamblee,GA
+ 4
+
+ -
+ "College Park,GA"
+ College Park,GA
+ 4
+
+ -
+ "Cumming,GA"
+ Cumming,GA
+ 4
+
+ -
+ "Griffin,GA"
+ Griffin,GA
+ 4
+
+ -
+ "Aiken,SC"
+ Aiken,SC
+ 3
+
+ -
+ "Austell,GA"
+ Austell,GA
+ 3
+
+ -
+ "Douglasville,GA"
+ Douglasville,GA
+ 3
+
+ -
+ "Snellville,GA"
+ Snellville,GA
+ 3
+
+ -
+ "Druid Hills,GA"
+ Druid Hills,GA
+ 2
+
+ -
+ "Forest Park,GA"
+ Forest Park,GA
+ 2
+
+ -
+ "Gresham Park,GA"
+ Gresham Park,GA
+ 2
+
+ -
+ "Lithia Springs,GA"
+ Lithia Springs,GA
+ 2
+
+ -
+ "Loganville,GA"
+ Loganville,GA
+ 2
+
+ -
+ "McDonough,GA"
+ McDonough,GA
+ 2
+
+ -
+ "Morrow,GA"
+ Morrow,GA
+ 2
+
+ -
+ "North Decatur,GA"
+ North Decatur,GA
+ 2
+
+ -
+ "Prescott,AR"
+ Prescott,AR
+ 2
+
+ -
+ "Woodstock,GA"
+ Woodstock,GA
+ 2
+
+ -
+ "Acworth,GA"
+ Acworth,GA
+ 1
+
+
+
+ -
+ [*****0]
+ Unspecified
+ 1648
+
+ -
+ [1*****14999]
+ $1 - <$15k
+ 92
+
+ -
+ [15000*****29999]
+ $15k - <$30k
+ 1
+
+ -
+ [30000*****49999]
+ $30k - <$50k
+ 8
+
+ -
+ [50000*****74999]
+ $50k - <$75k
+ 47
+
+ -
+ [75000*****99999]
+ $75k - <$100k
+ 53
+
+ -
+ [100000*****]
+ Over $100,000
+ 72
+
+
+
+
+
+
+ AKS, Inc
+
+
+ JHT71368BMZ38TGK6Q2
+ 17-2141.00
+ Mechanical Engineers
+ HVAC Engineer Working in a fast pace team environment with a group of Mechanical ... HVAC Engineer EIT/PE Plus Applicants should have 2 years plus...
+ Nearby
+ Full-Time
+ http://api.careerbuilder.com/v1/joblink?TrackingID=CBWG7KSY&DID=JHT71368BMZ38TGK6Q2
+ https://api.careerbuilder.com/v1/job?DID=JHT71368BMZ38TGK6Q2&DeveloperKey=WDRF81661JM5WPB63DGJ
+ GA - Atlanta
+ 33.74831
+ -84.39111
+ 3/14/2013
+ $55k - $80k/year
+ http://www.careerbuilder.com/Jobs/SimilarJobs.aspx?ipath=JELO&job_did=JHT71368BMZ38TGK6Q2
+ HVAC ENGINEER
+
+ US
+
+
+ Able Engineering Services
+
+
+ JHT46167G3GQPN4GF6Y
+ 49-9042.00
+ Maintenance and Repair Workers
+ Building Engineer JOB SUMMARY:Responsible for maintenance and repairs to the buildings ... Experience that is commensurate with the specific facility...
+ 7 miles
+ Full-Time
+ http://api.careerbuilder.com/v1/joblink?TrackingID=CBWG7KSY&DID=JHT46167G3GQPN4GF6Y
+ https://api.careerbuilder.com/v1/job?DID=JHT46167G3GQPN4GF6Y&DeveloperKey=WDRF81661JM5WPB63DGJ
+ GA - Atlanta
+ 33.8675
+ -84.4236
+ 3/18/2013
+ N/A
+ http://www.careerbuilder.com/Jobs/SimilarJobs.aspx?ipath=JELO&job_did=JHT46167G3GQPN4GF6Y
+ Building Engineer
+
+ US
+
+
+ Bartech Group
+ c8g5xl6rqnqy6pmmtkb
+ http://www.careerbuilder.com/Jobs/Company/C8G5XL6RQNQY6PMMTKB/Bartech-Group/?sc_cmp1=13_JobRes_ComDet
+ JB71S364NQ0X8VY51WD
+ 15-1071.00
+ Network and Computer Systems Administrators
+ IT Network Engineer (Network Administrator) Job DescriptionBartech Group, a leading global ... IT Network Engineer (Information Technology / Network...
+ Nearby
+ Full-Time
+ http://api.careerbuilder.com/v1/joblink?TrackingID=CBWG7KSY&DID=JB71S364NQ0X8VY51WD
+ https://api.careerbuilder.com/v1/job?DID=JB71S364NQ0X8VY51WD&DeveloperKey=WDRF81661JM5WPB63DGJ
+ GA - Various US Locations
+ 33.74831
+ -84.39111
+ 2/22/2013
+ N/A
+ http://www.careerbuilder.com/Jobs/SimilarJobs.aspx?ipath=JELO&job_did=JB71S364NQ0X8VY51WD
+ IT Network Engineer (Network Administrator)
+ http://emj.icbdr.com/MediaManagement/7P/MVJ81466WSNX4T1SG7P.gif
+ US
+
+
+ Parkway Properties, Inc.
+
+
+ JHT1D66BP5SXFX7KZQX
+ 49-9042.00
+ Maintenance and Repair Workers
+ Parkway has an immediate opening for a Building Engineer in downtown Atlanta. This position ... engineer or related training• Strong communication,...
+ Nearby
+ Full-Time
+ http://api.careerbuilder.com/v1/joblink?TrackingID=CBWG7KSY&DID=JHT1D66BP5SXFX7KZQX
+ https://api.careerbuilder.com/v1/job?DID=JHT1D66BP5SXFX7KZQX&DeveloperKey=WDRF81661JM5WPB63DGJ
+ GA - Atlanta
+ 33.74831
+ -84.39111
+ 3/11/2013
+ N/A
+ http://www.careerbuilder.com/Jobs/SimilarJobs.aspx?ipath=JELO&job_did=JHT1D66BP5SXFX7KZQX
+ Building Engineer
+
+ US
+
+
+ AKS, Inc
+
+
+ JHS8B379CPXFHMR5QXY
+ 17-2112.00
+ Industrial Engineers
+ PLC Controls Engineer Controls Project Engineer is responsible, individually or as a team ... PLC Controls Engineer -Bachelor’s degree in related...
+ Nearby
+ Full-Time
+ http://api.careerbuilder.com/v1/joblink?TrackingID=CBWG7KSY&DID=JHS8B379CPXFHMR5QXY
+ https://api.careerbuilder.com/v1/job?DID=JHS8B379CPXFHMR5QXY&DeveloperKey=WDRF81661JM5WPB63DGJ
+ GA - Atlanta
+ 33.74831
+ -84.39111
+ 3/21/2013
+ $65k - $85k/year
+ http://www.careerbuilder.com/Jobs/SimilarJobs.aspx?ipath=JELO&job_did=JHS8B379CPXFHMR5QXY
+ PLC Controls Engineer
+
+ US
+
+
+ Kinetix
+ chs8dc65hxy8q17glb6
+ http://www.careerbuilder.com/Jobs/Company/CHS8DC65HXY8Q17GLB6/Kinetix/?sc_cmp1=13_JobRes_ComDet
+ J3F3446404HM41Y3X2M
+ 15-1071.00
+ Network and Computer Systems Administrators
+ We are seeking a NOC Network Engineer on behalf of one of our clients in the Perimeter area of ... within a fast-paced environment.Tags: NOC...
+ Nearby
+ Full-Time
+ http://api.careerbuilder.com/v1/joblink?TrackingID=CBWG7KSY&DID=J3F3446404HM41Y3X2M
+ https://api.careerbuilder.com/v1/job?DID=J3F3446404HM41Y3X2M&DeveloperKey=WDRF81661JM5WPB63DGJ
+ GA - Atlanta
+ 33.74831
+ -84.39111
+ 2/22/2013
+ N/A
+ http://www.careerbuilder.com/Jobs/SimilarJobs.aspx?ipath=JELO&job_did=J3F3446404HM41Y3X2M
+ NOC Network Engineer
+ http://emj.icbdr.com/MediaManagement/Y7/MWV7G85WXH96NRDB6Y7.jpg
+ US
+
+
+ DISYS
+ c7x3336nbg18m66dlvt
+ http://www.careerbuilder.com/Jobs/Company/C7X3336NBG18M66DLVT/DISYS/?sc_cmp1=13_JobRes_ComDet
+ JHT7WW5W66T7KB8YF96
+ 15-1071.00
+ Network and Computer Systems Administrators
+ Network Engineer / AdministratorOur client in Suwanee, GA is looking for a solid Network ... Network Engineer / Administrator should have the...
+ Nearby
+ Full-Time
+ http://api.careerbuilder.com/v1/joblink?TrackingID=CBWG7KSY&DID=JHT7WW5W66T7KB8YF96
+ https://api.careerbuilder.com/v1/job?DID=JHT7WW5W66T7KB8YF96&DeveloperKey=WDRF81661JM5WPB63DGJ
+ GA - Atlanta
+ 33.74831
+ -84.39111
+ 2/28/2013
+ $45.00 - $50.00/hour
+ http://www.careerbuilder.com/Jobs/SimilarJobs.aspx?ipath=JELO&job_did=JHT7WW5W66T7KB8YF96
+ Network Engineer
+ http://emj.icbdr.com/MediaManagement/81/MRQ64T76FJNW313ZF81.jpg
+ US
+
+
+ Exactsource
+ chv4126dnvc2l6lcd3h
+ http://www.careerbuilder.com/Jobs/Company/CHV4126DNVC2L6LCD3H/Exactsource/?sc_cmp1=13_JobRes_ComDet
+ JHM32773G0MMBQKH3YN
+ 17-2171.00
+ Petroleum Engineers
+ *Non Civil Engineers need not applyClient DescriptionOur Client is a full ... Engineering, Electrical Engineering, Process/Chemical Engineering...
+ Nearby
+ Full-Time
+ http://api.careerbuilder.com/v1/joblink?TrackingID=CBWG7KSY&DID=JHM32773G0MMBQKH3YN
+ https://api.careerbuilder.com/v1/job?DID=JHM32773G0MMBQKH3YN&DeveloperKey=WDRF81661JM5WPB63DGJ
+ GA - Atlanta
+ 33.74831
+ -84.39111
+ 3/7/2013
+ $80k - $110k/year
+ http://www.careerbuilder.com/Jobs/SimilarJobs.aspx?ipath=JELO&job_did=JHM32773G0MMBQKH3YN
+ Midstream Oil & Gas Pipeline Engineer (PE License required)
+ http://emj.icbdr.com/MediaManagement/93/MVT4X56L7P6Y03S2493.jpg
+ US
+
+
+ The River Group
+
+
+ JHR1MM6K6SD304GNP15
+ 41-9031.00
+ Sales Engineers
+ Title: Sales Engineer Location: Atlanta, GA ... Qualifications: The successful candidate will have a...
+ Nearby
+ Full-Time
+ http://api.careerbuilder.com/v1/joblink?TrackingID=CBWG7KSY&DID=JHR1MM6K6SD304GNP15
+ https://api.careerbuilder.com/v1/job?DID=JHR1MM6K6SD304GNP15&DeveloperKey=WDRF81661JM5WPB63DGJ
+ GA - North Georgia
+ 33.74831
+ -84.39111
+ 3/20/2013
+ N/A
+ http://www.careerbuilder.com/Jobs/SimilarJobs.aspx?ipath=JELO&job_did=JHR1MM6K6SD304GNP15
+ Sales Engineer - Account Representative
+
+ US
+
+
+
+ ((searchtext.tlem_i:en♀♥♂engineer)) AND (_query_:"{!frange l=0 u=0.280329829863092}sqedist(latitude,longitude,33.748,-84.391)" OR geography.wsdt_i:NTUS OR geography.wsdt_i:RGSE OR geography.wsdt_i:STGA)
+ ;;mastercommunitylist.wsdt_is:"CMAL" AND mastercommunitylist.wsdt_is:"cmpub" AND NOT mastercommunitylist.wsdt_is:cmmlm AND prenddate.dt_is:[2013-03-21T04:00:00Z TO *]
+ http://solrjob.qtw.cbdr.com:31000/solr/core1/select/?defType=cbqp&fbweights=searchtext.tlem_i%3a%3a1%3a3%3b5%3a1.5%3b6%3a0.5%3b7%3a2%3b%3bsearchtext_exact.t_i%3a%3a1%3a3%3b5%3a1.5%3b6%3a0.5%3b7%3a2%3b%3bmatchcontent.cdt_i%3a%3a1%3a8%3b2%3a5.36%3b3%3a3.38%3b4%3a1.95%3b6%3a0.422%3b7%3a0.125%3b8%3a0.0156%3b%3bmultipleonet.cdt_i%3a%3a1%3a50%3b2%3a51%3b3%3a52%3b4%3a53%3b5%3a54%3b6%3a55%3b7%3a56%3b8%3a57%3b9%3a58%3b10%3a59%3b11%3a60%3b12%3a61%3b13%3a62%3b14%3a63%3b15%3a64%3b16%3a65%3b17%3a66%3b18%3a67%3b19%3a68%3b20%3a69%3b21%3a70%3b22%3a71%3b23%3a72%3b24%3a73%3b25%3a74%3b26%3a75%3b27%3a76%3b28%3a77%3b29%3a78%3b30%3a79%3b31%3a80%3b32%3a81%3b33%3a82%3b34%3a83%3b35%3a84%3b36%3a85%3b37%3a86%3b38%3a87%3b39%3a88%3b40%3a89%3b41%3a90%3b42%3a91%3b43%3a92%3b44%3a93%3b45%3a94%3b46%3a95%3b47%3a96%3b48%3a97%3b49%3a98%3b50%3a99%3b51%3a100%3b%3bclassifiedjobtitle.cdt_i%3a%3a0%3a0%3b2%3a2%3b3%3a3%3b4%3a4%3b5%3a5%3b6%3a6%3b7%3a7%3b8%3a8%3b9%3a9%3b10%3a10%3b11%3a11%3b12%3a12%3b13%3a13%3b14%3a14%3b15%3a15%3b16%3a16%3b17%3a17%3b18%3a18%3b19%3a19%3b20%3a20%3b21%3a21%3b22%3a22%3b23%3a23%3b24%3a24%3b25%3a25%3b26%3a26%3b27%3a27%3b28%3a28%3b29%3a29%3b30%3a30%3b31%3a31%3b32%3a32%3b33%3a33%3b34%3a34%3b35%3a35%3b36%3a36%3b37%3a37%3b38%3a38%3b39%3a39%3b40%3a40%3b41%3a41%3b42%3a42%3b43%3a43%3b44%3a44%3b45%3a45%3b46%3a46%3b47%3a47%3b48%3a48%3b49%3a49%3b50%3a50%3b51%3a51%3b52%3a52%3b53%3a53%3b54%3a54%3b55%3a55%3b56%3a56%3b57%3a57%3b58%3a58%3b59%3a59%3b60%3a60%3b61%3a61%3b62%3a62%3b63%3a63%3b64%3a64%3b65%3a65%3b66%3a66%3b67%3a67%3b68%3a68%3b69%3a69%3b70%3a70%3b71%3a71%3b72%3a72%3b73%3a73%3b74%3a74%3b75%3a75%3b76%3a76%3b77%3a77%3b78%3a78%3b79%3a79%3b80%3a80%3b81%3a81%3b82%3a82%3b83%3a83%3b84%3a84%3b85%3a85%3b86%3a86%3b87%3a87%3b88%3a88%3b89%3a89%3b90%3a90%3b91%3a91%3b92%3a92%3b93%3a93%3b94%3a94%3b95%3a95%3b96%3a96%3b97%3a97%3b98%3a98%3b99%3a99%3b100%3a100&cbscore.hitmap.default=0%3a0%3b1%3a14%3b2%3a16.5%3b3%3a19%3b4%3a21.5%3b5-16%3a24%3b17-MAX%3a0&cbscore.type=hitmap&cbscore.boostexact=true&q.op=AND&fq=mastercommunitylist.wsdt_is%3a%22CMAL%22+AND+mastercommunitylist.wsdt_is%3a%22cmpub%22+AND+NOT+mastercommunitylist.wsdt_is%3acmmlm+AND+prenddate.dt_is%3a%5b2013-03-21T04%3a00%3a00Z+TO+*%5d&facet.field=%7b!key%3d%22skilldids%22%7dskilldids.scdt_i&f.skilldids.scdt_i.facet.sort=count&f.skilldids.scdt_i.facet.limit=50&f.skilldids.scdt_i.facet.mincount=1&f.skilldids.scdt_i.facet.missing=false&f.skilldids.scdt_i.facet.method=fc&facet.field=%7b!key%3d%22certificationdids%22%7dcertificationdids.scdt_i&f.certificationdids.scdt_i.facet.sort=count&f.certificationdids.scdt_i.facet.limit=50&f.certificationdids.scdt_i.facet.mincount=1&f.certificationdids.scdt_i.facet.missing=false&f.certificationdids.scdt_i.facet.method=fc&facet.field=%7b!key%3d%22countryname%22%7dcountrynav.ms_i&f.countrynav.ms_i.facet.sort=count&f.countrynav.ms_i.facet.limit=40&f.countrynav.ms_i.facet.mincount=1&f.countrynav.ms_i.facet.missing=false&f.countrynav.ms_i.facet.method=fc&facet.field=%7b!key%3d%22userjobtypelist%22%7duserjobtypelistnav.mwsdt_is&f.userjobtypelistnav.mwsdt_is.facet.sort=count&f.userjobtypelistnav.mwsdt_is.facet.limit=40&f.userjobtypelistnav.mwsdt_is.facet.mincount=1&f.userjobtypelistnav.mwsdt_is.facet.missing=false&f.userjobtypelistnav.mwsdt_is.facet.method=fc&facet.field=%7b!key%3d%22contactcompany%22%7dcontactcompanynav.ms_i&f.contactcompanynav.ms_i.facet.sort=count&f.contactcompanynav.ms_i.facet.limit=40&f.contactcompanynav.ms_i.facet.mincount=1&f.contactcompanynav.ms_i.facet.missing=false&f.contactcompanynav.ms_i.facet.method=fc&facet.field=%7b!key%3d%22skilltags%22%7dskilltags.scdt_is&f.skilltags.scdt_is.facet.sort=count&f.skilltags.scdt_is.facet.limit=50&f.skilltags.scdt_is.facet.mincount=1&f.skilltags.scdt_is.facet.missing=false&f.skilltags.scdt_is.facet.method=fc&facet.field=%7b!key%3d%22jobtitlenorm%22%7djobtitlenav.ms_i&f.jobtitlenav.ms_i.facet.sort=count&f.jobtitlenav.ms_i.facet.limit=40&f.jobtitlenav.ms_i.facet.mincount=1&f.jobtitlenav.ms_i.facet.missing=false&f.jobtitlenav.ms_i.facet.method=fc&facet.field=%7b!key%3d%22statename%22%7dstatenav.ms_i&f.statenav.ms_i.facet.sort=count&f.statenav.ms_i.facet.limit=60&f.statenav.ms_i.facet.mincount=1&f.statenav.ms_i.facet.missing=false&f.statenav.ms_i.facet.method=fc&facet.field=%7b!key%3d%22cityname%22%7dcitynav.ms_i&f.citynav.ms_i.facet.sort=count&f.citynav.ms_i.facet.limit=40&f.citynav.ms_i.facet.mincount=1&f.citynav.ms_i.facet.missing=false&f.citynav.ms_i.facet.method=fc&facet.field=%7b!key%3d%22citystate%22%7dcitystatedisplay.ms_i&f.citystatedisplay.ms_i.facet.sort=count&f.citystatedisplay.ms_i.facet.limit=40&f.citystatedisplay.ms_i.facet.mincount=1&f.citystatedisplay.ms_i.facet.missing=false&f.citystatedisplay.ms_i.facet.method=fc&facet.query=%7b!key%3d%22payhigh%3a%5b*+0%5d%22%7dpayhigh.i_is%3a%5b*+0%5d&facet.query=%7b!key%3d%22payhigh%3a%5b1+14999%5d%22%7dpayhigh.i_is%3a%5b1+14999%5d&facet.query=%7b!key%3d%22payhigh%3a%5b15000+29999%5d%22%7dpayhigh.i_is%3a%5b15000+29999%5d&facet.query=%7b!key%3d%22payhigh%3a%5b30000+49999%5d%22%7dpayhigh.i_is%3a%5b30000+49999%5d&facet.query=%7b!key%3d%22payhigh%3a%5b50000+74999%5d%22%7dpayhigh.i_is%3a%5b50000+74999%5d&facet.query=%7b!key%3d%22payhigh%3a%5b75000+99999%5d%22%7dpayhigh.i_is%3a%5b75000+99999%5d&facet.query=%7b!key%3d%22payhigh%3a%5b100000+*%5d%22%7dpayhigh.i_is%3a%5b100000+*%5d&facet=true&hl=on&hl.fl=jobdesc.tlem_is%2cjobreq.tlem_is&hl.mergeContiguous=true&hl.fragsize=100&hl.simple.pre=%3cb%3e&hl.simple.post=%3c%2fb%3e&start=0&rows=9&q=(((searchtext.tlem_i%3aen%e2%99%80%e2%99%a5%e2%99%82engineer))+AND+(_query_%3a%22%7b!frange+l%3d0+u%3d0.280329829863092%7dsqedist(latitude%2clongitude%2c33.748%2c-84.391)%22+OR+geography.wsdt_i%3aNTUS+OR+geography.wsdt_i%3aRGSE+OR+geography.wsdt_i%3aSTGA))+AND+_val_%3a%22product(appliespersearch.d_i%2c1000)%22&debugQuery=false&fl=*%2cpartnerid.s_is%3afield(partnerid.s_is)%2cnormalizedretrievablecompanydid.s_is%3afield(normalizedretrievablecompanydid.s_is)%2cposterdid.s_is%3afield(posterdid.s_is)%2chostsite.s_is%3afield(hostsite.s_is)%2ccbtype.s_is%3afield(cbtype.s_is)%2cstate.s_is%3afield(state.s_is)%2ccountry.s_is%3afield(country.s_is)%2caccountdid.s_is%3afield(accountdid.s_is)%2ccompanydid.s_is%3afield(companydid.s_is)%2chhname.s_is%3afield(hhname.s_is)%2cclustereddate.dt_is%3afield(clustereddate.dt_is)%2csysmoddate.dt_is%3afield(sysmoddate.dt_is)%2cprbegindate.dt_is%3afield(prbegindate.dt_is)%2cprenddate.dt_is%3afield(prenddate.dt_is)%2cpayhigh.i_is%3afield(payhigh.i_is)%2cdegreerequiredint.i_is%3afield(degreerequiredint.i_is)%2cdisplayweight.i_is%3afield(displayweight.i_is)%2cmodifiedint.i_is%3afield(modifiedint.i_is)%2cpaylow.i_is%3afield(paylow.i_is)%2creqexpint.i_is%3afield(reqexpint.i_is)%2creservedint1.i_is%3afield(reservedint1.i_is)%2creservedint2.i_is%3afield(reservedint2.i_is)%2cyearsexperiencelow.i_is%3afield(yearsexperiencelow.i_is)%2cyearsexperiencehigh.i_is%3afield(yearsexperiencehigh.i_is)%2cscore&sort=displayweight.i_is+desc,score+desc,modifiedint.i_is+desc,score+desc
+
+
\ No newline at end of file
diff --git a/CBApi.Tests/testdata/SaveSearchCreateData.xml b/CBApi.Tests/testdata/SaveSearchCreateData.xml
new file mode 100644
index 0000000..503cbc8
--- /dev/null
+++ b/CBApi.Tests/testdata/SaveSearchCreateData.xml
@@ -0,0 +1,43 @@
+
+
+
+
+ lotsloc
+ US
+
+
+ none
+ NONE
+
+ AND
+
+ DRNS
+
+
+
+
+ false
+
+
+
+ Chicago, Il, Atlanta, Ga, New York, Ny
+ Pay
+ ascending
+ 70
+ false
+ 40
+ 30
+ 30
+ false
+
+
+
+
+
+
+
+
+
+ https://api.careerbuilder.com/v1/jobsearch?BooleanOperator=AND&EducationCode=DRNS&ExcludeNational=False&Location=Chicago%2c+Il%2c+Atlanta%2c+Ga%2c+New+York%2c+Ny&OrderBy=Pay&OrderDirection=ascending&PayHigh=70&PayInfoOnly=False&PayLow=40&PostedWithin=30&Radius=30&SpecificEducation=False&DeveloperKey=WDJ16BN6CQB69FP18Y8F&Hostsite=US
+
+
diff --git a/CBApi.Tests/testdata/SavedSearchDeleteResult.xml b/CBApi.Tests/testdata/SavedSearchDeleteResult.xml
new file mode 100644
index 0000000..0117d1b
--- /dev/null
+++ b/CBApi.Tests/testdata/SavedSearchDeleteResult.xml
@@ -0,0 +1,11 @@
+
+
+
+ WD******************
+ b5**************************************************************
+ ec**************************************************************
+ US
+
+
+ Success
+
\ No newline at end of file
diff --git a/CBApi.Tests/testdata/SavedSearchListResponseModel.xml b/CBApi.Tests/testdata/SavedSearchListResponseModel.xml
new file mode 100644
index 0000000..83be88f
--- /dev/null
+++ b/CBApi.Tests/testdata/SavedSearchListResponseModel.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+ software engineer
+ US
+ ea6c190017576af21724885aa7bde734130a06bbf32fd5e30f0ba814e2a68b2d
+ JRHR6D779M3W3HBG9PW3
+
+
+ engineer in 30071
+ US
+ f28273259cf31cbd1c0d07bf727deb8447a54d7e1c59d32399b937d469cf0a54
+ JR0Z8J26868M9MZMNKT5
+
+
+
\ No newline at end of file
diff --git a/Source/CBApi.sln b/CBApi.sln
similarity index 90%
rename from Source/CBApi.sln
rename to CBApi.sln
index 549ec60..f8503b2 100644
--- a/Source/CBApi.sln
+++ b/CBApi.sln
@@ -1,6 +1,6 @@
-Microsoft Visual Studio Solution File, Format Version 11.00
-# Visual Studio 2010
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2012
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CBApi", "CBApi\CBApi.csproj", "{58C4C156-4095-4F29-AF07-72722D262261}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CBApi.Tests", "CBApi.Tests\CBApi.Tests.csproj", "{563513D2-EDA6-417C-9111-CA0D7C9D6199}"
@@ -14,6 +14,13 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CBApiCosoleApp", "CBApiCosoleApp\CBApiCosoleApp.csproj", "{0B92E169-7ABE-4E30-8EEA-8C7AE17EC6E8}"
EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{C56AADF5-275B-465B-A122-A06073AD2CC8}"
+ ProjectSection(SolutionItems) = preProject
+ .nuget\NuGet.Config = .nuget\NuGet.Config
+ .nuget\NuGet.exe = .nuget\NuGet.exe
+ .nuget\NuGet.targets = .nuget\NuGet.targets
+ EndProjectSection
+EndProject
Global
GlobalSection(TestCaseManagementSettings) = postSolution
CategoryFile = CBApi.vsmdi
diff --git a/Source/CBApi.vsmdi b/CBApi.vsmdi
similarity index 100%
rename from Source/CBApi.vsmdi
rename to CBApi.vsmdi
diff --git a/CBApi/API.cs b/CBApi/API.cs
new file mode 100644
index 0000000..e86ccd5
--- /dev/null
+++ b/CBApi/API.cs
@@ -0,0 +1,36 @@
+using CBApi;
+using CBApi.Models.Service;
+
+namespace CBApi
+{
+ public class API
+ {
+ public static ICBApi GetInstance()
+ {
+ return new CbApi();
+ }
+
+ public static ICBApi GetInstance(string developerKey)
+ {
+ return new CbApi(developerKey);
+ }
+
+ public static ICBApi GetInstance(string developerKey,int timeoutMS) {
+ return new CbApi(developerKey);
+ }
+
+ public static ICBApi GetInstance(string developerKey, string cobrandCode)
+ {
+ return new CbApi(developerKey, cobrandCode);
+ }
+
+ public static ICBApi GetInstance(string developerKey, string cobrandCode, string siteID)
+ {
+ return new CbApi(developerKey, cobrandCode, siteID);
+ }
+
+ public static ICBApi GetInstance(string developerKey, int timeoutMS, TargetSite site) {
+ return new CbApi(developerKey,timeoutMS,site);
+ }
+ }
+}
\ No newline at end of file
diff --git a/CBApi/APIException.cs b/CBApi/APIException.cs
new file mode 100644
index 0000000..3ce43a8
--- /dev/null
+++ b/CBApi/APIException.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace CBApi {
+ [Serializable]
+ public class APIException : Exception {
+
+ public List APIErrors { get; set; }
+ public APIException(string message) : base(message){
+ APIErrors = new List();
+ APIErrors.Add(message);
+ }
+
+ public APIException(string message,List errors) : base(message) {
+ APIErrors = errors;
+ }
+ }
+}
diff --git a/CBApi/APISettings.cs b/CBApi/APISettings.cs
new file mode 100644
index 0000000..ad9532b
--- /dev/null
+++ b/CBApi/APISettings.cs
@@ -0,0 +1,19 @@
+using CBApi.Models.Service;
+
+namespace CBApi {
+ public class APISettings {
+ public TargetSite TargetSite { get; set; }
+ public string DevKey { get; set; }
+ public string CobrandCode { get; set; } //If you are a careerbuilder partner you can set these tracking codes
+ public string SiteId { get; set; } //Otherwise leave these two parameters alone
+ public int TimeoutMS { get; set; }
+
+ public APISettings() {
+ TargetSite = new CareerBuilderCom();
+ DevKey = "";
+ CobrandCode = "";
+ SiteId = "";
+ TimeoutMS = 30000;
+ }
+ }
+}
diff --git a/CBApi/APITimeoutException.cs b/CBApi/APITimeoutException.cs
new file mode 100644
index 0000000..7efba39
--- /dev/null
+++ b/CBApi/APITimeoutException.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace CBApi {
+ [Serializable]
+ public class APITimeoutException : APIException {
+ public APITimeoutException(string message)
+ : base(message) {
+ }
+ }
+}
diff --git a/CBApi/CBApi.cs b/CBApi/CBApi.cs
new file mode 100644
index 0000000..01cc973
--- /dev/null
+++ b/CBApi/CBApi.cs
@@ -0,0 +1,385 @@
+using System.Collections.Generic;
+using CBApi.Properties;
+using CBApi.Framework.Requests;
+using CBApi.Models;
+using CBApi.Models.Responses;
+using CBApi.Models.Service;
+using System;
+using System.Collections.Specialized;
+using CBApi.Framework.Events;
+
+namespace CBApi {
+ public class CbApi : ICBApi {
+ #region attributes
+ protected APISettings _Settings = new APISettings();
+ protected List _BeforeListeners = new List();
+ protected List _AfterListeners = new List();
+
+ public string DevKey {
+ get { return _Settings.DevKey; }
+ set { _Settings.DevKey = value; }
+ }
+ public string CobrandCode {
+ get { return _Settings.CobrandCode; }
+ set { _Settings.CobrandCode = value; }
+ }
+ public string SiteId {
+ get { return _Settings.SiteId; }
+ set { _Settings.SiteId = value; }
+ }
+
+ public virtual int TimeoutMS {
+ get { return _Settings.TimeoutMS; }
+ set { _Settings.TimeoutMS = value; }
+ }
+
+ public event BeforeRequestEvent OnBeforeRequest {
+ add { _BeforeListeners.Add(value); }
+ remove { _BeforeListeners.Remove(value); }
+ }
+
+ public event AfterRequestEvent OnAfterRequest {
+ add { _AfterListeners.Add(value); }
+ remove { _AfterListeners.Remove(value); }
+ }
+ #endregion
+
+ #region construction and factories
+
+ protected internal CbApi() {
+ _Settings.TargetSite = new CareerBuilderCom();
+ _Settings.DevKey = Settings.Default.DevKey;
+ }
+
+ protected internal CbApi(string key) {
+ _Settings.TargetSite = new CareerBuilderCom();
+ _Settings.DevKey = key;
+ }
+
+ protected internal CbApi(string key, int timeout) {
+ _Settings.TargetSite = new CareerBuilderCom();
+ _Settings.DevKey = key;
+ _Settings.TimeoutMS = timeout;
+ }
+
+ protected internal CbApi(string key, int timeout, TargetSite site) {
+ _Settings.TargetSite = site;
+ _Settings.DevKey = key;
+ _Settings.TimeoutMS = timeout;
+ }
+
+ protected internal CbApi(string key, string cobrandCode) {
+ _Settings.TargetSite = new CareerBuilderCom();
+ _Settings.DevKey = key;
+ _Settings.CobrandCode = cobrandCode;
+ }
+
+ protected internal CbApi(string key, string cobrandCode, string siteid) {
+ _Settings.TargetSite = new CareerBuilderCom();
+ _Settings.DevKey = key;
+ _Settings.CobrandCode = cobrandCode;
+ _Settings.SiteId = siteid;
+ }
+
+ #endregion
+
+ protected void WireBeforeRequestEvents(BaseRequest req) {
+ foreach (var item in _BeforeListeners) {
+ req.OnBeforeRequest += item;
+ }
+ }
+
+ protected void WireAfterRequestEvents(BaseRequest req) {
+ foreach (var item in _AfterListeners) {
+ req.OnAfterRequest += item;
+ }
+ }
+
+ #region api calls
+ ///
+ /// Make a call to /auth/token
+ ///
+ /// 20 character long external client ID.
+ /// 64 character long external client secret.
+ /// 20 character long OAuth authorization grant code returned from auth/prompt redirection.
+ /// URL that was provided at the time of external client registration.
+ ///
+ public AccessToken GetAccessToken(string clientId, string clientSecret, string code, string redirectUri) {
+ var req = new AuthTokenRequest(clientId, clientSecret, code, redirectUri, _Settings);
+ WireBeforeRequestEvents(req);
+ WireAfterRequestEvents(req);
+ return req.GetAccessToken();
+ }
+
+ ///
+ /// Gets the Uri to redirect to for OAuth
+ ///
+ ///
+ ///
+ ///
+ ///
+ public Uri GetOAuthRedirectUri(string clientId, string redirectUri, string permissions) {
+ var req = new OAuthRedirectBuilder(clientId, redirectUri, permissions, _Settings.TargetSite.Domain);
+ return req.OAuthUri();
+ }
+
+ ///
+ /// Make a call to /v1/application/blank
+ ///
+ /// The unique ID of the job
+ /// The job
+ public BlankApplication GetBlankApplication(string jobDid) {
+ var req = new BlankApplicationRequest(jobDid, _Settings);
+ WireBeforeRequestEvents(req);
+ WireAfterRequestEvents(req);
+ return req.Retrieve();
+ }
+
+ ///
+ /// Make a call to /v1/application/form
+ ///
+ /// The unique ID of the job
+ /// The job
+ public string GetApplicationForm(string jobDid) {
+ var req = new ApplicationFormRequest(jobDid, _Settings);
+ WireBeforeRequestEvents(req);
+ WireAfterRequestEvents(req);
+ return req.Retrieve();
+ }
+
+ ///
+ /// Gets the ApplyLink for a Job
+ ///
+ /// A named value collection of params to pass to the api
+ /// The uri to apply to the given job.
+ public string ApplyLink(NameValueCollection request) {
+ ApplyLinkRequest applyRequest = new ApplyLinkRequest(request, _Settings);
+ return applyRequest.Retrieve();
+ }
+
+ ///
+ /// Gets the ApplyLink for a Job
+ ///
+ /// An ApplyLink values collection to pass to the api.
+ /// The uri to apply to the given job.
+ public string ApplyLink(ApplyLink request) {
+ ApplyLinkRequest applyRequest = new ApplyLinkRequest(request, _Settings);
+ return applyRequest.Retrieve();
+ }
+
+ ///
+ /// Submit an application to /v1/application/submit
+ ///
+ /// The application being submited to careerbuilder
+ ///
+ public ResponseApplication SubmitApplication(Application app) {
+ RequestApplication req = new RequestApplication();
+ req.CoBrand = app.CoBrand;
+ req.DeveloperKey = app.DeveloperKey;
+ req.JobDID = app.JobDID;
+ req.SiteID = app.SiteID;
+ req.Test = app.Test;
+ req.Resume = app.Resume;
+ List responses = new List();
+ foreach (var item in app.Questions) {
+ responses.Add(new Response() { QuestionID = item.QuestionID, ResponseText = item.ResponseText });
+ }
+ req.Responses = responses;
+ return SubmitApplication(req);
+ }
+
+ ///
+ /// Submit an application to /v1/application/submit
+ ///
+ /// The application being submited to careerbuilder
+ ///
+ public ResponseApplication SubmitApplication(RequestApplication app) {
+ var req = new SubmitApplicationRequest(_Settings);
+ WireBeforeRequestEvents(req);
+ WireAfterRequestEvents(req);
+ return req.Submit(app);
+ }
+
+ ///
+
+ /// create a saved search
+ ///
+ /// the saved search that is wanting to be saved
+ ///
+ public SavedSearchCreateResponse CreateSavedSearch(SavedSearchCreate app) {
+ var req = new SavedSearchCreateRequest(_Settings);
+ WireBeforeRequestEvents(req);
+ WireAfterRequestEvents(req);
+ return req.Submit(app);
+ }
+
+ ///
+ /// Retrieve a single saved search
+ ///
+ /// Info to lead to the saved search
+ ///
+ public SavedSearchRetrieveResponseModel RetrieveSavedSearch(SavedSearchRetrieveRequestModel app) {
+ var req = new SavedSearchRetrieveRequest(_Settings);
+ WireBeforeRequestEvents(req);
+ WireAfterRequestEvents(req);
+ return req.Submit(app);
+ }
+
+ ///
+ /// Lists all saved searches from a single user
+ ///
+ /// info to lead to the users saved searches
+ ///
+ public SavedSearchListResponseModel ListSavedSearches(SavedSearchListRequestModel app) {
+ var req = new SavedSearchListRequest(_Settings);
+ WireBeforeRequestEvents(req);
+ WireAfterRequestEvents(req);
+ return req.Submit(app);
+ }
+
+ ///
+ /// Updates a SavedSearch
+ ///
+ /// The data for the savedsearch
+ ///
+ public SavedSearchUpdateResponseModel UpdateSavedSearch(SavedSearchUpdateRequestModel app) {
+ var req = new SavedSearchUpdateRequest(_Settings);
+ WireBeforeRequestEvents(req);
+ WireAfterRequestEvents(req);
+ return req.Submit(app);
+ }
+
+ /// Delete a saved search with /v1/savedsearch/delete.xml
+ ///
+ /// The search being deleted
+ ///
+ public SavedSearchDeleteResponse DeleteSavedSearchXML(RequestSavedSearchDelete search) {
+ var req = new SavedSearchDeleteRequest(_Settings);
+ WireBeforeRequestEvents(req);
+ WireAfterRequestEvents(req);
+ return req.Submit(search);
+ }
+
+ ///
+ /// Anonymous apply with /v2/Application/submit
+ ///
+ /// the input for the application
+ ///
+ public AnonymousApplicationResponse AnonymousApplication(AnonymousApplicationRequest request) {
+ var req = new AnonymousApplication(_Settings);
+ WireBeforeRequestEvents(req);
+ WireAfterRequestEvents(req);
+ return req.Submit(request);
+ }
+
+ ///
+ /// Make a call to /v1/categories
+ ///
+ /// A Category Request to query against
+ public ICategoryRequest GetCategories() {
+ var req = new CategoriesRequest(_Settings);
+ WireBeforeRequestEvents(req);
+ WireAfterRequestEvents(req);
+ return req;
+ }
+
+ ///
+ /// Make a call to /v1/educationcodes
+ ///
+ /// A Educationcodes Request to query against
+ public IEducationCodesRequest GetEducationCodes()
+ {
+ var req = new EducationCodesRequest(_Settings);
+ WireBeforeRequestEvents(req);
+ WireAfterRequestEvents(req);
+ return req;
+ }
+
+ ///
+ /// Make a call to /v1/employeetypes
+ ///
+ /// A Employee Request to query against
+ public IEmployeeTypesRequest GetEmployeeTypes() {
+ var req = new EmployeeTypesRequest(_Settings);
+ WireBeforeRequestEvents(req);
+ WireAfterRequestEvents(req);
+ return req;
+ }
+
+ ///
+ /// Make a call to /v1/job
+ ///
+ /// The unique ID of the job
+ /// The job
+ public Job GetJob(string jobDid) {
+ var req = new JobRequest(jobDid, _Settings);
+ WireBeforeRequestEvents(req);
+ WireAfterRequestEvents(req);
+ return req.Retrieve();
+ }
+
+ ///
+ /// Make a call to /v1/recommendations/forjob
+ ///
+ /// The unique ID of the job
+ /// The list of recommended jobs, based on the given job.
+ public List GetRecommendationsForJob(string jobDid) {
+ var req = new JobRecommendationsRequest(jobDid, _Settings);
+ WireBeforeRequestEvents(req);
+ WireAfterRequestEvents(req);
+ return req.GetRecommendations();
+ }
+
+ ///
+ /// Make a call to /v1/recommendations/forjobwithuserprefs
+ ///
+ /// The unique ID of the job
+ /// The unique ID of the user
+ /// The list of recommended jobs, based on the given job and taking the user's preferences into account.
+ public List GetRecommendationsForJobWithUserPreferences(string jobDid, string userDid) {
+ var req = new JobRecommendationsWithUserPreferencesRequest(jobDid, userDid, _Settings);
+ WireBeforeRequestEvents(req);
+ WireAfterRequestEvents(req);
+ return req.GetRecommendations();
+ }
+
+ ///
+ /// make a call to /v1/recommendations/foruser
+ ///
+ /// The ID of the user that you wish to get recs for
+ ///
+ public List GetRecommendationsForUser(string externalId) {
+ var req = new UserRecommendationsRequest(new ExternalID(externalId), _Settings);
+ WireBeforeRequestEvents(req);
+ WireAfterRequestEvents(req);
+ return req.GetRecommendations();
+ }
+
+ ///
+ /// Make a call to /v1/jobsearch
+ ///
+ /// A Job Request to query against
+ public IJobSearch JobSearch() {
+ var req = new JobSearchRequest(_Settings);
+ WireBeforeRequestEvents(req);
+ WireAfterRequestEvents(req);
+ return req;
+ }
+
+ public ResponseJobReport JobReport(string jobDid) {
+ var req = new JobReportRequest(jobDid, _Settings);
+ WireBeforeRequestEvents(req);
+ WireAfterRequestEvents(req);
+ return req.GetReport();
+ }
+
+ public Models.WebAPIs.SavedSearch.SavedSearches RetrieveASavedSearch(string savedSearchDID, string userOAuthToken) {
+ var req = new RetrieveASavedSearch(_Settings, savedSearchDID);
+ WireBeforeRequestEvents(req);
+ WireAfterRequestEvents(req);
+ return req.Submit(userOAuthToken);
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/CBApi/CBApi.csproj b/CBApi/CBApi.csproj
new file mode 100644
index 0000000..4de1b51
--- /dev/null
+++ b/CBApi/CBApi.csproj
@@ -0,0 +1,168 @@
+
+
+
+ Debug
+ AnyCPU
+ 8.0.30703
+ 2.0
+ {58C4C156-4095-4F29-AF07-72722D262261}
+ Library
+ Properties
+ CBApi
+ CBApi
+ v4.0
+ 512
+ ..\
+ true
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+ ..\packages\Newtonsoft.Json.6.0.8\lib\net40\Newtonsoft.Json.dll
+
+
+ ..\packages\RestSharp.104.3.3\lib\net4\RestSharp.dll
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ True
+ True
+ Settings.settings
+
+
+
+
+
+
+
+ SettingsSingleFileGenerator
+ Settings.Designer.cs
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/CBApi/CBApi.nuspec b/CBApi/CBApi.nuspec
new file mode 100644
index 0000000..027b4cf
--- /dev/null
+++ b/CBApi/CBApi.nuspec
@@ -0,0 +1,22 @@
+
+
+
+ $id$
+ $version$
+ CareerBuilder.com API C# Client Library
+ Jeffery Yeary
+ $author$
+ https://github.com/usbsnowcrash/Careerbuilder.com-API-for-.Net/blob/master/LICENSE
+ https://github.com/usbsnowcrash/Careerbuilder.com-API-for-.Net/wiki
+ https://github.com/usbsnowcrash/Careerbuilder.com-API-for-.Net/tree/master/NuPKG/career_builder_icon.jpg
+ false
+ $description$
+
+
+
+ @ CareerBuilder LLC, Jeffery Yeary
+ REST HTTP API JSON XML Careerbuilder Careerbuilders
+
+
\ No newline at end of file
diff --git a/CBApi/ErrorResponse.cs b/CBApi/ErrorResponse.cs
new file mode 100644
index 0000000..75955a4
--- /dev/null
+++ b/CBApi/ErrorResponse.cs
@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace CBApi {
+ public class ErrorResponse {
+ public Errors Errors { get; set; }
+ public string TimeResponseSent { get; set; }
+ public string TimeElapsed { get; set; }
+ }
+
+ public class Errors {
+ public string Error { get; set; }
+ }
+}
diff --git a/CBApi/Framework/ErrorParser.cs b/CBApi/Framework/ErrorParser.cs
new file mode 100644
index 0000000..d8b2e68
--- /dev/null
+++ b/CBApi/Framework/ErrorParser.cs
@@ -0,0 +1,116 @@
+using Newtonsoft.Json.Linq;
+using RestSharp;
+using RestSharp.Deserializers;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Xml;
+using System.Xml.Linq;
+
+namespace CBApi.Framework {
+ internal class ErrorParser {
+
+ public static void CheckForErrors(IRestResponse response) {
+ if (response != null) {
+ ParseResponseForErrorsNode(response);
+ CheckRestSharpForErrorStatus(response);
+ }
+ }
+
+ private static void ParseResponseForErrorsNode(IRestResponse response) {
+ if (string.IsNullOrWhiteSpace(response.Content)) {
+ return;
+ }
+
+ if ((response.ContentType ?? "").ToLower().StartsWith("application/json")) {
+ ParseJSONForErrorsNode(response);
+ } else {
+ ParseXmlForErrorsNode(response);
+ }
+ }
+
+ private static void ParseXmlForErrorsNode(IRestResponse response) {
+ var errors = new List();
+ var xml = new XmlDocument();
+
+ string filteredXmlContent = GetXmlContentWithoutNamespaces(response.Content);
+ xml.LoadXml(filteredXmlContent);
+
+ //xml.LoadXml(response.Content);
+ foreach (XmlNode item in xml.SelectNodes("//Error")) {
+ if (!string.IsNullOrEmpty(item.InnerText)) {
+ errors.Add(item.InnerText);
+ }
+ }
+
+ if (errors.Count == 0) {
+ XmlNode errorsNode = xml.SelectSingleNode("//Errors");
+ if (errorsNode != null) {
+ foreach (XmlNode error in errorsNode.SelectNodes("//string")) {
+ errors.Add(error.InnerText);
+ }
+ }
+ }
+
+ if (errors.Count > 0) {
+ throw new APIException(errors[0], errors);
+ }
+ }
+
+ //Implemented based on interface, not part of algorithm
+ public static string GetXmlContentWithoutNamespaces(string xmlDocument) {
+ XElement xmlDocumentWithoutNamespaces = RemoveAllNamespaces(XElement.Parse(xmlDocument));
+ return xmlDocumentWithoutNamespaces.ToString();
+ }
+
+ //Core recursion function
+ private static XElement RemoveAllNamespaces(XElement xmlDocument) {
+ if (!xmlDocument.HasElements) {
+ XElement xElement = new XElement(xmlDocument.Name.LocalName);
+ xElement.Value = xmlDocument.Value;
+
+ foreach (XAttribute attribute in xmlDocument.Attributes())
+ xElement.Add(attribute);
+
+ return xElement;
+ }
+ return new XElement(xmlDocument.Name.LocalName, xmlDocument.Elements().Select(el => RemoveAllNamespaces(el)));
+ }
+
+ private static void ParseJSONForErrorsNode(IRestResponse response) {
+ if (!String.IsNullOrWhiteSpace(response.Content)) {
+ var errors = new List();
+
+ JObject json = JObject.Parse(response.Content);
+ foreach (string error in json["Errors"].Select(e => (String)e).ToList()) {
+ if (!String.IsNullOrWhiteSpace(error))
+ errors.Add(error);
+ }
+
+ if (errors.Count > 0) {
+ throw new APIException(errors[0], errors);
+ }
+ }
+ }
+
+ private static void CheckRestSharpForErrorStatus(IRestResponse response) {
+ if (response.ResponseStatus == ResponseStatus.TimedOut) {
+ if (!string.IsNullOrEmpty(response.ErrorMessage)) {
+ throw new APITimeoutException(response.ErrorMessage);
+ } else {
+ throw new APITimeoutException("An unknown error occured while making the API call");
+ }
+
+ } else if (response.ResponseStatus != ResponseStatus.Completed) {
+ if (!string.IsNullOrEmpty(response.ErrorMessage)) {
+ throw new APIException(response.ErrorMessage);
+ } else {
+ throw new APIException("An unknown error occured while making the API call");
+ }
+
+ }
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/CBApi/Framework/RequestEventData.cs b/CBApi/Framework/RequestEventData.cs
new file mode 100644
index 0000000..72b0b4b
--- /dev/null
+++ b/CBApi/Framework/RequestEventData.cs
@@ -0,0 +1,48 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using RestSharp;
+namespace CBApi.Framework {
+ [Serializable]
+ internal class RequestEventData : IRequestEventData {
+ private string _BaseURL = "";
+ private string _Method = "";
+ private string _ResponseContent = "";
+ private Dictionary _Parameters = new Dictionary();
+
+ public RequestEventData(IRestClient client, IRestRequest request, IRestResponse response) {
+ if (client != null) {
+ _BaseURL = client.BaseUrl;
+ }
+ if (request != null) {
+ _Method = request.Method.ToString();
+ if (request.Parameters != null) {
+ foreach (var item in request.Parameters) {
+ _Parameters.Add(item.Name, item.Value.ToString());
+ }
+ }
+
+ }
+ if (response != null) {
+ _ResponseContent = response.Content;
+ }
+ }
+
+ public string BaseURL {
+ get { return _BaseURL; }
+ }
+
+ public string Method {
+ get { return _Method; }
+ }
+
+ public string ResponseContent {
+ get { return _ResponseContent; }
+ }
+
+ public Dictionary Parameters {
+ get { return _Parameters; }
+ }
+ }
+}
diff --git a/CBApi/Framework/events/Events.cs b/CBApi/Framework/events/Events.cs
new file mode 100644
index 0000000..c3a743a
--- /dev/null
+++ b/CBApi/Framework/events/Events.cs
@@ -0,0 +1,10 @@
+using RestSharp;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace CBApi.Framework.Events {
+ public delegate void BeforeRequestEvent(IRequestEventData data);
+ public delegate void AfterRequestEvent(IRequestEventData data);
+}
diff --git a/CBApi/Framework/requests/AnonymousApplication.cs b/CBApi/Framework/requests/AnonymousApplication.cs
new file mode 100644
index 0000000..b38f57e
--- /dev/null
+++ b/CBApi/Framework/requests/AnonymousApplication.cs
@@ -0,0 +1,34 @@
+using CBApi.Models;
+using RestSharp;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace CBApi.Framework.Requests
+{
+ internal class AnonymousApplication : PostRequest
+ {
+ private string DeveloperKey { get; set; }
+ public AnonymousApplication(APISettings settings)
+ : base(settings)
+ {
+ DeveloperKey = settings.DevKey;
+ }
+
+ public override string BaseUrl
+ {
+ get { return "/v2/Application/submit"; }
+ }
+
+ public AnonymousApplicationResponse Submit(AnonymousApplicationRequest request)
+ {
+ _request.AddBody(request);
+ base.BeforeRequest();
+ request.DeveloperKey=DeveloperKey;
+ IRestResponse response = _client.Execute(_request);
+ CheckForErrors(response);
+ return response.Data;
+ }
+ }
+}
diff --git a/CBApi/Framework/requests/ApplicationFormRequest.cs b/CBApi/Framework/requests/ApplicationFormRequest.cs
new file mode 100644
index 0000000..64bf5ea
--- /dev/null
+++ b/CBApi/Framework/requests/ApplicationFormRequest.cs
@@ -0,0 +1,44 @@
+using System;
+using RestSharp;
+
+namespace CBApi.Framework.Requests
+{
+ internal class ApplicationFormRequest : GetRequest
+ {
+ protected string JobDid = "";
+
+ public ApplicationFormRequest(string jobDid, APISettings settings)
+ : base(settings)
+ {
+ if (string.IsNullOrEmpty(jobDid))
+ {
+ throw new ArgumentNullException();
+ }
+
+ if (jobDid.Length >= 18 && jobDid.Length <= 20 &&
+ jobDid.StartsWith("J", StringComparison.InvariantCultureIgnoreCase))
+ {
+ JobDid = jobDid;
+ }
+ else
+ {
+ throw new ArgumentException("This does not look like a job did");
+ }
+ }
+
+ public override string BaseUrl
+ {
+ get { return "/v1/application/form"; }
+ }
+
+ public string Retrieve()
+ {
+ _request.AddParameter("JobDID", JobDid);
+ base.BeforeRequest();
+ IRestResponse response = _client.Execute(_request);
+ _AfterRequestEvent(new RequestEventData(_client, _request, response));
+ CheckForErrors(response);
+ return response.Content;
+ }
+ }
+}
\ No newline at end of file
diff --git a/CBApi/Framework/requests/ApplyLinkRequest.cs b/CBApi/Framework/requests/ApplyLinkRequest.cs
new file mode 100644
index 0000000..ac6f674
--- /dev/null
+++ b/CBApi/Framework/requests/ApplyLinkRequest.cs
@@ -0,0 +1,45 @@
+using CBApi.Models;
+using RestSharp;
+using System;
+using System.Collections.Specialized;
+using System.Reflection;
+
+namespace CBApi.Framework.Requests
+{
+ internal class ApplyLinkRequest : GetRequest
+ {
+ protected ApplyLink model;
+
+ public ApplyLinkRequest(NameValueCollection args, APISettings settings) :
+ this(new ApplyLink(args), settings) { }
+
+ public ApplyLinkRequest(ApplyLink args, APISettings settings)
+ : base(settings)
+ {
+ if (args == null) {
+ throw new ArgumentException();
+ }
+ model = args;
+ }
+
+ public override string BaseUrl {
+ get { return "/v2/application/applylink"; }
+ }
+
+ public string Retrieve()
+ {
+ foreach (PropertyInfo property in model.GetType().GetProperties())
+ {
+ var value = property.GetValue(model, null);
+ if (value != null)
+ {
+ _request.AddParameter(property.Name, value);
+ }
+ }
+ base.BeforeRequest();
+ IRestResponse response = _client.Execute(_request);
+ _AfterRequestEvent(new RequestEventData(_client, _request, response));
+ return response.ResponseUri.ToString();
+ }
+ }
+}
diff --git a/CBApi/Framework/requests/AuthTokenRequest.cs b/CBApi/Framework/requests/AuthTokenRequest.cs
new file mode 100644
index 0000000..a0e0ecc
--- /dev/null
+++ b/CBApi/Framework/requests/AuthTokenRequest.cs
@@ -0,0 +1,54 @@
+using System;
+using RestSharp;
+using CBApi.Models;
+
+namespace CBApi.Framework.Requests {
+ internal class AuthTokenRequest : GetRequest {
+ protected string _ClientId = "";
+ protected string _ClientSecret = "";
+ protected string _Code = "";
+ protected string _RedirectUri = "";
+
+ internal AuthTokenRequest(string clientId, string clientSecret, string code, string redirectUri, APISettings settings)
+ : base(settings) {
+
+ if (string.IsNullOrEmpty(clientId)) {
+ throw new ArgumentNullException();
+ }
+
+ if (string.IsNullOrEmpty(clientSecret)) {
+ throw new ArgumentNullException();
+ }
+
+ if (string.IsNullOrEmpty(code)) {
+ throw new ArgumentNullException();
+ }
+
+ if (string.IsNullOrEmpty(redirectUri)) {
+ throw new ArgumentNullException();
+ }
+
+ _ClientId = clientId;
+ _ClientSecret = clientSecret;
+ _Code = code;
+ _RedirectUri = redirectUri;
+
+ }
+
+ public override string BaseUrl {
+ get { return "/auth/token"; }
+ }
+
+ public AccessToken GetAccessToken() {
+ _request.AddParameter("client_id", _ClientId);
+ _request.AddParameter("client_secret", _ClientSecret);
+ _request.AddParameter("redirect_uri", _RedirectUri);
+ _request.AddParameter("code", _Code);
+ base.BeforeRequest();
+ IRestResponse response = _client.Execute(_request);
+ _AfterRequestEvent(new RequestEventData(_client, _request, response));
+ CheckForErrors(response);
+ return response.Data;
+ }
+ }
+}
\ No newline at end of file
diff --git a/CBApi/Framework/requests/BaseRequest.cs b/CBApi/Framework/requests/BaseRequest.cs
new file mode 100644
index 0000000..058c901
--- /dev/null
+++ b/CBApi/Framework/requests/BaseRequest.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using CBApi.Framework.Events;
+
+namespace CBApi.Framework.Requests {
+ public abstract class BaseRequest {
+ protected BeforeRequestEvent _BeforeRequestEvent = delegate { };
+ protected AfterRequestEvent _AfterRequestEvent = delegate { };
+
+ internal event BeforeRequestEvent OnBeforeRequest {
+ add { _BeforeRequestEvent += value; }
+ remove { _BeforeRequestEvent += value; }
+ }
+
+ internal event AfterRequestEvent OnAfterRequest {
+ add { _AfterRequestEvent += value; }
+ remove { _AfterRequestEvent += value; }
+ }
+ }
+}
diff --git a/CBApi/Framework/requests/BlankApplicationRequest.cs b/CBApi/Framework/requests/BlankApplicationRequest.cs
new file mode 100644
index 0000000..e43d595
--- /dev/null
+++ b/CBApi/Framework/requests/BlankApplicationRequest.cs
@@ -0,0 +1,57 @@
+using System;
+using RestSharp;
+using CBApi.Models;
+using System.Net;
+
+namespace CBApi.Framework.Requests
+{
+ internal class BlankApplicationRequest : GetRequest
+ {
+ protected string JobDid = "";
+
+
+
+ public BlankApplicationRequest(string jobDid, APISettings settings)
+ : base(settings)
+ {
+ if (string.IsNullOrEmpty(jobDid))
+ {
+ throw new ArgumentNullException();
+ }
+
+ if (jobDid.Length >= 18 && jobDid.Length <= 20 &&
+ jobDid.StartsWith("J", StringComparison.InvariantCultureIgnoreCase))
+ {
+ JobDid = jobDid;
+ }
+ else
+ {
+ throw new ArgumentException("This does not look like a job did");
+ }
+ ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Ssl3 | (SecurityProtocolType)768 | (SecurityProtocolType)3072;
+ }
+
+ public override string BaseUrl
+ {
+ get { return "/v1/application/blank"; }
+ }
+
+ public BlankApplication Retrieve()
+ {
+ _request.AddParameter("JobDID", JobDid);
+ _request.RootElement = "BlankApplication";
+ base.BeforeRequest();
+ IRestResponse response = _client.Execute(_request);
+ _AfterRequestEvent(new RequestEventData(_client, _request, response));
+ CheckForErrors(response);
+ BlankApplication app = response.Data;
+ if (app != null)
+ {
+ app.SiteID = _Settings.SiteId;
+ app.CoBrand = _Settings.CobrandCode;
+ app.DeveloperKey = _Settings.DevKey;
+ }
+ return app;
+ }
+ }
+}
\ No newline at end of file
diff --git a/CBApi/Framework/requests/CategoriesRequest.cs b/CBApi/Framework/requests/CategoriesRequest.cs
new file mode 100644
index 0000000..27513fc
--- /dev/null
+++ b/CBApi/Framework/requests/CategoriesRequest.cs
@@ -0,0 +1,49 @@
+using System.Collections.Generic;
+using RestSharp;
+using CBApi.Models;
+using CBApi.Models.Service;
+
+namespace CBApi.Framework.Requests
+{
+ internal class CategoriesRequest : GetRequest, ICategoryRequest
+ {
+ protected string _countryCode = "US";
+
+ public CategoriesRequest(APISettings settings)
+ : base(settings)
+ {
+ }
+
+ public override string BaseUrl
+ {
+ get { return "/v1/categories"; }
+ }
+
+ #region ICategoryRequest Members
+
+ public ICategoryRequest WhereCountryCode(CountryCode value)
+ {
+ _countryCode = value.ToString();
+ return this;
+ }
+
+ public ICategoryRequest WhereHostSite(HostSite value)
+ {
+ _countryCode = value.ToString();
+ return this;
+ }
+
+ public List ListAll()
+ {
+ _request.AddParameter("CountryCode", _countryCode);
+ _request.RootElement = "Categories";
+ base.BeforeRequest();
+ IRestResponse> response = _client.Execute>(_request);
+ _AfterRequestEvent(new RequestEventData(_client, _request, response));
+ CheckForErrors(response);
+ return response.Data;
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/CBApi/Framework/requests/EducationCodesRequest.cs b/CBApi/Framework/requests/EducationCodesRequest.cs
new file mode 100644
index 0000000..a43fd22
--- /dev/null
+++ b/CBApi/Framework/requests/EducationCodesRequest.cs
@@ -0,0 +1,38 @@
+using System.Collections.Generic;
+using RestSharp;
+using CBApi.Models;
+using CBApi.Models.Service;
+
+namespace CBApi.Framework.Requests
+{
+ internal class EducationCodesRequest : GetRequest, IEducationCodesRequest
+ {
+ protected string _countryCode = "US";
+
+ public EducationCodesRequest(APISettings settings) : base(settings) { }
+
+ public override string BaseUrl
+ {
+ get { return "/v1/educationcodes"; }
+ }
+
+ #region IEducationCodesRequest Members
+ public IEducationCodesRequest WhereCountryCode(CountryCode value)
+ {
+ _countryCode = value.ToString();
+ return this;
+ }
+
+ public List ListAll()
+ {
+ _request.AddParameter("CountryCode", _countryCode);
+ _request.RootElement = "EducationCodes";
+ base.BeforeRequest();
+ IRestResponse> response = _client.Execute>(_request);
+ _AfterRequestEvent(new RequestEventData(_client, _request, response));
+ CheckForErrors(response);
+ return response.Data;
+ }
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/CBApi/Framework/requests/EmployeeTypesRequest.cs b/CBApi/Framework/requests/EmployeeTypesRequest.cs
new file mode 100644
index 0000000..e94c4c1
--- /dev/null
+++ b/CBApi/Framework/requests/EmployeeTypesRequest.cs
@@ -0,0 +1,48 @@
+using System.Collections.Generic;
+using RestSharp;
+using CBApi.Models;
+using CBApi.Models.Service;
+
+namespace CBApi.Framework.Requests
+{
+ internal class EmployeeTypesRequest : GetRequest, IEmployeeTypesRequest
+ {
+ protected string _countryCode = "US";
+
+ public EmployeeTypesRequest(APISettings settings)
+ : base(settings)
+ {
+ }
+
+ public override string BaseUrl
+ {
+ get { return "/v1/employeetypes"; }
+ }
+
+ #region IEmployeeTypesRequest Members
+
+ public IEmployeeTypesRequest WhereCountryCode(CountryCode value)
+ {
+ _countryCode = value.ToString();
+ return this;
+ }
+
+ public IEmployeeTypesRequest WhereHostSite(HostSite value)
+ {
+ _countryCode = value.ToString();
+ return this;
+ }
+
+ public List ListAll()
+ {
+ _request.AddParameter("CountryCode", _countryCode);
+ _request.RootElement = "EmployeeTypes";
+ base.BeforeRequest();
+ IRestResponse> response = _client.Execute>(_request);
+ CheckForErrors(response);
+ return response.Data;
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/CBApi/Framework/requests/GetRequest.cs b/CBApi/Framework/requests/GetRequest.cs
new file mode 100644
index 0000000..09a7d26
--- /dev/null
+++ b/CBApi/Framework/requests/GetRequest.cs
@@ -0,0 +1,74 @@
+using System;
+using System.Text;
+using System.Xml;
+using System.Linq;
+using RestSharp;
+using System.Collections.Generic;
+using CBApi.Framework.Events;
+
+namespace CBApi.Framework.Requests {
+ public abstract class GetRequest : BaseRequest {
+ protected APISettings _Settings = null;
+
+ protected IRestClient _client = new RestClient();
+ protected IRestRequest _request = new RestRequest();
+
+ protected GetRequest(APISettings settings) {
+ if (settings == null) {
+ throw new ArgumentNullException("settings", "You must provide valid API Settings");
+ }
+ _Settings = settings;
+
+ if (string.IsNullOrEmpty(settings.DevKey)) {
+ throw new ArgumentNullException("DevKey", "Please provide a valid developer key");
+ }
+
+ if (settings.TargetSite == null) {
+ throw new ArgumentNullException("TargetSite", "Please provide a valid domain name");
+ }
+
+ if (settings.TargetSite != null && string.IsNullOrEmpty(settings.TargetSite.Domain)) {
+ throw new ArgumentNullException("TargetSite", "Please provide a valid domain name");
+ }
+ }
+
+ public abstract string BaseUrl { get; }
+
+ protected virtual string GetRequestURL() {
+ var url = new StringBuilder(20);
+ if (_Settings.TargetSite.Secure) {
+ url.Append("https://");
+ } else {
+ url.Append("http://");
+ }
+ url.Append(_Settings.TargetSite.Domain);
+ url.Append(this.BaseUrl);
+ return url.ToString();
+ }
+
+ protected virtual void BeforeRequest() {
+ _client.BaseUrl = GetRequestURL();
+ _request.AddParameter("DeveloperKey", _Settings.DevKey);
+
+ if (!string.IsNullOrEmpty(_Settings.CobrandCode)) {
+ _request.AddParameter("CoBrand", _Settings.CobrandCode);
+ }
+
+ if (!string.IsNullOrEmpty(_Settings.SiteId)) {
+ _request.AddParameter("SiteID", _Settings.SiteId);
+ }
+ _request.Timeout = _Settings.TimeoutMS;
+ if (!string.IsNullOrEmpty(_Settings.TargetSite.Host)) {
+ _request.AddHeader("Host", _Settings.TargetSite.Host);
+ }
+ foreach (var item in _Settings.TargetSite.Headers) {
+ _request.AddHeader(item.Key,item.Value);
+ }
+ _BeforeRequestEvent(new RequestEventData(_client, _request, null));
+ }
+
+ protected virtual void CheckForErrors(IRestResponse response) {
+ ErrorParser.CheckForErrors(response);
+ }
+ }
+}
\ No newline at end of file
diff --git a/CBApi/Framework/requests/JobRecommendationsRequest.cs b/CBApi/Framework/requests/JobRecommendationsRequest.cs
new file mode 100644
index 0000000..329c222
--- /dev/null
+++ b/CBApi/Framework/requests/JobRecommendationsRequest.cs
@@ -0,0 +1,36 @@
+using System.Collections.Generic;
+using RestSharp;
+using CBApi.Models;
+using System;
+
+namespace CBApi.Framework.Requests {
+ internal class JobRecommendationsRequest : GetRequest {
+ protected string _jobDid = "";
+
+ public JobRecommendationsRequest(string jobDid, APISettings settings) : base(settings) {
+ if (string.IsNullOrEmpty(jobDid)) {
+ throw new ArgumentNullException();
+ }
+ if (jobDid.Length >= 18 && jobDid.Length <= 20 &&
+ jobDid.StartsWith("J", StringComparison.InvariantCultureIgnoreCase)) {
+ _jobDid = jobDid;
+ } else {
+ throw new ArgumentException("This does not look like a jobDid");
+ }
+ }
+
+ public override string BaseUrl {
+ get { return "/v2/recommendations/forjob"; }
+ }
+
+ public List GetRecommendations() {
+ _request.AddParameter("JobDID", _jobDid);
+ _request.AddParameter("ShowMoreFields", true);
+ _request.RootElement = "RecommendJobResults";
+ BeforeRequest();
+ IRestResponse> response = _client.Execute