public async void GetData_CalledTwice_UsesCacheSecondTime()
        {
            var campData = new CampData
            {
                Speakers = new List<Speaker> { new Speaker { Id = 1 }},
                Sessions = new List<Session> { new Session { Title = "Best Session Ever", Id = 42, SpeakerId = 1} }
            };
            bool clientCalled = false;
            _mockDataClient.GetDataBody = () =>
            {
                clientCalled = true;
                return Task.FromResult(campData);
            };

            var service = new CodeCampService(_fileManager, _jsonConverter, _mockDataClient);

            var data = await service.GetData();

            Assert.True(clientCalled);
            Assert.AreEqual(campData, data);

            _mockDataClient.GetDataBody = delegate { throw new Exception(); };

            data = await service.GetData();

            Assert.AreEqual(campData, data);
        }
        public async void Init_DataLoadsSuccessfully_LoadsTimeSlots()
        {
            var session = new Session {StartTime = DateTime.Now, EndTime = DateTime.Now, Id = 42, SpeakerId = 1};
            var data = new CampData
                           {
                               Sessions = new List<Session> {session},
                               Speakers = new List<Speaker> {new Speaker {Id = 1}},
                           };
            DataClient.GetDataBody = () => Task.FromResult(data);
            var viewModel = new SessionsViewModel(Messenger, CodeCampService);

            Assert.True(viewModel.IsLoading);

            await viewModel.Init();

            Assert.AreEqual(1, viewModel.TimeSlots.Count);

            var slot = viewModel.TimeSlots.First();

            Assert.AreEqual(session.StartTime, slot.StartTime);
            Assert.AreEqual(session.EndTime, slot.EndTime);
            Assert.AreEqual(1, slot.Sessions.Count);
            Assert.AreEqual(session, slot.Sessions.First());
            Assert.False(viewModel.IsLoading);
        }
        public async Task<bool> RefreshData()
        {
            try
            {
                var data = await _client.GetData();

                foreach (var session in data.Sessions ?? new List<Session>())
                {
                    var speaker = data.Speakers.FirstOrDefault(s => s.Id == session.SpeakerId);

                    if (speaker == null)
                        continue;

                    session.SpeakerName = speaker.Name;
                }

                try
                {
                    _fileManager.WriteFile(DataFileName, _jsonConverter.SerializeObject(data));
                }
                catch (Exception)
                {
                }

                _campData = data;
                
                return true;
            }
            catch(Exception ex)
            {
                Console.WriteLine( ex);
                return false;
            }
        }
        public async void ViewWebsiteCommand_Executed_GoesToSponsorWebsite()
        {
            var sponsor = new Sponsor { Id = 42, Website = "http://codecampnyc.org" };
            var data = new CampData { Sponsors = new List<Sponsor> { sponsor } };
            DataClient.GetDataBody = () => Task.FromResult(data);
            var viewModel = new SponsorViewModel(Messenger, CodeCampService, WebBrowserTask);
            await viewModel.Init(new SponsorViewModel.NavigationParameters(sponsor.Id));

            viewModel.ViewWebsiteCommand.Execute(null);

            Assert.AreEqual(1, WebBrowserTask.UrlRequests.Count);
            Assert.AreEqual(sponsor.Website, WebBrowserTask.UrlRequests.First());
        }
        public async void Init_DataLoadsSuccessfully_LoadsSponsor()
        {
            var sponsor = new Sponsor { Id = 42 };
            var data = new CampData { Sponsors = new List<Sponsor> { sponsor } };
            DataClient.GetDataBody = () => Task.FromResult(data);
            var viewModel = new SponsorViewModel(Messenger, CodeCampService, WebBrowserTask);

            Assert.True(viewModel.IsLoading);

            await viewModel.Init(new SponsorViewModel.NavigationParameters(sponsor.Id));

            Assert.False(viewModel.IsLoading);
            Assert.AreEqual(sponsor, viewModel.Sponsor);
        }
        public async void Init_DataLoadsSuccessfully_LoadsSponsorList()
        {
            var sponsor = new Sponsor {Name = "Sponsor", Tier = "Gold"};
            var data = new CampData { Sponsors = new List<Sponsor> { sponsor } };
            DataClient.GetDataBody = () => Task.FromResult(data);
            var viewModel = new SponsorsViewModel(Messenger, CodeCampService);

            Assert.True(viewModel.IsLoading);

            await viewModel.Init();

            //Assert.AreEqual(data.Sponsors, viewModel.Sponsors);
            Assert.AreEqual(1, viewModel.SponsorTiers.Count);
            Assert.AreEqual(1, viewModel.SponsorTiers.First().Sponsors.Count);
            Assert.AreEqual(sponsor, viewModel.SponsorTiers.First().Sponsors.First());
            Assert.False(viewModel.IsLoading);
        }
        public async void Init_SomeSessionsHaveEnded_LoadsNextUnfinishedSlots()
        {
            var speaker = new Speaker {Id = 1};
            var pastSession = new Session { StartTime = DateTime.UtcNow.AddHours(-1), EndTime = DateTime.UtcNow.AddHours(-1), Id = 42, SpeakerId = speaker.Id};
            var inProgressSession = new Session { StartTime = DateTime.UtcNow.AddMinutes(-10), EndTime = DateTime.UtcNow.AddHours(1), Id = 24 };
            var data = new CampData
                           {
                               Sessions = new List<Session> {inProgressSession, pastSession},
                               Speakers = new List<Speaker> {speaker}
                           };
            DataClient.GetDataBody = () => Task.FromResult(data);
            var viewModel = new OverviewViewModel(Messenger, CodeCampService);

            await viewModel.Init();

            Assert.AreEqual(1, viewModel.TimeSlots.Count);
            Assert.AreEqual(inProgressSession, viewModel.TimeSlots.First().Sessions.Single());
        }
        public async void Init_DataLoadsSuccessfully_LoadsSession()
        {
            var session = new Session { Id = 42, SpeakerId = 1 };
            var data = new CampData
                           {
                               Sessions = new List<Session> {session},
                               Speakers = new List<Speaker> {new Speaker {Id = 1}},
                           };
            DataClient.GetDataBody = () => Task.FromResult(data);
            var viewModel = new SessionViewModel(Messenger, CodeCampService);

            Assert.True(viewModel.IsLoading);

            await viewModel.Init(new SessionViewModel.NavigationParameters(session.Id));

            Assert.False(viewModel.IsLoading);
            Assert.AreEqual(session, viewModel.Session);
        }
        public async void ListSessions_FetchesDataAndReturnsSessions()
        {
            var session = new Session
                              {
                                  Title = "Best Session Ever",
                                  Id = 42,
                                  StartTime = DateTime.UtcNow,
                                  EndTime = DateTime.UtcNow,
                                  SpeakerId = 1
                              };
            var campData = new CampData
            {
                Speakers = new List<Speaker> { new Speaker { Id = session.SpeakerId.Value } },
                Sessions = new List<Session> { session }
            };
            _mockDataClient.GetDataBody = () => Task.FromResult(campData);

            var service = new CodeCampService(_fileManager, _jsonConverter, _mockDataClient);

            var timeSlots = await service.ListSessions();

            Assert.AreEqual(1, timeSlots.Count);

            var slot = timeSlots.First();

            Assert.AreEqual(session.StartTime, slot.StartTime);
            Assert.AreEqual(session.EndTime, slot.EndTime);
            Assert.AreEqual(1, slot.Sessions.Count);
            Assert.AreEqual(session, slot.Sessions.First());
        }
        public async void GetSponsor_ValidSponsorId_ReturnsSponsor()
        {
            var awesomeSponsor = new Sponsor {Id = 42};
            var campData = new CampData
            {
                Sponsors = new List<Sponsor> { awesomeSponsor }
            };
            _mockDataClient.GetDataBody = () => Task.FromResult(campData);

            var service = new CodeCampService(_fileManager, _jsonConverter, _mockDataClient);

            var sponsor = await service.GetSponsor(awesomeSponsor.Id);

            Assert.AreEqual(awesomeSponsor, sponsor);
        }
        public async void ListSponsors_FetchesDataAndReturnsSponsors()
        {
            var sponsor = new Sponsor {Id = 42, Tier = "Gold" };
            var campData = new CampData
            {
                Sponsors = new List<Sponsor> { sponsor }
            };
            _mockDataClient.GetDataBody = () => Task.FromResult(campData);

            var service = new CodeCampService(_fileManager, _jsonConverter, _mockDataClient);
            var tiers = await service.ListSponsors();

            Assert.AreEqual(1, tiers.Count);
            Assert.AreEqual(1, tiers.First().Sponsors.Count);
            Assert.AreEqual(sponsor, tiers.First().Sponsors.First());
        }
        public async void ListSpeakers_FetchesDataAndReturnsSpeakers()
        {
            var campData = new CampData
            {
                Speakers = new List<Speaker> { new Speaker { Id = 42 } }
            };
            _mockDataClient.GetDataBody = () => Task.FromResult(campData);

            var service = new CodeCampService(_fileManager, _jsonConverter, _mockDataClient);
            var speakers = await service.ListSpeakers();

            Assert.AreEqual(campData.Speakers, speakers);
        }
        public async void GetSession_ValidSessionId_ReturnsSession()
        {
            var awesomeSession = new Session {Title = "Best Session Ever", Id = 42, SpeakerId = 1};
            var campData = new CampData
            {
                Sessions = new List<Session> { awesomeSession },
                Speakers = new List<Speaker> { new Speaker { Id = 1 } }
            };
            _mockDataClient.GetDataBody = () => Task.FromResult(campData);

            var service = new CodeCampService(_fileManager, _jsonConverter, _mockDataClient);

            var session = await service.GetSession(awesomeSession.Id);

            Assert.AreEqual(awesomeSession, session);
        }
        public async void ListSessionsBySpeaker_ValidSpeakerId_ReturnsSessionsForSpeaker()
        {
            int speakerId = 1;
            var correctSession = new Session {Id = 2, SpeakerId = speakerId};
            var wrongSession = new Session {Id = 3, SpeakerId = speakerId + 1};
            var campData = new CampData
                               {
                                   Sessions = new List<Session> {correctSession, wrongSession},
                                   Speakers = new List<Speaker> {new Speaker {Id = speakerId}}
                               };
            _mockDataClient.GetDataBody = () => Task.FromResult(campData);

            var service = new CodeCampService(_fileManager, _jsonConverter, _mockDataClient);

            var sessions = await service.ListSessionsBySpeaker(speakerId);

            Assert.AreEqual(1, sessions.Count);
            Assert.AreEqual(correctSession, sessions.First());
        }
        internal async Task<CampData> GetData()
        {
            // TODO: lock around the body of this method?
            _campData = _campData ?? LoadCachedCampData();

            if (_campData != null)
                return _campData;

            if (await RefreshData())
                return _campData;

            throw new Exception("There was a problem refreshing the data");
        }