//[Koan(Order = 3)] public void YouCanListenToMultipleStreamsOverASingleConnection() { var ukNewsListener = _streamingClient.BuildNewsHeadlinesListener("UK"); var gbpusdPriceListener = _streamingClient.BuildPricesListener(154297); //Build as many listeners as you want var ukNewsHeadlines = new List <NewsDTO>(); ukNewsListener.MessageReceived += (sender, message) => ukNewsHeadlines.Add(message.Data); var gbpusdPrices = new List <PriceDTO>(); gbpusdPriceListener.MessageReceived += (sender, message) => gbpusdPrices.Add(message.Data); //Wait whilst some data is connected new AutoResetEvent(false).WaitOne(20000); //Remember to tear them down when you are done _streamingClient.TearDownListener(ukNewsListener); _streamingClient.TearDownListener(gbpusdPriceListener); KoanAssert.That(ukNewsHeadlines.Count, Is.GreaterThan(8), "On the mock news headlines stream we should get 1 headline per second"); KoanAssert.That(gbpusdPrices.Count, Is.GreaterThanOrEqualTo(1), "GBP/USD Prices should come through fairly regularly"); }
public void ExceptionsOnAsyncMethodsNeedToBeManagedCarefully() { const int maxHeadlines = 500; var gate = new ManualResetEvent(false); ListNewsHeadlinesResponseDTO listNewsHeadlinesResponseDto = null; _rpcClient.News.BeginListNewsHeadlinesWithSource( source: "dj", category: "UK", maxResults: maxHeadlines + 1, callback: (response) => { try { listNewsHeadlinesResponseDto = _rpcClient.News.EndListNewsHeadlinesWithSource(response); } catch (ReliableHttpException ex) { Console.WriteLine("ResponseTest: {0}", ex.ResponseText); KoanAssert.That(ex.Message, Is.StringContaining("You cannot request more than 500 news headlines"), "The error will talk about 'You cannot request more than 500 news headlines'"); } gate.Set(); }, state: null); gate.WaitOne(TimeSpan.FromSeconds(60)); //Never wait indefinately }
//[Koan(Order = 2)] public void YouListenToAStreamsOverAConnection() { //Beginning with a connected streamingClient, you create a listener expected a specific message type on a certain channel/topic const string topic = "UK"; //The mock news headlines stream publishes one "story" per second. var ukNewsListener = _streamingClient.BuildNewsHeadlinesListener(topic); var ukNewsHeadlines = new List <NewsDTO>(); ukNewsListener.MessageReceived += (sender, message) => /* The MessageReceived event is raised every time a new message arrives */ { ukNewsHeadlines.Add(message.Data); //Its data property contains a typed DTO }; //You call start to begin listening //Wait whilst some data is connected new AutoResetEvent(false).WaitOne(20000); //And tear down to finish _streamingClient.TearDownListener(ukNewsListener); KoanAssert.That(ukNewsHeadlines.Count, Is.GreaterThan(3), "On the mock news headlines stream we should get 1 headline per second"); }
public void AskingForAnInvalidStoryIdWillGetYouNullStoryDetails() { const int invalidStoryId = Int32.MaxValue; var newsStory = _rpcClient.News.GetNewsDetail("dj", storyId: invalidStoryId.ToString()); KoanAssert.That(newsStory.NewsDetail, Is.EqualTo(null), "There are no details for an invalid story Id"); }
public void UsingTheStoryIdYouCanFetchTheStoryDetails() { var newsStory = _rpcClient.News.GetNewsDetail("dj", _ukHeadlines.Headlines[0].StoryId.ToString()); KoanAssert.That(newsStory.NewsDetail.Story, Is.Not.Null.Or.Empty, "You now have the full body of the news story"); //KoanAssert.That(newsStory.NewsDetail.Story, Is.StringContaining("<p>"), "which contains simple HTML"); }
public void ButGenerallyYouWillNeedToChangeTheCodeToMakeTheKoanPass() { //Fix this sum so that the Koan assertion is correct const string answer = "42"; KoanAssert.That(answer, Is.EqualTo(FILL_ME_IN), "the assertion should be true"); }
public void UsingNewsRequiresAValidSession() { _rpcClient = new Rpc.Client(Settings.RpcUri, Settings.StreamingUri, AppKey); _rpcClient.LogIn(USERNAME, PASSWORD); KoanAssert.That(_rpcClient.Session, Is.Not.Null.Or.Empty, "after logging in, you should have a valid session"); }
// DAVID: we have a serious issue regarding subsequent exceptions (i am working on it)- as it is you get one exception, pick one. // I think the 'be diligent catching async errors' is more important. public void AskingForTooManyHeadlinesIsConsideredABadRequest() { try { const int maxHeadlines = 500; _ukHeadlines = _rpcClient.News.ListNewsHeadlinesWithSource("dj", category: "UK", maxResults: maxHeadlines + 1); } catch (Exception ex) { KoanAssert.That(ex.Message, Is.StringContaining("You cannot request more than 500 news headlines"), "The error will talk about 'You cannot request more than 500 news headlines'"); } }
public void YouCanFetchTheLatestNewsHeadlines() { const int numberOfHeadlines = 25; _ukHeadlines = _rpcClient.News.ListNewsHeadlinesWithSource("dj", category: "UK", maxResults: numberOfHeadlines); _ausHeadlines = _rpcClient.News.ListNewsHeadlinesWithSource("dj", category: "AUS", maxResults: numberOfHeadlines); KoanAssert.That(_ukHeadlines.Headlines.Length, Is.EqualTo(25), "You should get the number of headlines requested"); //Each headline contains a StoryId, a Headline and a PublishDate KoanAssert.That(_ukHeadlines.Headlines[0].StoryId, Is.GreaterThan(0).And.LessThan(int.MaxValue), "StoryId is a positive integer"); // sky: not sure about this one.. requires user to guess or get the error and then come back. is this intended. KoanAssert.That(_ukHeadlines.Headlines[0].Headline, Is.Not.Null.Or.Empty, "Headline is a short string"); KoanAssert.That(_ukHeadlines.Headlines[0].PublishDate, Is.GreaterThan(new DateTime(2010, 12, 8)), "PublishDate is in UTC"); }
public void EveryRequestCanBeMadeAsyncronouslyToPreventHangingYourUIThread() { var gate = new ManualResetEvent(false); GetNewsDetailResponseDTO newsDetailResponseDto = null; _rpcClient.News.BeginGetNewsDetail( "dj", storyId: _ukHeadlines.Headlines[0].StoryId.ToString(), callback: (response) => { newsDetailResponseDto = _rpcClient.News.EndGetNewsDetail(response); gate.Set(); }, state: null); //DoStuffInCurrentThreadyWhilstRequestHappensInBackground(); gate.WaitOne(TimeSpan.FromSeconds(30)); //Never wait indefinately KoanAssert.That(newsDetailResponseDto.NewsDetail.Story, Is.Not.Null.Or.Empty, "You now have the full body of the news story"); //KoanAssert.That(newsDetailResponseDto.NewsDetail.Story, Is.StringContaining("<p>"), "You now have the full body of the news story"); }
public void YouCanForceYourSessionToExpireByLoggingOut() { _rpcClient.LogIn(USERNAME, PASSWORD); KoanAssert.That(_rpcClient.Session, Is.Not.Null, "You should have a valid sessionId after logon"); var oldSessionId = _rpcClient.Session; //Logging out force expires your session token on the server _rpcClient.LogOut(); //So that future requests with your old token will fail. try { _rpcClient.Session = oldSessionId; var headlines2 = _rpcClient.News.ListNewsHeadlinesWithSource("dj", "AUS", 4); KoanAssert.Fail("the previous line should have thrown an (401) Unauthorized exception"); } catch (ReliableHttpException e) { KoanAssert.That(e.Message, Is.StringContaining("Session is not valid"), "The error message should contain something about 'Session is not valid'"); } }
public void EveryRequestUsesYourSession() { //The rpcClient stores your current session details, and uses it to authenticate //every request. var headlines = _rpcClient.News.ListNewsHeadlinesWithSource("dj", "UK", 10); KoanAssert.That(headlines.Headlines.Length > 0, "you should have a set of headlines"); //When your sessionId expires _rpcClient.Session = "{an-expired-session-token}"; //Then future requests will fail. try { var headlines2 = _rpcClient.News.ListNewsHeadlinesWithSource("dj", "AUS", 10); KoanAssert.That(false, "the previous line should have thrown an (401) Unauthorized exception"); } catch (ReliableHttpException e) { KoanAssert.That(e.Message, Is.StringContaining("Session is not valid"), "The error message should contain something about 'Session is not valid'"); } }
public void CreatingASession() { //Interaction with the API is done via a top level "client" object //that holds details about your connection. //You need to initialise the client with a valid endpoint _rpcClient = new Rpc.Client(Settings.RpcUri, Settings.StreamingUri, AppKey); //And then create a session by creating a username & password //You can get test credentials by requesting them at https://ciapipreprod.cityindextest9.co.uk/CIAPI.docs/#content.test-credentials try { _rpcClient.LogIn(USERNAME, PASSWORD); } catch (ReliableHttpException apiException) { KoanAssert.Fail(string.Format("cannot login because {0}", apiException.Message)); } KoanAssert.That(_rpcClient.Session != "", "after logging in, you should have a valid session"); }
public void WhenAKoanPassesYouIncreaseYourKarma() { KoanAssert.That(true, "true is true"); }