gothinkster/realworld

๐Ÿ—„๐Ÿ”ง Haskell / Yesod

tzemanovic opened this issue ยท 5 comments

Current Status

Codebase in progress: https://github.com/tzemanovic/haskell-yesod-realworld-example-app

Todo:

  • ๐Ÿ Fork the starter repo & post the link in this issue
  • ๐ŸŽจ Create logo for repo & update issue status (@EricSimons)
  • ๐Ÿ”จ Implement all of Conduit's functionality per the spec & API
  • ๐Ÿ‘€ Move repo to main org & Peer review final codebase by admins/community (RFC)
  • ๐ŸŽ‰ Tag v1 release and officially list it on the README!

Hi, I've got this implementation ready. Please, let me know what to do for the next step.

@tzemanovic this looks amazing! ๐Ÿ™Œ a few suggestions:

  1. Could you summarize "How it works" in the README itself (its okay if not the whole blog post, at least some key information)?
  2. Could you run Postman API tests against your stack to ensure they work, and maybe even add to Travis YML file?

Great work!!!

Hi Anish, thank you!

  1. I've had a link to a blog post with overview of the project, but it wasn't very visible, so I've updated it.
  2. Thanks for fixing the tests in #255, I've ran them and all are passing except for the timestamp tests such as:

tests['Article\\'s \"createdAt\" property is an ISO 8601 timestamp'] = new Date(article.createdAt).toISOString() === article.createdAt;",

SQLite seems to be using 3 more decimals for microseconds, which get lost in the new Date(t).toISOString() conversion, but this is a valid ISO 8601 date.

With the updates from #255 and #260, this is passing the postman tests now:

Conduit

โ Auth
โ†ณ Register
  POST https://localhost:3443/api/users [200 OK, 733B, 79ms]
  โœ“  Response contains "user" property
  โœ“  User has "email" property
  โœ“  User has "username" property
  โœ“  User has "bio" property
  โœ“  User has "image" property
  โœ“  User has "token" property

โ†ณ Login
  POST https://localhost:3443/api/users/login [200 OK, 733B, 33ms]
  โœ“  Response contains "user" property
  โœ“  User has "email" property
  โœ“  User has "username" property
  โœ“  User has "bio" property
  โœ“  User has "image" property
  โœ“  User has "token" property

โ†ณ Login and Remember Token
  POST https://localhost:3443/api/users/login [200 OK, 733B, 31ms]
  โœ“  Response contains "user" property
  โœ“  User has "email" property
  โœ“  User has "username" property
  โœ“  User has "bio" property
  โœ“  User has "image" property
  โœ“  User has "token" property
  โœ“  Global variable "token" has been set

โ†ณ Current User
  GET https://localhost:3443/api/user [200 OK, 733B, 4ms]
  โœ“  Response contains "user" property
  โœ“  User has "email" property
  โœ“  User has "username" property
  โœ“  User has "bio" property
  โœ“  User has "image" property
  โœ“  User has "token" property

โ†ณ Update User
  PUT https://localhost:3443/api/user [200 OK, 732B, 6ms]
  โœ“  Response contains "user" property
  โœ“  User has "email" property
  โœ“  User has "username" property
  โœ“  User has "bio" property
  โœ“  User has "image" property
  โœ“  User has "token" property

โ Articles
โ†ณ All Articles
  GET https://localhost:3443/api/articles [200 OK, 436B, 4ms]
  โœ“  Response code is 200 OK
  โœ“  Response contains "articles" property
  โœ“  Response contains "articlesCount" property
  โœ“  articlesCount is an integer
  โœ“  articlesCount is 0 when feed is empty

โ†ณ Articles by Author
  GET https://localhost:3443/api/articles?author=johnjacob [200 OK, 436B, 4ms]
  โœ“  Response code is 200 OK
  โœ“  Response contains "articles" property
  โœ“  Response contains "articlesCount" property
  โœ“  articlesCount is an integer
  โœ“  articlesCount is 0 when feed is empty

โ†ณ Articles Favorited by Username
  GET https://localhost:3443/api/articles?favorited=jane [200 OK, 436B, 3ms]
  โœ“  Response code is 200 OK
  โœ“  Response contains "articles" property
  โœ“  Response contains "articlesCount" property
  โœ“  articlesCount is an integer
  โœ“  articlesCount is 0 when feed is empty

โ†ณ Articles by Tag
  GET https://localhost:3443/api/articles?tag=dragons [200 OK, 436B, 3ms]
  โœ“  Response code is 200 OK
  โœ“  Response contains "articles" property
  โœ“  Response contains "articlesCount" property
  โœ“  articlesCount is an integer
  โœ“  articlesCount is 0 when feed is empty

โ Articles, Favorite, Comments
โ†ณ Create Article
  POST https://localhost:3443/api/articles [200 OK, 834B, 11ms]
  โœ“  Response contains "article" property
  โœ“  Article has "title" property
  โœ“  Article has "slug" property
  โœ“  Article has "body" property
  โœ“  Article has "createdAt" property
  โœ“  Article's "createdAt" property is an ISO 8601 timestamp
  โœ“  Article has "updatedAt" property
  โœ“  Article's "updatedAt" property is an ISO 8601 timestamp
  โœ“  Article has "description" property
  โœ“  Article has "tagList" property
  โœ“  Article's "tagList" property is an Array
  โœ“  Article has "author" property
  โœ“  Article has "favorited" property
  โœ“  Article has "favoritesCount" property
  โœ“  favoritesCount is an integer

โ†ณ Feed
  GET https://localhost:3443/api/articles/feed [200 OK, 436B, 3ms]
  โœ“  Response code is 200 OK
  โœ“  Response contains "articles" property
  โœ“  Response contains "articlesCount" property
  โœ“  articlesCount is an integer
  โœ“  articlesCount is 0 when feed is empty

โ†ณ All Articles
  GET https://localhost:3443/api/articles [200 OK, 855B, 3ms]
  โœ“  Response code is 200 OK
  โœ“  Response contains "articles" property
  โœ“  Response contains "articlesCount" property
  โœ“  articlesCount is an integer
  โœ“  Article has "title" property
  โœ“  Article has "slug" property
  โœ“  Article has "body" property
  โœ“  Article has "createdAt" property
  โœ“  Article's "createdAt" property is an ISO 8601 timestamp
  โœ“  Article has "updatedAt" property
  โœ“  Article's "updatedAt" property is an ISO 8601 timestamp
  โœ“  Article has "description" property
  โœ“  Article has "tagList" property
  โœ“  Article's "tagList" property is an Array
  โœ“  Article has "author" property
  โœ“  Article has "favorited" property
  โœ“  Article has "favoritesCount" property
  โœ“  favoritesCount is an integer

โ†ณ All Articles with auth
  GET https://localhost:3443/api/articles [200 OK, 855B, 3ms]
  โœ“  Response code is 200 OK
  โœ“  Response contains "articles" property
  โœ“  Response contains "articlesCount" property
  โœ“  articlesCount is an integer
  โœ“  Article has "title" property
  โœ“  Article has "slug" property
  โœ“  Article has "body" property
  โœ“  Article has "createdAt" property
  โœ“  Article's "createdAt" property is an ISO 8601 timestamp
  โœ“  Article has "updatedAt" property
  โœ“  Article's "updatedAt" property is an ISO 8601 timestamp
  โœ“  Article has "description" property
  โœ“  Article has "tagList" property
  โœ“  Article's "tagList" property is an Array
  โœ“  Article has "author" property
  โœ“  Article has "favorited" property
  โœ“  Article has "favoritesCount" property
  โœ“  favoritesCount is an integer

โ†ณ Articles by Author
  GET https://localhost:3443/api/articles?author=tzemanovic [200 OK, 855B, 5ms]
  โœ“  Response code is 200 OK
  โœ“  Response contains "articles" property
  โœ“  Response contains "articlesCount" property
  โœ“  articlesCount is an integer
  โœ“  Article has "title" property
  โœ“  Article has "slug" property
  โœ“  Article has "body" property
  โœ“  Article has "createdAt" property
  โœ“  Article's "createdAt" property is an ISO 8601 timestamp
  โœ“  Article has "updatedAt" property
  โœ“  Article's "updatedAt" property is an ISO 8601 timestamp
  โœ“  Article has "description" property
  โœ“  Article has "tagList" property
  โœ“  Article's "tagList" property is an Array
  โœ“  Article has "author" property
  โœ“  Article has "favorited" property
  โœ“  Article has "favoritesCount" property
  โœ“  favoritesCount is an integer

โ†ณ Articles by Author with auth
  GET https://localhost:3443/api/articles?author=tzemanovic [200 OK, 855B, 3ms]
  โœ“  Response code is 200 OK
  โœ“  Response contains "articles" property
  โœ“  Response contains "articlesCount" property
  โœ“  articlesCount is an integer
  โœ“  Article has "title" property
  โœ“  Article has "slug" property
  โœ“  Article has "body" property
  โœ“  Article has "createdAt" property
  โœ“  Article's "createdAt" property is an ISO 8601 timestamp
  โœ“  Article has "updatedAt" property
  โœ“  Article's "updatedAt" property is an ISO 8601 timestamp
  โœ“  Article has "description" property
  โœ“  Article has "tagList" property
  โœ“  Article's "tagList" property is an Array
  โœ“  Article has "author" property
  โœ“  Article has "favorited" property
  โœ“  Article has "favoritesCount" property
  โœ“  favoritesCount is an integer

โ†ณ Articles Favorited by Username
  GET https://localhost:3443/api/articles?favorited=jane [200 OK, 436B, 2ms]
  โœ“  Response code is 200 OK
  โœ“  Response contains "articles" property
  โœ“  Response contains "articlesCount" property
  โœ“  articlesCount is an integer
  โœ“  articlesCount is 0 when feed is empty

โ†ณ Articles Favorited by Username with auth
  GET https://localhost:3443/api/articles?favorited=jane [200 OK, 436B, 3ms]
  โœ“  Response code is 200 OK
  โœ“  Response contains "articles" property
  โœ“  Response contains "articlesCount" property
  โœ“  articlesCount is an integer
  โœ“  articlesCount is 0 when feed is empty

โ†ณ Single Article by slug
  GET https://localhost:3443/api/articles/how-to-train-your-dragon-toll6b [200 OK, 834B, 3ms]
  โœ“  Response contains "article" property
  โœ“  Article has "title" property
  โœ“  Article has "slug" property
  โœ“  Article has "body" property
  โœ“  Article has "createdAt" property
  โœ“  Article's "createdAt" property is an ISO 8601 timestamp
  โœ“  Article has "updatedAt" property
  โœ“  Article's "updatedAt" property is an ISO 8601 timestamp
  โœ“  Article has "description" property
  โœ“  Article has "tagList" property
  โœ“  Article's "tagList" property is an Array
  โœ“  Article has "author" property
  โœ“  Article has "favorited" property
  โœ“  Article has "favoritesCount" property
  โœ“  favoritesCount is an integer

โ†ณ Articles by Tag
  GET https://localhost:3443/api/articles?tag=dragons [200 OK, 855B, 4ms]
  โœ“  Response code is 200 OK
  โœ“  Response contains "articles" property
  โœ“  Response contains "articlesCount" property
  โœ“  articlesCount is an integer
  โœ“  Article has "title" property
  โœ“  Article has "slug" property
  โœ“  Article has "body" property
  โœ“  Article has "createdAt" property
  โœ“  Article's "createdAt" property is an ISO 8601 timestamp
  โœ“  Article has "updatedAt" property
  โœ“  Article's "updatedAt" property is an ISO 8601 timestamp
  โœ“  Article has "description" property
  โœ“  Article has "tagList" property
  โœ“  Article's "tagList" property is an Array
  โœ“  Article has "author" property
  โœ“  Article has "favorited" property
  โœ“  Article has "favoritesCount" property
  โœ“  favoritesCount is an integer

โ†ณ Update Article
  PUT https://localhost:3443/api/articles/how-to-train-your-dragon-toll6b [200 OK, 833B, 4ms]
  โœ“  Response contains "article" property
  โœ“  Article has "title" property
  โœ“  Article has "slug" property
  โœ“  Article has "body" property
  โœ“  Article has "createdAt" property
  โœ“  Article's "createdAt" property is an ISO 8601 timestamp
  โœ“  Article has "updatedAt" property
  โœ“  Article's "updatedAt" property is an ISO 8601 timestamp
  โœ“  Article has "description" property
  โœ“  Article has "tagList" property
  โœ“  Article's "tagList" property is an Array
  โœ“  Article has "author" property
  โœ“  Article has "favorited" property
  โœ“  Article has "favoritesCount" property
  โœ“  favoritesCount is an integer

โ†ณ Favorite Article
  POST https://localhost:3443/api/articles/how-to-train-your-dragon-toll6b/favorite [200 OK, 832B, 4ms]
  โœ“  Response contains "article" property
  โœ“  Article has "title" property
  โœ“  Article has "slug" property
  โœ“  Article has "body" property
  โœ“  Article has "createdAt" property
  โœ“  Article's "createdAt" property is an ISO 8601 timestamp
  โœ“  Article has "updatedAt" property
  โœ“  Article's "updatedAt" property is an ISO 8601 timestamp
  โœ“  Article has "description" property
  โœ“  Article has "tagList" property
  โœ“  Article's "tagList" property is an Array
  โœ“  Article has "author" property
  โœ“  Article has "favorited" property
  โœ“  Article's 'favorited' property is true
  โœ“  Article has "favoritesCount" property
  โœ“  favoritesCount is an integer
  โœ“  Article's 'favoritesCount' property is greater than 0

โ†ณ Unfavorite Article
  DELETE https://localhost:3443/api/articles/how-to-train-your-dragon-toll6b/favorite [200 OK, 833B, 3ms]
  โœ“  Response contains "article" property
  โœ“  Article has "title" property
  โœ“  Article has "slug" property
  โœ“  Article has "body" property
  โœ“  Article has "createdAt" property
  โœ“  Article's "createdAt" property is an ISO 8601 timestamp
  โœ“  Article has "updatedAt" property
  โœ“  Article's "updatedAt" property is an ISO 8601 timestamp
  โœ“  Article has "description" property
  โœ“  Article has "tagList" property
  โœ“  Article's "tagList" property is an Array
  โœ“  Article has "author" property
  โœ“  Article has "favorited" property
  โœ“  Article has "favoritesCount" property
  โœ“  favoritesCount is an integer
  โœ“  Article's "favorited" property is true

โ†ณ Create Comment for Article
  POST https://localhost:3443/api/articles/how-to-train-your-dragon-toll6b/comments [200 OK, 665B, 4ms]
  โœ“  Response contains "comment" property
  โœ“  Comment has "id" property
  โœ“  Comment has "body" property
  โœ“  Comment has "createdAt" property
  โœ“  "createdAt" property is an ISO 8601 timestamp
  โœ“  Comment has "updatedAt" property
  โœ“  "updatedAt" property is an ISO 8601 timestamp
  โœ“  Comment has "author" property

โ†ณ All Comments for Article
  GET https://localhost:3443/api/articles/how-to-train-your-dragon-toll6b/comments [200 OK, 668B, 2ms]
  โœ“  Response code is 200 OK
  โœ“  Response contains "comments" property
  โœ“  Comment has "id" property
  โœ“  Comment has "body" property
  โœ“  Comment has "createdAt" property
  โœ“  "createdAt" property is an ISO 8601 timestamp
  โœ“  Comment has "updatedAt" property
  โœ“  "updatedAt" property is an ISO 8601 timestamp
  โœ“  Comment has "author" property

โ†ณ Delete Comment for Article
  DELETE https://localhost:3443/api/articles/how-to-train-your-dragon-toll6b/comments/1 [200 OK, 407B, 2ms]

โ†ณ Delete Article
  DELETE https://localhost:3443/api/articles/how-to-train-your-dragon-toll6b [200 OK, 407B, 3ms]

โ Profiles
โ†ณ Register Celeb
  POST https://localhost:3443/api/users [200 OK, 745B, 31ms]
  โœ“  Response contains "user" property
  โœ“  User has "email" property
  โœ“  User has "username" property
  โœ“  User has "bio" property
  โœ“  User has "image" property
  โœ“  User has "token" property

โ†ณ Profile
  GET https://localhost:3443/api/profiles/celeb_tzemanovic [200 OK, 541B, 3ms]
  โœ“  Response code is 200 OK
  โœ“  Response contains "profile" property
  โœ“  Profile has "username" property
  โœ“  Profile has "bio" property
  โœ“  Profile has "image" property
  โœ“  Profile has "following" property

โ†ณ Follow Profile
  POST https://localhost:3443/api/profiles/celeb_tzemanovic/follow [200 OK, 540B, 4ms]
  โœ“  Response code is 200 OK
  โœ“  Response contains "profile" property
  โœ“  Profile has "username" property
  โœ“  Profile has "bio" property
  โœ“  Profile has "image" property
  โœ“  Profile has "following" property
  โœ“  Profile's "following" property is true

โ†ณ Unfollow Profile
  DELETE https://localhost:3443/api/profiles/celeb_tzemanovic/follow [200 OK, 541B, 3ms]
  โœ“  Response code is 200 OK
  โœ“  Response contains "profile" property
  โœ“  Profile has "username" property
  โœ“  Profile has "bio" property
  โœ“  Profile has "image" property
  โœ“  Profile has "following" property
  โœ“  Profile's "following" property is false

โ Tags
โ†ณ All Tags
  GET https://localhost:3443/api/tags [200 OK, 434B, 2ms]
  โœ“  Response code is 200 OK
  โœ“  Response contains "tags" property
  โœ“  "tags" property returned as array

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                         โ”‚ executed โ”‚   failed โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚              iterations โ”‚        1 โ”‚        0 โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                requests โ”‚       31 โ”‚        0 โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚            test-scripts โ”‚       46 โ”‚        0 โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚      prerequest-scripts โ”‚       17 โ”‚        0 โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚              assertions โ”‚      280 โ”‚        0 โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ total run duration: 1024ms                    โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ total data received: 7.43KB (approx)          โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ average response time: 8ms                    โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Fantastic!