defmodule Test.Core.PostsTest do use Test.DataCase, async: true describe "get!/1" do @tag post: :post test "returns the post with the given id", %{posts: %{post: post}} do assert result = Core.Posts.get!(post.id) assert %Schema.Post{} = result assert result.id == post.id end test "raises an Ecto.NoResultsError if there is no matching post" do assert_raise Ecto.NoResultsError, fn -> Core.Posts.get!(Faker.UUID.v4()) end end end describe "get_by_publish_date_and_slug!/2" do @tag blog: :blog test "returns the post with the given publish date and slug", %{blogs: %{blog: blog}} do assert {:ok, blog} = Core.Posts.publish_post(blog) publish_date = DateTime.to_date(blog.published_at) assert result = Core.Posts.get_by_publish_date_and_slug!(publish_date, blog.slug) assert %Schema.Post{} = result assert result.id == blog.id end @tag blog: :blog test "raises an Ecto.NoResultsError if there is no matching post", %{blogs: %{blog: blog}} do assert_raise Ecto.NoResultsError, fn -> Core.Posts.get_by_publish_date_and_slug!(~D[1993-11-28], "first-day-on-earth") end assert {:ok, blog} = Core.Posts.publish_post(blog) assert_raise Ecto.NoResultsError, fn -> Core.Posts.get_by_publish_date_and_slug!(~D[1993-11-28], blog.slug) end end end describe "change_post/1/2" do test "returns a changeset" do assert %Ecto.Changeset{} = Core.Posts.change_post(%{}) assert %Ecto.Changeset{} = Core.Posts.change_post(%Schema.Post{}, %{}) assert %Ecto.Changeset{} = Test.Fixtures.Posts.blog_post(:blog) |> Core.Posts.change_post() assert %Ecto.Changeset{} = %Schema.Post{} |> Core.Posts.change_post(Test.Fixtures.Posts.blog_post(:blog)) assert %Ecto.Changeset{} = Test.Fixtures.Posts.status_post(:status) |> Core.Posts.change_post() assert %Ecto.Changeset{} = %Schema.Post{} |> Core.Posts.change_post(Test.Fixtures.Posts.status_post(:status)) end end describe "create_post/1" do test "creates a status post" do assert {:ok, %Schema.Post{}} = Test.Fixtures.Posts.status_post(:status) |> Core.Posts.create_post() end test "creates a blug post" do assert {:ok, %Schema.Post{}} = Test.Fixtures.Posts.blog_post(:blog) |> Core.Posts.create_post() end test "returns an error changeset for invalid attrs" do assert {:error, %Ecto.Changeset{} = changeset} = Core.Posts.create_post(%{}) refute changeset.valid? assert "must have a kind" in errors_on(changeset).kind assert "must have a body" in errors_on(changeset).body assert {:error, %Ecto.Changeset{} = changeset} = Core.Posts.create_post(%{kind: :blog}) refute changeset.valid? assert "must have a body" in errors_on(changeset).body assert "can't be blank" in errors_on(changeset).title assert "can't be blank" in errors_on(changeset).slug assert {:error, %Ecto.Changeset{} = changeset} = Core.Posts.create_post(%{ kind: :blog, title: "Hello, World!", slug: "hello-world!", body: "This is a sample blog posts." }) refute changeset.valid? assert "has invalid format" in errors_on(changeset).slug end end describe "update_post/2" do @tag blog: :to_update test "updates a blog post", %{blogs: %{to_update: post}} do assert {:ok, %Schema.Post{} = post} = Core.Posts.update_post(post, %{title: "A new title"}) assert post.tid == "to_update" assert post.title == "A new title" end @tag status: :to_update test "updates a status post", %{statuses: %{to_update: post}} do assert {:ok, %Schema.Post{} = post} = Core.Posts.update_post(post, %{body: "Hello, World!"}) assert post.tid == "to_update" assert post.body == "Hello, World!" end end describe "publish_post/1/2" do @describetag post: :to_publish test "publishes a post", %{posts: %{to_publish: to_publish}} do refute to_publish.published_at assert {:ok, published} = Core.Posts.publish_post(to_publish) assert published.tid == "to_publish" assert published.published_at end test "does not update an already published post", %{posts: %{to_publish: to_publish}} do assert {:ok, published} = Core.Posts.publish_post(to_publish) assert {:ok, published_again} = Core.Posts.publish_post(published) assert published.updated_at == published_again.updated_at end end describe "delete_post/1/2" do @describetag post: :to_delete test "soft deletes a post", %{posts: %{to_delete: post}} do refute post.deleted_at assert {:ok, post} = Core.Posts.delete_post(post) assert post.deleted_at end test "does not update an already deleted post", %{posts: %{to_delete: to_delete}} do assert {:ok, deleted} = Core.Posts.delete_post(to_delete) assert {:ok, deleted_again} = Core.Posts.delete_post(deleted) assert deleted.updated_at == deleted_again.updated_at end end describe "unpublish_post/1" do @describetag posts: [:published, :not_published] setup %{posts: %{published: published, not_published: not_published}} do {:ok, published} = Core.Posts.publish_post(published) [posts: %{published: published, not_published: not_published}] end test "unpublishes a post", %{posts: %{published: published}} do assert published.published_at assert {:ok, unpublished} = Core.Posts.unpublish_post(published) refute unpublished.published_at end test "does not update a post that isn't published", %{posts: %{not_published: not_published}} do refute not_published.published_at assert {:ok, not_updated} = Core.Posts.unpublish_post(not_published) assert not_published.updated_at == not_updated.updated_at end end describe "undelete_post/1" do @describetag posts: [:deleted, :not_deleted] setup %{posts: %{deleted: deleted, not_deleted: not_deleted}} do {:ok, deleted} = Core.Posts.delete_post(deleted) [posts: %{deleted: deleted, not_deleted: not_deleted}] end test "undeletees a post", %{posts: %{deleted: deleted}} do assert deleted.deleted_at assert {:ok, undeleted} = Core.Posts.undelete_post(deleted) refute undeleted.deleted_at end test "does not update a post that isn't deleted", %{posts: %{not_deleted: not_deleted}} do refute not_deleted.deleted_at assert {:ok, not_updated} = Core.Posts.undelete_post(not_deleted) assert not_deleted.updated_at == not_updated.updated_at end end end