Skip to content

Commit e881137

Browse files
committed
Use modified_at in Task and Comment to ensure the last write wins
Add TimeValidator and validation
1 parent 7aad455 commit e881137

20 files changed

Lines changed: 176 additions & 72 deletions

lib/code_corps/github/event/issue_comment/changeset_builder.ex

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ defmodule CodeCorps.GitHub.Event.IssueComment.ChangesetBuilder do
88
Comment,
99
Services.MarkdownRendererService,
1010
Task,
11-
User
11+
User,
12+
Validators.TimeValidator
1213
}
1314
alias CodeCorps.GitHub.Adapters.Comment, as: CommentAdapter
1415
alias Ecto.Changeset
@@ -45,6 +46,7 @@ defmodule CodeCorps.GitHub.Event.IssueComment.ChangesetBuilder do
4546
|> Changeset.cast(CommentAdapter.from_api(attrs), @update_attrs)
4647
|> MarkdownRendererService.render_markdown_to_html(:markdown, :body)
4748
|> Changeset.put_change(:modified_from, "github")
49+
|> TimeValidator.validate_time_after(:modified_at)
4850
|> Changeset.validate_required([:markdown, :body])
4951
end
5052
end

lib/code_corps/github/event/issue_comment/comment_deleter.ex

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,8 @@ defmodule CodeCorps.GitHub.Event.IssueComment.CommentDeleter do
77
import Ecto.Query
88

99
@doc """
10-
When provided a `GithubRepo`, a `User` and a GitHub API payload, for each
11-
`Project` associated to that `GithubRepo` via a `ProjectGithubRepo`, it
12-
creates or updates a `Task` associated to the specified `User`.
10+
When provided a GitHub API payload, it deletes each `Comment` associated to
11+
the specified `IssueComment`.
1312
"""
1413
@spec delete_all(map) :: {:ok, list(Comment.t)}
1514
def delete_all(%{"comment" => %{"id" => github_id}}) do

lib/code_corps/github/event/issue_comment/comment_syncer.ex

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ defmodule CodeCorps.GitHub.Event.IssueComment.CommentSyncer do
1010
alias Ecto.Changeset
1111

1212
@doc """
13-
When provided a `GithubRepo`, a `User` and a GitHub API payload, for each
14-
`Project` associated to that `GithubRepo` via a `ProjectGithubRepo`, it
15-
creates or updates a `Task` associated to the specified `User`.
13+
When provided a list of `Task`s, a `User` and a GitHub API payload, for each
14+
`Comment` associated to those `Task`s it creates or updates a `Comment`
15+
associated to the specified `User`.
1616
"""
1717
@spec sync_all(list(Task.t), User.t, map) :: {:ok, list(Comment.t)}
1818
def sync_all(tasks, %User{} = user, %{} = payload) do

lib/code_corps/github/event/issues/changeset_builder.ex

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ defmodule CodeCorps.GitHub.Event.Issues.ChangesetBuilder do
1010
Services.MarkdownRendererService,
1111
Task,
1212
TaskList,
13-
User
13+
User,
14+
Validators.TimeValidator
1415
}
1516
alias CodeCorps.GitHub.Adapters.Task, as: TaskAdapter
1617
alias Ecto.Changeset
@@ -68,6 +69,7 @@ defmodule CodeCorps.GitHub.Event.Issues.ChangesetBuilder do
6869
|> Changeset.cast(TaskAdapter.from_api(issue_attrs), @update_attrs)
6970
|> MarkdownRendererService.render_markdown_to_html(:markdown, :body)
7071
|> Changeset.put_change(:modified_from, "github")
72+
|> TimeValidator.validate_time_after(:modified_at)
7173
|> Changeset.validate_required([:project_id, :title, :user_id])
7274
|> Changeset.assoc_constraint(:github_repo)
7375
|> Changeset.assoc_constraint(:project)
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
defmodule CodeCorps.Validators.TimeValidator do
2+
@moduledoc """
3+
Used for validating timestamp fields in a given changeset.
4+
"""
5+
6+
alias Ecto.Changeset
7+
8+
@doc """
9+
Validates a time after a given time.
10+
"""
11+
def validate_time_after(%{data: data} = changeset, field) do
12+
previous_time = Map.get(data, field)
13+
current_time = Changeset.get_change(changeset, field)
14+
case current_time |> Timex.after?(previous_time) do
15+
true -> changeset
16+
false -> Changeset.add_error(changeset, field, "cannot be before the last recorded time")
17+
end
18+
end
19+
end

