Skip to content

omefire/Telnyx

Repository files navigation

Telnyx

Blog App

What the final app looks like

Blog Feed

Blog Detail

Add Comment

Reply To Comment

Getting started

Requirements

What's included

This starter kit provides the basics needed to quickly bootstrap your web application in the framework of your choice. We provide the following, managed through npm packages:

As long as requirements for the challenge are met, feel free to add additional npm packages and modify files in the starter kit as you see fit.

A barebones web application with routing, seed data, and stubbed out REST API is also included to get you started. See Using the REST API once you're up and running for more information.

Quick start

1. Run npm install

This will install all dependencies (listed in package.json) necessary to get you up and running. Feel free to add additional npm packages as you progress.

2. Run npm start

This will run two scripts concurrently:

  1. npm run api will start json-server to provide a stubbed out REST API through localhost:9001.
  2. npm run serve will start webpack-dev-server to serve up your application. You should see your default browser open up a window pointing to localhost:9000.

3. Navigate to http://localhost:9000/

You should see "Welcome!", and a barebones web application with navigational links to "Home" and "About".

Testing

To run tests:

$ npm test

Karma will look for all files matching a *.spec.(js|jsx|ts) glob in /src. You may add new tests by creating files under /src that follow the *.spec.* pattern. If you prefer to change the spec file pattern, or use another testing framework than Jasmine, you may modify configuration options in karma.config.js.

Using the REST API

Note: Ensure that you've started the API server with npm start or npm run api.

A REST API is provided with seed data for blog posts and comments. The REST API returns and accepts JSON. Changes made to the "database" will persist as long as the API is running on localhost:9001.

Base path: http://localhost:9001

GET /posts List all blog posts
GET /posts/{id} View single blog post
GET /posts/{id}/comments List all comments for single blog post
POST /posts/{id}/comments Add comment to single blog post
PUT /comments/{id} Update single comment

interface Post {
  "id": Number;
  "title": String;
  "author": String;
  "publish_date": String; // Date that post was published in YYYY-MM-DD format
  "slug": String;         // Readable URL to use for individual posts
  "description": String;  // Short description for blog post listing
  "content": String;      // Full blog post content -- may contain markup
}
interface Comment {
  "id": Number;
  "postId": Number;
  "parent_id": Number|null; // Parent comment for replies, is `null` if top-level comment
  "user": String;           // Name of commenter
  "date": String;           // Date of comment in YYYY-MM-DD format
  "content": String;        // Comment content
}
A unit test:

  it('getBlogPostAndComments should fail if either blog posts or comments fail', () => {
    const http = null;
    const blogService = new BlogService(http);
    const spy = spyOn(blogService, 'getBlogPost').and.throwError('Error while getting blog post');
    const spy2 = spyOn(blogService, 'getComments').and.returnValues([]);
    component.getBlogPostAndComments();
    expect(component.isInErrorState).toBeTruthy();
    expect(component.errorMessage).toBe('Error while getting blog post');
    expect(blogService.getBlogPost).toHaveBeenCalled();
    expect(blogService.getComments).toHaveBeenCalled();
  });