Skip to content

Commit

Permalink
Fixes #739 and fixes #740 by adding website to projects
Browse files Browse the repository at this point in the history
  • Loading branch information
joshsmith committed Mar 9, 2017
1 parent bf313db commit 1e7c6e1
Show file tree
Hide file tree
Showing 11 changed files with 131 additions and 16 deletions.
25 changes: 25 additions & 0 deletions lib/code_corps/helpers/url.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
defmodule CodeCorps.Helpers.URL do
@moduledoc """
Provides some helpers for assembling and validating URLs.
"""

alias Ecto.Changeset

@doc """
Prefixes the URL with `http://` in the event that `http://` and `https://` are
not already the starting format. If `nil`, simply returns `nil`.
"""
def prefix_url(changeset, key) do
changeset
|> Changeset.update_change(key, &do_prefix_url/1)
end

defp do_prefix_url(nil), do: nil
defp do_prefix_url("http://" <> rest), do: "http://" <> rest
defp do_prefix_url("https://" <> rest), do: "https://" <> rest
defp do_prefix_url(value), do: "http://" <> value

def valid_format do
~r/\A((http|https):\/\/)?[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,}(([0-9]{1,5})?\/.*)?#=\z/ix
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
defmodule CodeCorps.Repo.Migrations.AddWebsiteToProject do
use Ecto.Migration

def change do
alter table(:projects) do
add :website, :string
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
defmodule CodeCorps.Repo.Migrations.AddShouldLinkExternallyToProject do
use Ecto.Migration

def change do
alter table(:projects) do
add :should_link_externally, :boolean, default: false
end
end
end
10 changes: 6 additions & 4 deletions priv/repo/structure.sql
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
-- PostgreSQL database dump
--

-- Dumped from database version 9.5.1
-- Dumped by pg_dump version 9.5.1
-- Dumped from database version 9.5.4
-- Dumped by pg_dump version 9.5.4

SET statement_timeout = 0;
SET lock_timeout = 0;
Expand Down Expand Up @@ -369,7 +369,9 @@ CREATE TABLE projects (
approved boolean DEFAULT false,
cloudinary_public_id character varying(255),
default_color character varying(255),
owner_id integer
owner_id integer,
website character varying(255),
should_link_externally boolean DEFAULT false
);


Expand Down Expand Up @@ -2608,5 +2610,5 @@ ALTER TABLE ONLY user_tasks
-- PostgreSQL database dump complete
--

INSERT INTO "schema_migrations" (version) VALUES (20160723215749), (20160804000000), (20160804001111), (20160805132301), (20160805203929), (20160808143454), (20160809214736), (20160810124357), (20160815125009), (20160815143002), (20160816020347), (20160816034021), (20160817220118), (20160818000944), (20160818132546), (20160820113856), (20160820164905), (20160822002438), (20160822004056), (20160822011624), (20160822020401), (20160822044612), (20160830081224), (20160830224802), (20160911233738), (20160912002705), (20160912145957), (20160918003206), (20160928232404), (20161003185918), (20161019090945), (20161019110737), (20161020144622), (20161021131026), (20161031001615), (20161121005339), (20161121014050), (20161121043941), (20161121045709), (20161122015942), (20161123081114), (20161123150943), (20161124085742), (20161125200620), (20161126045705), (20161127054559), (20161205024856), (20161207112519), (20161209192504), (20161212005641), (20161214005935), (20161215052051), (20161216051447), (20161218005913), (20161219160401), (20161219163909), (20161220141753), (20161221085759), (20161226213600), (20161231063614), (20170102130055), (20170102181053), (20170104113708), (20170104212623), (20170104235423), (20170106013143), (20170115035159), (20170115230549), (20170121014100), (20170131234029), (20170201014901), (20170201025454), (20170201035458), (20170201183258), (20170220032224), (20170224233516), (20170226050552), (20170228085250), (20170228144515), (20170228145755);
INSERT INTO "schema_migrations" (version) VALUES (20160723215749), (20160804000000), (20160804001111), (20160805132301), (20160805203929), (20160808143454), (20160809214736), (20160810124357), (20160815125009), (20160815143002), (20160816020347), (20160816034021), (20160817220118), (20160818000944), (20160818132546), (20160820113856), (20160820164905), (20160822002438), (20160822004056), (20160822011624), (20160822020401), (20160822044612), (20160830081224), (20160830224802), (20160911233738), (20160912002705), (20160912145957), (20160918003206), (20160928232404), (20161003185918), (20161019090945), (20161019110737), (20161020144622), (20161021131026), (20161031001615), (20161121005339), (20161121014050), (20161121043941), (20161121045709), (20161122015942), (20161123081114), (20161123150943), (20161124085742), (20161125200620), (20161126045705), (20161127054559), (20161205024856), (20161207112519), (20161209192504), (20161212005641), (20161214005935), (20161215052051), (20161216051447), (20161218005913), (20161219160401), (20161219163909), (20161220141753), (20161221085759), (20161226213600), (20161231063614), (20170102130055), (20170102181053), (20170104113708), (20170104212623), (20170104235423), (20170106013143), (20170115035159), (20170115230549), (20170121014100), (20170131234029), (20170201014901), (20170201025454), (20170201035458), (20170201183258), (20170220032224), (20170224233516), (20170226050552), (20170228085250), (20170308214128), (20170308220713);