test/fixtures/github/endpoints/issue.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -87,10 +87,10 @@
8787
},
8888
"open_issues": 4,
8989
"closed_issues": 8,
90-
"created_at": "2011-04-10T20:09:31Z",
91-
"updated_at": "2014-03-03T18:58:10Z",
92-
"closed_at": "2013-02-12T13:22:01Z",
93-
"due_on": "2012-10-09T23:39:01Z"
90+
"created_at": "2071-04-10T20:09:31Z",
91+
"updated_at": "2074-03-03T18:58:10Z",
92+
"closed_at": "2073-02-12T13:22:01Z",
93+
"due_on": "2072-10-09T23:39:01Z"
9494
},
9595
"locked": false,
9696
"comments": 0,
@@ -101,8 +101,8 @@
101101
"patch_url": "https://github.com/octocat/Hello-World/pull/1347.patch"
102102
},
103103
"closed_at": null,
104-
"created_at": "2011-04-22T13:33:48Z",
105-
"updated_at": "2011-04-22T13:33:48Z",
104+
"created_at": "2071-04-22T13:33:48Z",
105+
"updated_at": "2071-04-22T13:33:48Z",
106106
"closed_by": {
107107
"login": "octocat",
108108
"id": 1,

test/fixtures/github/events/issue_comment_created.json

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@
4040
"assignee": null,
4141
"milestone": null,
4242
"comments": 1,
43-
"created_at": "2015-05-05T23:40:28Z",
44-
"updated_at": "2015-05-05T23:40:28Z",
43+
"created_at": "2075-05-05T23:40:28Z",
44+
"updated_at": "2075-05-05T23:40:28Z",
4545
"closed_at": null,
4646
"body": "It looks like you accidently spelled 'commit' with two 't's."
4747
},
@@ -69,8 +69,8 @@
6969
"type": "User",
7070
"site_admin": false
7171
},
72-
"created_at": "2015-05-05T23:40:28Z",
73-
"updated_at": "2015-05-05T23:40:28Z",
72+
"created_at": "2075-05-05T23:40:28Z",
73+
"updated_at": "2075-05-05T23:40:28Z",
7474
"body": "You are totally right! I'll get this fixed right away."
7575
},
7676
"repository": {
@@ -136,9 +136,9 @@
136136
"notifications_url": "https://api.github.com/repos/baxterthehacker/public-repo/notifications{?since,all,participating}",
137137
"labels_url": "https://api.github.com/repos/baxterthehacker/public-repo/labels{/name}",
138138
"releases_url": "https://api.github.com/repos/baxterthehacker/public-repo/releases{/id}",
139-
"created_at": "2015-05-05T23:40:12Z",
140-
"updated_at": "2015-05-05T23:40:12Z",
141-
"pushed_at": "2015-05-05T23:40:27Z",
139+
"created_at": "2075-05-05T23:40:12Z",
140+
"updated_at": "2075-05-05T23:40:12Z",
141+
"pushed_at": "2075-05-05T23:40:27Z",
142142
"git_url": "git://github.com/baxterthehacker/public-repo.git",
143143
"ssh_url": "[email protected]:baxterthehacker/public-repo.git",
144144
"clone_url": "https://github.com/baxterthehacker/public-repo.git",

test/fixtures/github/events/issue_comment_created_by_bot.json

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@
4040
"assignee": null,
4141
"milestone": null,
4242
"comments": 1,
43-
"created_at": "2015-05-05T23:40:28Z",
44-
"updated_at": "2015-05-05T23:40:28Z",
43+
"created_at": "2075-05-05T23:40:28Z",
44+
"updated_at": "2075-05-05T23:40:28Z",
4545
"closed_at": null,
4646
"body": "It looks like you accidently spelled 'commit' with two 't's."
4747
},
@@ -69,8 +69,8 @@
6969
"type": "Bot",
7070
"site_admin": false
7171
},
72-
"created_at": "2015-05-05T23:40:28Z",
73-
"updated_at": "2015-05-05T23:40:28Z",
72+
"created_at": "2075-05-05T23:40:28Z",
73+
"updated_at": "2075-05-05T23:40:28Z",
7474
"body": "You are totally right! I'll get this fixed right away."
7575
},
7676
"repository": {
@@ -136,9 +136,9 @@
136136
"notifications_url": "https://api.github.com/repos/baxterthehacker/public-repo/notifications{?since,all,participating}",
137137
"labels_url": "https://api.github.com/repos/baxterthehacker/public-repo/labels{/name}",
138138
"releases_url": "https://api.github.com/repos/baxterthehacker/public-repo/releases{/id}",
139-
"created_at": "2015-05-05T23:40:12Z",
140-
"updated_at": "2015-05-05T23:40:12Z",
141-
"pushed_at": "2015-05-05T23:40:27Z",
139+
"created_at": "2075-05-05T23:40:12Z",
140+
"updated_at": "2075-05-05T23:40:12Z",
141+
"pushed_at": "2075-05-05T23:40:27Z",
142142
"git_url": "git://github.com/baxterthehacker/public-repo.git",
143143
"ssh_url": "[email protected]:baxterthehacker/public-repo.git",
144144
"clone_url": "https://github.com/baxterthehacker/public-repo.git",

test/fixtures/github/events/issue_comment_deleted.json

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@
4040
"assignee": null,
4141
"milestone": null,
4242
"comments": 1,
43-
"created_at": "2015-05-05T23:40:28Z",
44-
"updated_at": "2015-05-05T23:40:28Z",
43+
"created_at": "2075-05-05T23:40:28Z",
44+
"updated_at": "2075-05-05T23:40:28Z",
4545
"closed_at": null,
4646
"body": "It looks like you accidently spelled 'commit' with two 't's."
4747
},
@@ -69,8 +69,8 @@
6969
"type": "User",
7070
"site_admin": false
7171
},
72-
"created_at": "2015-05-05T23:40:28Z",
73-
"updated_at": "2015-05-05T23:40:28Z",
72+
"created_at": "2075-05-05T23:40:28Z",
73+
"updated_at": "2075-05-05T23:40:28Z",
7474
"body": "You are totally right! I'll get this fixed right away."
7575
},
7676
"repository": {
@@ -136,9 +136,9 @@
136136
"notifications_url": "https://api.github.com/repos/baxterthehacker/public-repo/notifications{?since,all,participating}",
137137
"labels_url": "https://api.github.com/repos/baxterthehacker/public-repo/labels{/name}",
138138
"releases_url": "https://api.github.com/repos/baxterthehacker/public-repo/releases{/id}",
139-
"created_at": "2015-05-05T23:40:12Z",
140-
"updated_at": "2015-05-05T23:40:12Z",
141-
"pushed_at": "2015-05-05T23:40:27Z",
139+
"created_at": "2075-05-05T23:40:12Z",
140+
"updated_at": "2075-05-05T23:40:12Z",
141+
"pushed_at": "2075-05-05T23:40:27Z",
142142
"git_url": "git://github.com/baxterthehacker/public-repo.git",
143143
"ssh_url": "[email protected]:baxterthehacker/public-repo.git",
144144
"clone_url": "https://github.com/baxterthehacker/public-repo.git",

test/fixtures/github/events/issue_comment_edited.json

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@
4040
"assignee": null,
4141
"milestone": null,
4242
"comments": 1,
43-
"created_at": "2015-05-05T23:40:28Z",
44-
"updated_at": "2015-05-05T23:40:28Z",
43+
"created_at": "2075-05-05T23:40:28Z",
44+
"updated_at": "2075-05-05T23:40:28Z",
4545
"closed_at": null,
4646
"body": "It looks like you accidently spelled 'commit' with two 't's."
4747
},
@@ -69,8 +69,8 @@
6969
"type": "User",
7070
"site_admin": false
7171
},
72-
"created_at": "2015-05-05T23:40:28Z",
73-
"updated_at": "2015-05-05T23:40:28Z",
72+
"created_at": "2075-05-05T23:40:28Z",
73+
"updated_at": "2075-05-05T23:40:28Z",
7474
"body": "You are totally right! I'll get this fixed right away."
7575
},
7676
"repository": {
@@ -136,9 +136,9 @@
136136
"notifications_url": "https://api.github.com/repos/baxterthehacker/public-repo/notifications{?since,all,participating}",
137137
"labels_url": "https://api.github.com/repos/baxterthehacker/public-repo/labels{/name}",
138138
"releases_url": "https://api.github.com/repos/baxterthehacker/public-repo/releases{/id}",
139-
"created_at": "2015-05-05T23:40:12Z",
140-
"updated_at": "2015-05-05T23:40:12Z",
141-
"pushed_at": "2015-05-05T23:40:27Z",
139+
"created_at": "2075-05-05T23:40:12Z",
140+
"updated_at": "2075-05-05T23:40:12Z",
141+
"pushed_at": "2075-05-05T23:40:27Z",
142142
"git_url": "git://github.com/baxterthehacker/public-repo.git",
143143
"ssh_url": "[email protected]:baxterthehacker/public-repo.git",
144144
"clone_url": "https://github.com/baxterthehacker/public-repo.git",

0 commit comments

Comments
 (0)