public ContentDelivery(IContentfulOptions options) { if (_instance == null) { _instance = new ContentfulClient(new HttpClient(), options.GetOptionsObject()); } }
public async Task <ActionResult> Register() { HttpClient httpClient = new HttpClient(); var options = new ContentfulOptions { DeliveryApiKey = "4df4c5c7ed276605d36b9d880f1455aea05fe9b47e2da6acf518c0771d300625", PreviewApiKey = "3aaec008db04a17e144539715f539354ff73cf8d82c2548c3045bbcfc2ee32a2", SpaceId = "bda2gc49gm0w" }; var client = new ContentfulClient(httpClient, options); List <string> Cities = new List <string>(); var AllCategories = await client.GetContentType("users"); foreach (var fields in AllCategories.Fields) { if (fields.Id == "allCity") { Cities = ((Contentful.Core.Models.Management.InValuesValidator)fields.Items.Validations[0]).RequiredValues; } } HttpContext.Cache.Add("City", Cities, null, System.Web.Caching.Cache.NoAbsoluteExpiration, new TimeSpan(1, 0, 0), System.Web.Caching.CacheItemPriority.Normal, null); return(View()); }
public async Task SettingPreviewApiShouldUseCorrectApiKey() { //Arrange _handler = new FakeMessageHandler(); var httpClient = new HttpClient(_handler); _client = new ContentfulClient(httpClient, new ContentfulOptions() { DeliveryApiKey = "123", ManagementApiKey = "123", PreviewApiKey = "ABC-PREVIEW", SpaceId = "666", UsePreviewApi = true, MaxNumberOfRateLimitRetries = 3 }); var authHeader = ""; _handler.Response = GetResponseFromFile(@"SampleEntry.json"); _handler.VerifyRequest = (HttpRequestMessage request) => { authHeader = request.Headers.GetValues("Authorization").First(); }; //Act var res = await _client.GetEntry <Entry <TestEntryModel> >("12"); //Assert Assert.Equal("Bearer ABC-PREVIEW", authHeader); }
public async Task TestCanSearchAssetsAsync() { const string endpointUrl = "https://cdn.contentful.com/spaces/spaceId/assets/?skip=0&limit=10", assetId = "123456789"; const int skip = 0, limit = 10; var cancellationToken = new CancellationToken(); var mockHttpWrapper = new Mock <IHttpClientWrapper>(); mockHttpWrapper.Setup(m => m.GetAsync(endpointUrl, cancellationToken)) .ReturnsAsync(new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent("{ skip: 0, limit: 10, items: [ { sys: { \"id\": \"123456789\" } } ] }") }); var client = new ContentfulClient("spaceId", mockHttpWrapper.Object); var results = await client.SearchAsync <Asset>(cancellationToken, new ISearchFilter[] { new SkipSearchFilter(skip), new LimitSearchFilter(limit) }); Assert.IsNotNull(results); Assert.AreEqual(skip, results.Skip); Assert.AreEqual(limit, results.Limit); Assert.IsTrue(results.Items.Any()); var asset = results.Items.First(); Assert.AreEqual(assetId, asset.SystemProperties.Id); }
public ContentfulService(IHostingEnvironment hostingEnvironment, ICacheService cacheService, IOptions <ContentfulConfig> contentfulConfig, IBaseClient baseClient) { _hostingEnvironment = hostingEnvironment; _cacheService = cacheService; _contentfulConfig = contentfulConfig.Value; _imageDBPath = _hostingEnvironment.WebRootPath + "/data/header-images.json"; // Build Contentful client var options = new ContentfulOptions() { UsePreviewApi = false, DeliveryApiKey = _contentfulConfig.DeliveryApiKey, SpaceId = _contentfulConfig.SpaceId }; _client = new ContentfulClient(baseClient.GetHttpClient(), options); // Build Contentful preview client var previewOptions = new ContentfulOptions() { UsePreviewApi = true, PreviewApiKey = _contentfulConfig.PreviewApiKey, SpaceId = _contentfulConfig.SpaceId }; _previewClient = new ContentfulClient(baseClient.GetHttpClient(), previewOptions); }
public void GetRequestUrlReturnsIdOnly() { const string id = "12345"; var result = ContentfulClient.GetRequestUrl(RequestBaseUrl, id); Assert.AreEqual("http://test.com/12345", result); }
public void TestBuildsHttpClientWithAuthHeader() { const string accessToken = "accessToken1"; var result = ContentfulClient.BuildHttpClient(accessToken); Assert.IsNotNull(result); }
public async Task RateLimitWithRetryShouldCallSeveralTimes() { //Arrange _handler = new FakeMessageHandler(); var httpClient = new HttpClient(_handler); _client = new ContentfulClient(httpClient, new ContentfulOptions() { DeliveryApiKey = "123", ManagementApiKey = "123", SpaceId = "666", UsePreviewApi = false, MaxNumberOfRateLimitRetries = 3 }); var response = GetResponseFromFile(@"ErrorRateLimit.json"); response.StatusCode = (HttpStatusCode)429; response.Headers.Add("X-Contentful-RateLimit-Reset", "1"); _handler.Response = response; var numberOfTimesCalled = 0; _handler.VerificationBeforeSend = () => { numberOfTimesCalled++; }; _handler.VerifyRequest = (HttpRequestMessage msg) => { response.RequestMessage = msg; }; //Act var ex = await Assert.ThrowsAsync <ContentfulRateLimitException>(async() => await _client.GetEntryAsync <TestEntryModel>("12")); //Assert Assert.Equal(1, ex.SecondsUntilNextRequest); //1 request + 3 retries Assert.Equal(4, numberOfTimesCalled); }
public async Task <ActionResult> Index() { if (Session["username"] != null) { ViewBag.Session = Session["username"].ToString(); } else { ViewBag.Session = "Contentful"; } HttpClient httpClient = new HttpClient(); var options = new ContentfulOptions { DeliveryApiKey = "4df4c5c7ed276605d36b9d880f1455aea05fe9b47e2da6acf518c0771d300625", PreviewApiKey = "3aaec008db04a17e144539715f539354ff73cf8d82c2548c3045bbcfc2ee32a2", SpaceId = "bda2gc49gm0w" }; var client = new ContentfulClient(httpClient, options); var AllCategories = await client.GetEntries(QueryBuilder <Category> .New.ContentTypeIs("category")); var AllCategoryItems = await client.GetEntries(QueryBuilder <Product> .New.ContentTypeIs("categoryItems")); Homepage model = new Homepage(); model.Kategori = AllCategories.Items.ToList(); model.Urun = AllCategoryItems.Items.ToList(); return(View(model)); }
/// <summary> /// Validation logic for the options. /// </summary> /// <param name="validationContext">The validation context.</param> /// <returns>An IEnumerable of ValidationResult.</returns> public IEnumerable <ValidationResult> Validate(ValidationContext validationContext) { var localizer = validationContext.GetService(typeof(IViewLocalizer)) as IViewLocalizer; if (string.IsNullOrEmpty(SpaceId)) { yield return(new ValidationResult(localizer["fieldIsRequiredLabel"].Value, new[] { nameof(SpaceId) })); } if (string.IsNullOrEmpty(AccessToken)) { yield return(new ValidationResult(localizer["fieldIsRequiredLabel"].Value, new[] { nameof(AccessToken) })); } if (string.IsNullOrEmpty(PreviewToken)) { yield return(new ValidationResult(localizer["fieldIsRequiredLabel"].Value, new[] { nameof(PreviewToken) })); } if (!string.IsNullOrEmpty(SpaceId) && !string.IsNullOrEmpty(AccessToken) && !string.IsNullOrEmpty(PreviewToken)) { // We got all required fields. Make a test call to each API to verify. var httpClient = validationContext.GetService(typeof(HttpClient)) as HttpClient; var contentfulClient = new ContentfulClient(httpClient, AccessToken, PreviewToken, SpaceId); foreach (var validationResult in MakeTestCalls(httpClient, contentfulClient, localizer)) { yield return(validationResult); } } }
public void GetRequestUrlReturnsOrderBy() { const string property = "title"; const OrderByDirection direction = OrderByDirection.Descending; var result = ContentfulClient.GetRequestUrl(RequestBaseUrl, orderByProperty: property, orderByDirection: direction); Assert.AreEqual("http://test.com/?order=-title", result); }
public IContentfulClient GetClient(ContentfulConfig config) { bool.TryParse(_configuration["Contentful:UsePreviewAPI"], out var usePreviewApi); var client = new ContentfulClient(_httpClient, !usePreviewApi ? config.AccessKey : "", usePreviewApi ? config.AccessKey : "", config.SpaceKey, usePreviewApi) { ResolveEntriesSelectively = true }; return(client); }
/// <summary> /// Publishes the content items referenced by the project. /// </summary> /// <param name="slug">The slug identifying the project</param> /// <returns></returns> public async Task <List <string> > PublishProject(string slug) { _logger.LogTrace($"ContentfulContentRepository.PublishProject({slug})"); if (string.IsNullOrWhiteSpace(slug)) { throw new ArgumentException("Missing required parameter", nameof(slug)); } try { var cful = new ContentfulClient(_httpClient, _options); var managementClient = new ContentfulManagementClient(_httpClient, _options); var facetQuery = new QueryBuilder <Project>() .ContentTypeIs("project") .FieldEquals("fields.slug", slug) .Include(8); _logger.LogInformation($"executing CMS call with query: {facetQuery.Build()}"); // Retrieve the entire content tree by starting at the project and pulling includes // an arbitrary depth of 8 var entrySet = await cful.GetEntries(facetQuery); // todo: determine if our process will already have the actual project published or not. // var projectId = entrySet.Items.FirstOrDefault().Sys.Id; var includedEntryIds = entrySet.IncludedEntries.Select(x => x.SystemProperties.Id); // todo: publish assets, too. // var includedAssetIds = entrySet.IncludedAssets.Select(x => x.SystemProperties.Id); foreach (var entry in entrySet.IncludedEntries) { var id = entry.SystemProperties.Id; // Retrieve the item from mgmt API. Version is not included from delivery API so we get it again. var mgmtEntry = await managementClient.GetEntry(id); var latestVersion = mgmtEntry.SystemProperties.Version.GetValueOrDefault(); var result = await managementClient.PublishEntry(id, latestVersion); } return(null); } catch (Contentful.Core.Errors.ContentfulException ex) { var msg = "Error retrieving content: " + ex; _logger.LogError(msg); throw new ContentException(msg, ex); } catch (Exception ex) { var msg = "Unable to retrieve content: " + ex; _logger.LogError(msg); throw new ProcessException(msg, ex); } }
public void GetRequestUrlReturnsFiltersOnly() { var filters = new ISearchFilter[] { new EqualitySearchFilter("title", "hello"), new EqualitySearchFilter("name", "test") }; var result = ContentfulClient.GetRequestUrl(RequestBaseUrl, filters: filters); Assert.AreEqual("http://test.com/?title=hello&name=test", result); }
// When you go to /Lessons, return a list of all lessons public async Task <ActionResult> Index() { var httpClient = new System.Net.Http.HttpClient(); var client = new ContentfulClient(httpClient, "TJUTn86tuAZZ0L4Aw1LmA2HUBWNoU2TBHeCghBWJTac", "XsWxHVfA6Mu5yO2rlMf_IlrmIxfy5nAnFPraPg5LGc0", "dgv1c069l5im"); var entries = await client.GetEntriesByType <Lesson>("lesson"); // foreach (var row in entries) Console.WriteLine(row.Slug); return(View(entries)); }
/// <summary> /// Invokes the view component and returns the result. /// </summary> /// <param name="sys">They system properties of the entry to display status for.</param> /// <returns>The view.</returns> public async Task <IViewComponentResult> InvokeAsync(IEnumerable <SystemProperties> sys) { // Create a new client with preview set to false to always get the entry from the delivery API. var client = new ContentfulClient(_httpClient, _options.DeliveryApiKey, _options.PreviewApiKey, _options.SpaceId, false); IEnumerable <EntryStateModel> entries = null; var model = new EntryStateModel(); try { // Try getting the entry by the specified Id. If it throws or returns null the entry is not published. entries = await client.GetEntries <EntryStateModel>($"?sys.id[in]={string.Join(",", sys.Select(c => c.Id))}"); } catch { } if (entries == null || (entries.Any() == false || sys.Select(c => c.Id).Except(entries.Select(e => e.Sys.Id)).Any())) { // One of the entries are not published, thus it is in draft mode. model.Draft = true; } if (entries != null && AnySystemPropertiesNotMatching(entries.Select(c => c.Sys), sys)) { // The entry is published but the UpdatedAt dates do not match, thus it must have pending changes. model.PendingChanges = true; } return(View(model)); bool AnySystemPropertiesNotMatching(IEnumerable <SystemProperties> published, IEnumerable <SystemProperties> preview) { foreach (var publishedEntry in published) { var previewEntry = preview.FirstOrDefault(c => c.Id == publishedEntry.Id); if (TrimMilliseconds(publishedEntry.UpdatedAt) != TrimMilliseconds(previewEntry?.UpdatedAt)) { // At least one of the entries have UpdatedAt that does not match, thus it has pending changes. return(true); } } return(false); } DateTime?TrimMilliseconds(DateTime?dateTime) { if (!dateTime.HasValue) { return(dateTime); } return(new DateTime(dateTime.Value.Year, dateTime.Value.Month, dateTime.Value.Day, dateTime.Value.Hour, dateTime.Value.Minute, dateTime.Value.Second, 0)); } }
public async Task TestCanDeserializeFromHttpResponseMessage() { var message = new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent("{ StringValue: \"value\", BoolValue: true }") }; var result = await ContentfulClient.GetItemAsync <MockJsonModel>(message); Assert.IsNotNull(result); Assert.AreEqual("value", result.StringValue); Assert.IsTrue(result.BoolValue); }
public void TestQueryStringReturnsForValidFilters() { var filters = new ISearchFilter[] { new SkipSearchFilter(0), new LimitSearchFilter(15), new EqualitySearchFilter("test", "true"), }; var result = ContentfulClient.GetQueryStringFromSearchFilters(filters); const string expectedQueryString = "skip=0&limit=15&test=true"; Assert.AreEqual(expectedQueryString, result); }
public ContentfulClientTests() { _handler = new FakeMessageHandler(); var httpClient = new HttpClient(_handler); _client = new ContentfulClient(httpClient, new ContentfulOptions() { DeliveryApiKey = "123", ManagementApiKey = "123", SpaceId = "666", UsePreviewApi = false }); }
// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.TryAddSingleton <IHttpContextAccessor, HttpContextAccessor>(); services.AddContentful(Configuration); if (CurrentEnvironment.IsStaging()) { var host = Environment.GetEnvironmentVariable("StagingHost"); if (!string.IsNullOrEmpty(host)) { services.AddSingleton((ip) => { var stagingHandler = new StagingMessageHandler { StagingHost = host }; return(new HttpClient(stagingHandler)); }); } } // This would normally not be needed, but since we want to load our ContentfulOptions from memory if they're changed within the application // we provide our own implementation logic for the IContentfulClient services.AddSingleton <IContentfulOptionsManager, ContentfulOptionsManager>(); services.AddTransient <IContentfulClient, ContentfulClient>((ip) => { var client = ip.GetService <HttpClient>(); var options = ip.GetService <IContentfulOptionsManager>().Options; var contentfulClient = new ContentfulClient(client, options); var version = typeof(Startup).GetTypeInfo().Assembly.GetCustomAttribute <AssemblyInformationalVersionAttribute>() .InformationalVersion; contentfulClient.Application = $"app the-example-app.csharp/{version}; {contentfulClient.Application}"; return(contentfulClient); }); services.AddSingleton <IViewLocalizer, JsonViewLocalizer>(); services.AddTransient <IVisitedLessonsManager, VisitedLessonsManager>(); services.AddMvc().AddRazorPagesOptions( options => { options.Conventions.AddPageRoute("/Courses", "Courses/Categories/{category?}"); options.Conventions.AddPageRoute("/Courses/Index", "Courses/{slug}/lessons"); options.Conventions.AddPageRoute("/Courses/Lessons", "Courses/{slug}/lessons/{lessonSlug}"); }); services.AddSession(options => { // IdleTimeout is set to a high value to confirm to requirements for this particular application. // In your application you should use an IdleTimeout that suits your application needs or stick to the default of 20 minutes. options.IdleTimeout = TimeSpan.FromDays(2); }); services.AddTransient <IBreadcrumbsManager, BreadcrumbsManager>(); var embeddedProvider = new EmbeddedFileProvider(GetType().GetTypeInfo().Assembly); services.AddSingleton <IFileProvider>(embeddedProvider); }
private ContentfulClient GetClientWithEnvironment(string env = "special") { var httpClient = new HttpClient(_handler); var options = new ContentfulOptions { DeliveryApiKey = "123", PreviewApiKey = "3123", Environment = env, SpaceId = "564" }; var client = new ContentfulClient(httpClient, options); return(client); }
public CtfDeliveryService(IConfiguration configuration, CacheService cacheService) { _cacheService = cacheService; CtfClient = new ContentfulClient(new HttpClient(), new ContentfulOptions { DeliveryApiKey = configuration["DeliveryApiKey"], SpaceId = configuration["DeliverySpaceId"] }) { ResolveEntriesSelectively = true }; _htmlRenderer = new HtmlRenderer(); _htmlRenderer.AddRenderer(new LinkContentRenderer { Order = 10 }); }
public override Task InitializeStore() { if (this.client == null) { var httpClient = new HttpClient(new MessageHandler()); this.client = new ContentfulClient(httpClient, new Contentful.Core.Configuration.ContentfulOptions { DeliveryApiKey = ContentfulDeliveryApiKey.Trim(), SpaceId = ContentfulSpaceKey.Trim() }); } return(Task.CompletedTask); }
public async Task <ActionResult> ProductDetails(string productID) { HttpClient httpClient = new HttpClient(); var options = new ContentfulOptions { DeliveryApiKey = "4df4c5c7ed276605d36b9d880f1455aea05fe9b47e2da6acf518c0771d300625", PreviewApiKey = "3aaec008db04a17e144539715f539354ff73cf8d82c2548c3045bbcfc2ee32a2", SpaceId = "bda2gc49gm0w" }; var client = new ContentfulClient(httpClient, options); var ProductDetail = await client.GetEntries(QueryBuilder <Product> .New.ContentTypeIs("categoryItems").FieldEquals(f => f.Sys.Id, productID)); return(View(ProductDetail.ToList())); }
public async Task TestMakeGetRequestThrowsContentfulExceptionOnErrorCode() { const string requestUri = "http://test.com"; var cancellationToken = new CancellationToken(); var mockHttpClient = new Mock<IHttpClientWrapper>(); mockHttpClient.Setup(h => h.GetAsync(requestUri, cancellationToken)) .ReturnsAsync(new HttpResponseMessage(HttpStatusCode.BadRequest) { Content = new StringContent("") }); var client = new ContentfulClient("spaceId", mockHttpClient.Object); await client.MakeGetRequestAsync(requestUri, cancellationToken); }
public async Task Contentful() { var httpClient = new HttpClient(); var options = new ContentfulOptions() { DeliveryApiKey = "c66a798c5adb7e11727de7831e48f2cf5039b2c2f2595be6f83b67c03fac3e4a", PreviewApiKey = "ae5d997b2a95d49e250939bc350397778bb17ebe56560e8e2442b320668b2550", SpaceId = "fgj5iptu3uwg" }; var client = new ContentfulClient(httpClient, options); var entry = await client.GetEntry <Product>("3r6V9g1XzGaKAY4syUuyIg"); Assert.That(entry.Sys.Id, Is.Not.Null); }
public async Task TestMakeGetRequestThrowsContentfulExceptionOnErrorCode() { const string requestUri = "http://test.com"; var cancellationToken = new CancellationToken(); var mockHttpClient = new Mock <IHttpClientWrapper>(); mockHttpClient.Setup(h => h.GetAsync(requestUri, cancellationToken)) .ReturnsAsync(new HttpResponseMessage(HttpStatusCode.BadRequest) { Content = new StringContent("") }); var client = new ContentfulClient("spaceId", mockHttpClient.Object); await client.MakeGetRequestAsync(requestUri, cancellationToken); }
public async Task <ActionResult> Lesson(string slug) { // slug is being passed in by the actionLink in /Lessons ViewData["slug"] = slug; var httpClient = new System.Net.Http.HttpClient(); var client = new ContentfulClient(httpClient, "TJUTn86tuAZZ0L4Aw1LmA2HUBWNoU2TBHeCghBWJTac", "XsWxHVfA6Mu5yO2rlMf_IlrmIxfy5nAnFPraPg5LGc0", "dgv1c069l5im"); // if you had the entry id you could just return the single entry without having to do a forEach in the view var entry = await client.GetEntries <Lesson>($"?content_type=lesson&fields.slug={slug}"); // logs the total number of entries returned // Console.WriteLine(entries.Total.ToString()); return(View(entry)); }
public async Task TestCanGetEntryAsync() { const string endpointUrl = "https://cdn.contentful.com/spaces/spaceId/entries/123456"; var cancellationToken = new CancellationToken(); var mockHttpWrapper = new Mock <IHttpClientWrapper>(); mockHttpWrapper.Setup(m => m.GetAsync(endpointUrl, cancellationToken)) .ReturnsAsync(new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent("{ sys: { \"id\": \"123456\" } }") }); var client = new ContentfulClient("spaceId", mockHttpWrapper.Object); var entry = await client.GetAsync <Entry>(cancellationToken, "123456"); Assert.IsNotNull(entry); Assert.AreEqual("123456", entry.SystemProperties.Id); }
public async Task CreatingAContentfulClientAndMakingCallShouldAddUserAgentHeader() { //Arrange var httpClient = new HttpClient(_handler); var client = new ContentfulClient(httpClient, "123", "435"); _handler.Response = GetResponseFromFile(@"SampleAsset.json"); var userAgent = ""; _handler.VerifyRequest = (HttpRequestMessage request) => { userAgent = request.Headers.UserAgent.First().Product.Name; }; //Act await client.GetAssetAsync("123"); //Assert Assert.Equal("Contentful-.NET-SDK", userAgent); }
public async Task CreatingAContentfulClientAndMakingCallShouldAddAuthHeader() { //Arrange var httpClient = new HttpClient(_handler); var client = new ContentfulClient(httpClient, "444", "435"); _handler.Response = GetResponseFromFile(@"SampleAsset.json"); var authHeader = ""; _handler.VerifyRequest = (HttpRequestMessage request) => { authHeader = request.Headers.GetValues("Authorization").First(); }; //Act await client.GetAssetAsync("564"); //Assert Assert.Equal("Bearer 444", authHeader); }
public void TestPublicConstructorAcceptsOptionalPreviewParameter() { var client = new ContentfulClient("accessToken", "space", true); Assert.IsNotNull(client.HttpClient); }
public async Task TestCanSearchAssetsAsync() { const string endpointUrl = "https://cdn.contentful.com/spaces/spaceId/assets/?skip=0&limit=10", assetId = "123456789"; const int skip = 0, limit = 10; var cancellationToken = new CancellationToken(); var mockHttpWrapper = new Mock<IHttpClientWrapper>(); mockHttpWrapper.Setup(m => m.GetAsync(endpointUrl, cancellationToken)) .ReturnsAsync(new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent("{ skip: 0, limit: 10, items: [ { sys: { \"id\": \"123456789\" } } ] }") }); var client = new ContentfulClient("spaceId", mockHttpWrapper.Object); var results = await client.SearchAsync<Asset>(cancellationToken, new ISearchFilter[] { new SkipSearchFilter(skip), new LimitSearchFilter(limit) }); Assert.IsNotNull(results); Assert.AreEqual(skip, results.Skip); Assert.AreEqual(limit, results.Limit); Assert.IsTrue(results.Items.Any()); var asset = results.Items.First(); Assert.AreEqual(assetId, asset.SystemProperties.Id); }
public void TestPublicConstructorCreatesHttpClient() { var client = new ContentfulClient("accessToken", "space"); Assert.IsNotNull(client.HttpClient); }
public async Task TestCanGetEntryAsync() { const string endpointUrl = "https://cdn.contentful.com/spaces/spaceId/entries/123456"; var cancellationToken = new CancellationToken(); var mockHttpWrapper = new Mock<IHttpClientWrapper>(); mockHttpWrapper.Setup(m => m.GetAsync(endpointUrl, cancellationToken)) .ReturnsAsync(new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent("{ sys: { \"id\": \"123456\" } }") }); var client = new ContentfulClient("spaceId", mockHttpWrapper.Object); var entry = await client.GetAsync<Entry>(cancellationToken, "123456"); Assert.IsNotNull(entry); Assert.AreEqual("123456", entry.SystemProperties.Id); }