31 changes: 31 additions & 0 deletions test/lib/code_corps/helpers/url_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
defmodule CodeCorps.Helpers.URLTest do
use ExUnit.Case, async: true
import CodeCorps.Helpers.URL
alias Ecto.Changeset

test "returns nil when nil" do
changeset = create_prefixed_changeset(nil)
assert Changeset.get_change(changeset, :url) == nil
end

test "returns the original when starts with http://" do
original = "http://www.google.com"
changeset = create_prefixed_changeset(original)
assert Changeset.get_change(changeset, :url) == original
end

test "returns the original when starts with https://" do
original = "https://www.google.com"
changeset = create_prefixed_changeset(original)
assert Changeset.get_change(changeset, :url) == original
end

test "returns prefixed with http:// in every other case" do
changeset = create_prefixed_changeset("www.google.com")
assert Changeset.get_change(changeset, :url) == "http://www.google.com"
end

defp create_prefixed_changeset(value) do
%Changeset{changes: %{url: value}} |> prefix_url(:url)
end
end
36 changes: 36 additions & 0 deletions test/models/project_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -96,5 +96,41 @@ defmodule CodeCorps.ProjectTest do
changeset = Project.update_changeset(%Project{}, %{organization_id: 1})
assert :error == changeset |> fetch_change(:organization_id)
end

test "requires :website to be in proper format" do
project = %Project{}
attrs = %{website: "bad <> website"}

changeset = Project.update_changeset(project, attrs)

assert_error_message(changeset, :website, "has invalid format")
end

test "doesn't require :website to be part of the changes" do
project = %Project{}
attrs = %{}

changeset = Project.update_changeset(project, attrs)

refute Keyword.has_key?(changeset.errors, :website)
end

test "prefixes website with 'http://' if there is no prefix" do
project = %Project{website: "https://first.com"}
attrs = %{website: "example.com"}

changeset = Project.update_changeset(project, attrs)

assert changeset.changes.website == "http://example.com"
end

test "doesn't make a change to the url when there is no param for it" do
project = %Project{website: "https://first.com"}
attrs = %{}

changeset = Project.update_changeset(project, attrs)

refute Map.has_key?(changeset.changes, :website)
end
end
end
3 changes: 2 additions & 1 deletion test/support/factories.ex
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ defmodule CodeCorps.Factories do
title: sequence(:title, &"Project #{&1}"),
slug: sequence(:slug, &"project-#{&1}"),
organization: build(:organization),
owner: build(:user)
owner: build(:user),
website: sequence(:website, &"http://test-#{&1}.com")
}
end

