mine-shipper 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,19 @@
1
+ #
2
+ # Copyright (C) 2020 Takuro Ashie <ashie@clear-code.com>
3
+ #
4
+ # This program is free software: you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation, either version 3 of the License, or
7
+ # (at your option) any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+
17
+ module MineShipper
18
+ VERSION = '0.0.1'
19
+ end
@@ -0,0 +1,24 @@
1
+ require File.expand_path('../lib/mine-shipper/version', __FILE__)
2
+
3
+ Gem::Specification.new do |spec|
4
+ spec.name = "mine-shipper"
5
+ spec.version = MineShipper::VERSION
6
+ spec.authors = ["Takuro Ashie"]
7
+ spec.email = ["ashie@clear-code.com"]
8
+ spec.summary = "Connect GitHub issues with Redmine"
9
+ spec.description = "Duplicate comments in GitHub issues to Redmine"
10
+ spec.homepage = "https://gitlab.com/clear-code/mine-shipper"
11
+ spec.license = "GPL-3.0-or-later"
12
+
13
+ spec.files = `git ls-files`.split($/)
14
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
15
+ spec.bindir = "bin"
16
+ spec.executables = spec.files.grep(%r{^bin/}) {|f| File.basename(f) }
17
+ spec.require_paths = ["lib"]
18
+
19
+ spec.add_runtime_dependency("octokit", "~> 4.0")
20
+ spec.add_runtime_dependency("dotenv", "~> 2.7")
21
+ spec.add_development_dependency("rake", "~> 13.0")
22
+ spec.add_development_dependency("test-unit", "~> 3.3")
23
+ spec.add_development_dependency("test-unit-rr", "~> 1.0")
24
+ end
data/sample.env ADDED
@@ -0,0 +1,5 @@
1
+ #MINE_SHIPPER_LOG_LEVEL=WARN
2
+ GITHUB_ACCESS_TOKEN=
3
+ REDMINE_BASE_URL="https://redmine.example.com"
4
+ REDMINE_API_KEY="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
5
+ REDMINE_CUSTOM_FIELD_ID=4
@@ -0,0 +1,64 @@
1
+ require "test/unit"
2
+ require "json"
3
+ require "time"
4
+ require_relative "../lib/mine-shipper/issue_comment"
5
+
6
+ class TestIssueComment < Test::Unit::TestCase
7
+ include MineShipper
8
+
9
+ CREATED_TIME = Time.parse("2020-08-06 10:41:42 +0000")
10
+ UPDATED_TIME = Time.parse("2020-08-06 10:52:12 +0000")
11
+ EXPECTED_FIRST_LINE = "### [foobar commented on #{CREATED_TIME.getlocal}](http://example.com/issue/1234)\n"
12
+ EXPECTED_BODY =
13
+ EXPECTED_FIRST_LINE +
14
+ "{{collapse(More...)\n" +
15
+ "* created_at: \"#{CREATED_TIME.getlocal}\"\n" +
16
+ "* updated_at: \"#{UPDATED_TIME.getlocal}\"\n"+
17
+ "}}\n" +
18
+ "\n" +
19
+ "hoge"
20
+
21
+ class TestComment < IssueComment
22
+ attr_reader :created_at, :user, :url, :body
23
+ attr_accessor :body, :updated_at
24
+
25
+ def initialize
26
+ @created_at = CREATED_TIME
27
+ @updated_at = UPDATED_TIME
28
+ @user = "foobar"
29
+ @url = "http://example.com/issue/1234"
30
+ @body = "hoge"
31
+ end
32
+ end
33
+
34
+ test "render" do
35
+ comment = TestComment.new
36
+ assert_equal(EXPECTED_BODY, comment.render)
37
+ end
38
+
39
+ data('corresponding' => [EXPECTED_FIRST_LINE, true],
40
+ 'with heading space' => [" " + EXPECTED_FIRST_LINE, false],
41
+ 'missing line break' => [EXPECTED_FIRST_LINE.delete("\n"), false],
42
+ 'different user' => [EXPECTED_FIRST_LINE.gsub("foobar", "hoge"), false],
43
+ 'different date' => [EXPECTED_FIRST_LINE.gsub("2020", "2018"), false],
44
+ 'different url' => [EXPECTED_FIRST_LINE.gsub("example.com", "example.org"), false])
45
+ test "corresponding?" do |data|
46
+ body, expected = data
47
+ comment1 = TestComment.new
48
+ comment2 = TestComment.new
49
+ comment1.body = body
50
+ assert_equal(expected, comment1.corresponding?(comment2))
51
+ end
52
+
53
+ data('same date' => ["2020-08-06 10:52:12 +0000", true],
54
+ 'updated at upstream' => ["2020-08-06 10:52:13 +0000", false],
55
+ 'past date' => ["2020-08-06 10:52:11 +0000", true])
56
+ test "updated?" do
57
+ date, expected = data
58
+ comment1 = TestComment.new
59
+ comment2 = TestComment.new
60
+ comment1.body = EXPECTED_BODY
61
+ comment2.updated_at = Time.parse(date)
62
+ assert_equal(expected, comment1.updated?(comment2))
63
+ end
64
+ end
@@ -0,0 +1,139 @@
1
+ require "test/unit"
2
+ require "test/unit/rr"
3
+ require "json"
4
+ require "time"
5
+ require_relative "../lib/mine-shipper/redmine"
6
+
7
+ class TestRedmineIssue < Test::Unit::TestCase
8
+ include MineShipper
9
+
10
+ TEST_ISSUE = {
11
+ id: 13,
12
+ subject: "test subject",
13
+ journals: [
14
+ {
15
+ created_on: Time.parse("2020-08-06 09:41:42 +0000"),
16
+ updated_on: Time.parse("2020-08-06 09:52:12 +0000"),
17
+ notes: "hoge"
18
+ },
19
+ {
20
+ created_on: Time.parse("2020-08-06 10:41:42 +0000"),
21
+ updated_on: Time.parse("2020-08-06 10:52:12 +0000"),
22
+ notes: ""
23
+ },
24
+ {
25
+ created_on: Time.parse("2020-08-06 11:41:42 +0000"),
26
+ updated_on: Time.parse("2020-08-06 11:52:12 +0000"),
27
+ notes: "hage"
28
+ }
29
+ ]
30
+ }
31
+
32
+ setup do
33
+ obj = JSON.parse(TEST_ISSUE.to_json)
34
+ @issue = Redmine::Issue.new(nil, obj)
35
+ end
36
+
37
+ test "tracker" do
38
+ assert_equal("Redmine", @issue.tracker)
39
+ end
40
+
41
+ test "id" do
42
+ assert_equal(13, @issue.id)
43
+ end
44
+
45
+ test "identifier" do
46
+ assert_equal("#13", @issue.identifier)
47
+ end
48
+
49
+ test "title" do
50
+ assert_equal("test subject", @issue.title)
51
+ end
52
+
53
+ test "comments" do
54
+ assert_equal(2, @issue.comments.length)
55
+ end
56
+
57
+ sub_test_case "post comments" do
58
+ class TestComment < IssueComment
59
+ attr_accessor :created_at, :updated_at, :user, :url, :body
60
+
61
+ def initialize
62
+ @created_at = Time.parse("2020-08-06 12:41:42 +0000")
63
+ @updated_at = Time.parse("2020-08-06 12:52:12 +0000")
64
+ @user = "foobar"
65
+ @url = "https://example.com/issue/13#comment1"
66
+ @body = "hoge"
67
+ end
68
+ end
69
+
70
+ setup do
71
+ @redmine = Redmine.new("https://redmine.example.com")
72
+ obj = JSON.parse(TEST_ISSUE.to_json)
73
+ @issue = Redmine::Issue.new(@redmine, obj)
74
+ @comment = TestComment.new
75
+ @comment_params = {
76
+ issue: {
77
+ notes: @comment.render
78
+ }
79
+ }
80
+ end
81
+
82
+ test "post_comment" do
83
+ mock(@redmine).api_request("issues/13.json", @comment_params, :put) { "200" }
84
+ assert_equal("200", @issue.post_comment(@comment))
85
+ end
86
+
87
+ test "sync_comment" do
88
+ mock(@redmine).api_request("issues/13.json", @comment_params, :put) { "200" }
89
+ assert_equal("200", @issue.sync_comment(@comment))
90
+ end
91
+
92
+ test "don't sync_comment" do
93
+ stub(@issue.comments[0]).corresponding? {true}
94
+ stub(@redmine).api_request do
95
+ raise "Updating an issue isn't implemented yet since Redmine doesn't have API to do it"
96
+ end
97
+ assert_nil(@issue.sync_comment(@comment))
98
+ end
99
+ end
100
+ end
101
+
102
+ class TestRedmineComment < Test::Unit::TestCase
103
+ include MineShipper
104
+
105
+ TEST_COMMENT = {
106
+ created_on: Time.parse("2020-08-06 10:41:42 +0000"),
107
+ updated_on: Time.parse("2020-08-06 10:52:12 +0000"),
108
+ notes: "hoge"
109
+ }
110
+
111
+ setup do
112
+ obj = JSON.parse(TEST_COMMENT.to_json)
113
+ @comment = Redmine::Comment.new(obj)
114
+ end
115
+
116
+ test "tracker" do
117
+ assert_equal("Redmine", @comment.tracker)
118
+ end
119
+
120
+ test "body" do
121
+ assert_equal("hoge", @comment.body)
122
+ end
123
+
124
+ test "created_at" do
125
+ assert_equal(TEST_COMMENT[:created_on], @comment.created_at)
126
+ end
127
+
128
+ test "updated_at" do
129
+ assert_raise(NotImplemented) do
130
+ assert_equal(TEST_COMMENT[:updated_on], @comment.updated_at)
131
+ end
132
+ end
133
+
134
+ test "user" do
135
+ assert_raise(NotImplemented) do
136
+ assert_equal(TEST_COMMENT[:updated_on], @comment.user)
137
+ end
138
+ end
139
+ end
metadata ADDED
@@ -0,0 +1,133 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mine-shipper
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Takuro Ashie
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2021-03-29 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: octokit
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '4.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '4.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: dotenv
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '2.7'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '2.7'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '13.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '13.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: test-unit
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.3'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.3'
69
+ - !ruby/object:Gem::Dependency
70
+ name: test-unit-rr
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '1.0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '1.0'
83
+ description: Duplicate comments in GitHub issues to Redmine
84
+ email:
85
+ - ashie@clear-code.com
86
+ executables:
87
+ - mine-shipper
88
+ extensions: []
89
+ extra_rdoc_files: []
90
+ files:
91
+ - ".gitignore"
92
+ - COPYING
93
+ - Gemfile
94
+ - Gemfile.lock
95
+ - README.md
96
+ - Rakefile
97
+ - bin/mine-shipper
98
+ - lib/mine-shipper/app.rb
99
+ - lib/mine-shipper/config.rb
100
+ - lib/mine-shipper/github.rb
101
+ - lib/mine-shipper/issue_comment.rb
102
+ - lib/mine-shipper/redmine.rb
103
+ - lib/mine-shipper/version.rb
104
+ - mine-shipper.gemspec
105
+ - sample.env
106
+ - test/test_issue_comment.rb
107
+ - test/test_redmine.rb
108
+ homepage: https://gitlab.com/clear-code/mine-shipper
109
+ licenses:
110
+ - GPL-3.0-or-later
111
+ metadata: {}
112
+ post_install_message:
113
+ rdoc_options: []
114
+ require_paths:
115
+ - lib
116
+ required_ruby_version: !ruby/object:Gem::Requirement
117
+ requirements:
118
+ - - ">="
119
+ - !ruby/object:Gem::Version
120
+ version: '0'
121
+ required_rubygems_version: !ruby/object:Gem::Requirement
122
+ requirements:
123
+ - - ">="
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ requirements: []
127
+ rubygems_version: 3.1.2
128
+ signing_key:
129
+ specification_version: 4
130
+ summary: Connect GitHub issues with Redmine
131
+ test_files:
132
+ - test/test_issue_comment.rb
133
+ - test/test_redmine.rb