Expand Down
2 changes: 2 additions & 0 deletions test/views/project_view_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,12 @@ defmodule CodeCorps.ProjectViewTest do
"inserted-at" => project.inserted_at,
"long-description-body" => project.long_description_body,
"long-description-markdown" => project.long_description_markdown,
"should-link-externally" => project.should_link_externally,
"slug" => project.slug,
"title" => project.title,
"total-monthly-donated" => project.total_monthly_donated,
"updated-at" => project.updated_at,
"website" => project.website,
},
"id" => project.id |> Integer.to_string,
"relationships" => %{
Expand Down
6 changes: 6 additions & 0 deletions web/models/project.ex
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ defmodule CodeCorps.Project do

import CodeCorps.Helpers.RandomIconColor
import CodeCorps.Helpers.Slug
import CodeCorps.Helpers.URL, only: [prefix_url: 2]
import CodeCorps.Validators.SlugValidator

alias CodeCorps.Services.MarkdownRendererService
Expand All @@ -21,9 +22,11 @@ defmodule CodeCorps.Project do
field :description, :string
field :long_description_body, :string
field :long_description_markdown, :string
field :should_link_externally, :boolean, default: false # temporary for linking to projects off Code Corps while in alpha
field :slug, :string
field :title, :string
field :total_monthly_donated, :integer, default: 0
field :website, :string

belongs_to :organization, CodeCorps.Organization
belongs_to :owner, CodeCorps.User
Expand Down Expand Up @@ -73,6 +76,9 @@ defmodule CodeCorps.Project do
def update_changeset(struct, params) do
struct
|> changeset(params)
|> cast(params, [:website])
|> prefix_url(:website)
|> validate_format(:website, CodeCorps.Helpers.URL.valid_format())
end

def update_total_changeset(struct, params) do
Expand Down
12 changes: 2 additions & 10 deletions web/models/user.ex
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ defmodule CodeCorps.User do
use CodeCorps.Web, :model

import CodeCorps.Helpers.RandomIconColor
import CodeCorps.Helpers.URL, only: [prefix_url: 2]
import CodeCorps.Validators.SlugValidator

alias CodeCorps.SluggedRoute
Expand Down Expand Up @@ -90,7 +91,7 @@ defmodule CodeCorps.User do
|> changeset(params)
|> cast(params, [:biography, :cloudinary_public_id, :first_name, :last_name, :state_transition, :twitter, :website])
|> prefix_url(:website)
|> validate_format(:website, ~r/\A((http|https):\/\/)?[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,}(([0-9]{1,5})?\/.*)?#=\z/ix)
|> validate_format(:website, CodeCorps.Helpers.URL.valid_format())
|> validate_format(:twitter, ~r/\A[a-zA-Z0-9_]{1,15}\z/)
|> apply_state_transition(struct)
end
Expand Down Expand Up @@ -136,15 +137,6 @@ defmodule CodeCorps.User do
end
end

defp prefix_url(changeset, key) do
changeset
|> update_change(key, &do_prefix_url/1)
end
defp do_prefix_url(nil), do: nil
defp do_prefix_url("http://" <> rest), do: "http://" <> rest
defp do_prefix_url("https://" <> rest), do: "https://" <> rest
defp do_prefix_url(value), do: "http://" <> value

defp check_email_valid(struct, email) do
struct
|> Map.put(:valid, String.match?(email, ~r/@/))
Expand Down
4 changes: 3 additions & 1 deletion web/views/project_view.ex
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ defmodule CodeCorps.ProjectView do
:slug, :title, :can_activate_donations, :cloudinary_public_id,
:description, :donations_active, :icon_thumb_url,
:icon_large_url, :long_description_body, :long_description_markdown,
:inserted_at, :total_monthly_donated, :updated_at]
:inserted_at, :should_link_externally, :total_monthly_donated, :updated_at,
:website
]

has_one :organization, serializer: CodeCorps.OrganizationView
has_one :owner, serializer: CodeCorps.UserView
Expand Down

0 comments on commit 1e7c6e1

Please sign in to comment.