dovico 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,3 @@
1
+ module Dovico
2
+ VERSION = '1.0.0'
3
+ end
@@ -0,0 +1,24 @@
1
+ require "simplecov"
2
+ require "simplecov-rcov"
3
+ SimpleCov.formatters = [
4
+ SimpleCov::Formatter::HTMLFormatter,
5
+ SimpleCov::Formatter::RcovFormatter
6
+ ]
7
+ SimpleCov.start do
8
+ add_filter "db/"
9
+ add_filter "spec/"
10
+ add_group "Dovico", "lib/dovico"
11
+ end
12
+ require "rspec"
13
+ require "rspec/its"
14
+ require "timecop"
15
+ require "rack/test"
16
+ require 'webmock/rspec'
17
+
18
+ require 'pry'
19
+
20
+ # Load libs
21
+ require "dovico"
22
+
23
+ Timecop.safe_mode = true
24
+ WebMock.disable_net_connect!(allow_localhost: true)
@@ -0,0 +1,81 @@
1
+ require "helper"
2
+
3
+ module Dovico
4
+ describe Dovico::ApiClient do
5
+ let(:client_token) { "aaaaa-client-token-aaaaa" }
6
+ let(:user_token) { "zzzzz-user-token-zzzzz" }
7
+ let(:response_body) do
8
+ {
9
+ "Stubbed": "Response"
10
+ }.to_json
11
+ end
12
+
13
+ before do
14
+ Dovico::ApiClient.initialize!(client_token, user_token)
15
+ end
16
+
17
+ describe ".get" do
18
+ context 'with a succcessful response' do
19
+ it "passes the correct headers to the request and parses the JSON response" do
20
+ stub_request(
21
+ :get,
22
+ "#{Dovico::ApiClient::API_URL}TimeEntries?filter=1234%205678&version=#{Dovico::ApiClient::API_VERSION}"
23
+ )
24
+ .with(
25
+ headers: {
26
+ 'Accept': 'application/json',
27
+ 'Content-Type': 'application/json',
28
+ 'Authorization': "WRAP access_token=\"client=#{client_token}&user_token=#{user_token}\"",
29
+ }
30
+ )
31
+ .to_return(body: response_body)
32
+
33
+ response = Dovico::ApiClient.get(
34
+ 'TimeEntries',
35
+ params: {
36
+ filter: '1234 5678'
37
+ }
38
+ )
39
+
40
+ expect(response).to eq({"Stubbed": "Response"}.stringify_keys)
41
+ end
42
+ end
43
+
44
+ context 'with a succcessful response' do
45
+ it "raises an error if the API response is not 200 OK" do
46
+ stub_request(:get, "#{Dovico::ApiClient::API_URL}TimeEntries?version=#{Dovico::ApiClient::API_VERSION}")
47
+ .to_return(
48
+ status: 503,
49
+ body: response_body
50
+ )
51
+
52
+ expect { Dovico::ApiClient.get('TimeEntries') }.to raise_error 'Error during HTTP request'
53
+ end
54
+ end
55
+ end
56
+
57
+ describe ".post" do
58
+ it 'posts the body with a POST request' do
59
+ stub_request(:post,
60
+ "#{Dovico::ApiClient::API_URL}TimeEntries?version=#{Dovico::ApiClient::API_VERSION}"
61
+ )
62
+ .with(
63
+ body: '{"Fake":"Object"}',
64
+ )
65
+ .to_return(body: response_body)
66
+
67
+ Dovico::ApiClient.post('TimeEntries', body: {"Fake": "Object"}.to_json)
68
+ end
69
+ end
70
+
71
+ describe ".put" do
72
+ it 'perform a PUT request' do
73
+ stub_request(:put, "#{Dovico::ApiClient::API_URL}TimeEntries?version=#{Dovico::ApiClient::API_VERSION}")
74
+ .to_return(body: response_body)
75
+
76
+ response = Dovico::ApiClient.put('TimeEntries')
77
+ expect(response).to eq({"Stubbed": "Response"}.stringify_keys)
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,26 @@
1
+ require "helper"
2
+
3
+ module Dovico
4
+ describe Dovico::Assignment do
5
+ let(:assignment_api_hash) do
6
+ {
7
+ "ItemID": "123",
8
+ "AssignmentID": "T456",
9
+ "Name": "Dovico API Client",
10
+ "StartDate": "2017-01-01",
11
+ "FinishDate": "2017-12-31",
12
+ }.stringify_keys
13
+ end
14
+
15
+ describe ".parse" do
16
+ it "parses the API hash" do
17
+ assignment = Dovico::Assignment.parse(assignment_api_hash)
18
+
19
+ expect(assignment).to be_an(Dovico::Assignment)
20
+ expect(assignment.id).to eq('123')
21
+ expect(assignment.assignement_id).to eq('T456')
22
+ expect(assignment.name).to eq('Dovico API Client')
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,44 @@
1
+ require "helper"
2
+
3
+ module Dovico
4
+ describe Dovico::Employee do
5
+ let(:employee_api_hash) do
6
+ {
7
+ "ID": "123",
8
+ "FirstName": "James",
9
+ "LastName": "Bond",
10
+ }.stringify_keys
11
+ end
12
+
13
+ describe ".parse" do
14
+ it "parses the hash" do
15
+ employee = Dovico::Employee.parse(employee_api_hash)
16
+
17
+ expect(employee).to be_an(Dovico::Employee)
18
+ expect(employee.id).to eq('123')
19
+ expect(employee.first_name).to eq('James')
20
+ expect(employee.last_name).to eq('Bond')
21
+ end
22
+ end
23
+
24
+ describe ".myself" do
25
+ let(:employee_me_answer) do
26
+ {
27
+ "Employees": [ employee_api_hash ]
28
+ }.stringify_keys
29
+ end
30
+
31
+ before do
32
+ allow(ApiClient).to receive(:get).and_return(employee_me_answer)
33
+ end
34
+
35
+ it 'calls the API and return an Employee object' do
36
+ myself = Dovico::Employee.myself
37
+
38
+ expect(ApiClient).to have_received(:get).with("#{Dovico::Employee::URL_PATH}/Me")
39
+ expect(myself).to be_an(Dovico::Employee)
40
+ expect(myself.id).to eq('123')
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,56 @@
1
+ require "helper"
2
+
3
+ module Dovico
4
+ describe Dovico::Project do
5
+ let(:project_api_hash) do
6
+ {
7
+ "ItemID": "123",
8
+ "AssignmentID": "T456",
9
+ "Name": "Project Dovico API Client",
10
+ "StartDate": "2017-01-01",
11
+ "FinishDate": "2017-12-31",
12
+ }.stringify_keys
13
+ end
14
+ let(:projects_api_hash) do
15
+ {
16
+ "Assignments": [project_api_hash]
17
+ }.stringify_keys
18
+ end
19
+ let(:task_api_hash) do
20
+ {
21
+ "ItemID": "789",
22
+ "AssignmentID": "E456",
23
+ "Name": "Task write specs",
24
+ "StartDate": "2016-10-25",
25
+ "FinishDate": "2018-05-01",
26
+ }.stringify_keys
27
+ end
28
+ let(:tasks_api_hash) do
29
+ {
30
+ "Assignments": [task_api_hash]
31
+ }.stringify_keys
32
+ end
33
+
34
+ describe ".all" do
35
+ before do
36
+ allow(ApiClient).to receive(:get).with(Dovico::Project::URL_PATH).and_return(projects_api_hash)
37
+ allow(ApiClient).to receive(:get).with("#{Dovico::Project::URL_PATH}T456").and_return(tasks_api_hash)
38
+ end
39
+
40
+ it "lists all the assignements" do
41
+ projects = Dovico::Project.all
42
+
43
+ expect(projects.count).to eq(1)
44
+ project = projects.first
45
+ expect(project).to be_an(Dovico::Project)
46
+ expect(project.id).to eq('123')
47
+ expect(project.name).to eq('Project Dovico API Client')
48
+
49
+ expect(project.tasks.count).to eq(1)
50
+ task = project.tasks.first
51
+ expect(task.id).to eq('789')
52
+ expect(task.name).to eq('Task write specs')
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,26 @@
1
+ require "helper"
2
+
3
+ module Dovico
4
+ describe Dovico::Task do
5
+ let(:task_api_hash) do
6
+ {
7
+ "ItemID": "123",
8
+ "AssignmentID": "E456",
9
+ "Name": "Dovico API Client",
10
+ "StartDate": "2017-01-01",
11
+ "FinishDate": "2017-12-31",
12
+ }.stringify_keys
13
+ end
14
+
15
+ describe ".parse" do
16
+ it "parses the API hash" do
17
+ task = Dovico::Task.parse(task_api_hash)
18
+
19
+ expect(task).to be_an(Dovico::Task)
20
+ expect(task.id).to eq('123')
21
+ expect(task.assignement_id).to eq('E456')
22
+ expect(task.name).to eq('Dovico API Client')
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,86 @@
1
+ require "helper"
2
+
3
+ module Dovico
4
+ describe Dovico::TimeEntryGenerator do
5
+ subject do
6
+ Dovico::TimeEntryGenerator.new(
7
+ employee_id: employee_id,
8
+ assignments: assignments_config
9
+ )
10
+ end
11
+ let(:employee_id) { "999" }
12
+ let(:assignment_1) do
13
+ {
14
+ "project_id": "1234",
15
+ "task_id": "456",
16
+ "hours": 4,
17
+ }.stringify_keys
18
+ end
19
+ let(:assignment_2) do
20
+ {
21
+ "project_id": "6789",
22
+ "task_id": "999",
23
+ "hours": 3,
24
+ }.stringify_keys
25
+ end
26
+ let(:assignments_config) do
27
+ {
28
+ "default_day": [ assignment_1, assignment_2 ]
29
+ }.stringify_keys
30
+ end
31
+
32
+ describe "#generate" do
33
+ let(:start_date) { Date.parse('2017-01-02') }
34
+ let(:end_date) { Date.parse('2017-01-06') }
35
+
36
+ context 'with minimal configuration' do
37
+ it 'creates TimeEntries object for the date range' do
38
+ time_entries = subject.generate(start_date, end_date)
39
+
40
+ # 5 days * 2 time entries
41
+ expect(time_entries.count).to eq(10)
42
+ first_time_entry = time_entries.first
43
+ last_time_entry = time_entries.last
44
+
45
+ expect(first_time_entry.id).to be_nil
46
+ expect(first_time_entry.employee_id).to eq(employee_id)
47
+ expect(first_time_entry.project_id).to eq('1234')
48
+ expect(first_time_entry.task_id).to eq('456')
49
+ expect(first_time_entry.date).to eq('2017-01-02')
50
+ expect(first_time_entry.start_time).to eq('0900')
51
+ expect(first_time_entry.stop_time).to eq('1300')
52
+ expect(first_time_entry.total_hours).to eq(4)
53
+
54
+ expect(first_time_entry.employee_id).to eq(employee_id)
55
+ expect(last_time_entry.project_id).to eq('6789')
56
+ expect(last_time_entry.task_id).to eq('999')
57
+ expect(last_time_entry.date).to eq('2017-01-06')
58
+ expect(last_time_entry.start_time).to eq('1300')
59
+ expect(last_time_entry.stop_time).to eq('1600')
60
+ expect(last_time_entry.total_hours).to eq(3)
61
+ end
62
+ end
63
+
64
+ context 'with specific day assignments' do
65
+ let(:assignments_config) do
66
+ {
67
+ 'default_day': [ assignment_1, assignment_2 ],
68
+ '2016-02-29': [],
69
+ '2016-03-01': [ assignment_2 ],
70
+ }.stringify_keys
71
+ end
72
+ let(:start_date) { Date.parse('2016-02-29') }
73
+ let(:end_date) { Date.parse('2016-03-01') }
74
+
75
+ it 'uses specific day assignments' do
76
+ time_entries = subject.generate(start_date, end_date)
77
+
78
+ expect(time_entries.count).to eq(1)
79
+ time_entry = time_entries.first
80
+ expect(time_entry.date).to eq('2016-03-01')
81
+ expect(time_entry.total_hours).to eq(3)
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,168 @@
1
+ require "helper"
2
+
3
+ module Dovico
4
+ describe Dovico::TimeEntry do
5
+ subject do
6
+ Dovico::TimeEntry.parse(time_entry_api_hash)
7
+ end
8
+ let(:project_hash) do
9
+ {
10
+ "ID": "111"
11
+ }.stringify_keys
12
+ end
13
+ let(:task_hash) do
14
+ {
15
+ "ID": "222"
16
+ }.stringify_keys
17
+ end
18
+ let(:employee_hash) do
19
+ {
20
+ "ID": "333"
21
+ }.stringify_keys
22
+ end
23
+ let(:time_entry_api_hash) do
24
+ {
25
+ "ID": "456",
26
+ "StartTime": "0800",
27
+ "StopTime": "1100",
28
+ "Project": project_hash,
29
+ "Task": task_hash,
30
+ "Employee": employee_hash,
31
+ "Date": "2017-01-05",
32
+ "TotalHours": "3",
33
+ "Description": "Unit test",
34
+ }.stringify_keys
35
+ end
36
+
37
+ describe ".parse" do
38
+ it "parses the API hash" do
39
+ time_entry = Dovico::TimeEntry.parse(time_entry_api_hash)
40
+
41
+ expect(time_entry).to be_an(Dovico::TimeEntry)
42
+ expect(time_entry.start_time).to eq('0800')
43
+ expect(time_entry.project_id).to eq('111')
44
+ expect(time_entry.employee_id).to eq('333')
45
+ expect(time_entry.total_hours).to eq('3')
46
+ end
47
+
48
+ context 'with a GUID ID' do
49
+ it 'removes the first character of the GUID' do
50
+ time_entry = Dovico::TimeEntry.parse(
51
+ time_entry_api_hash.merge(
52
+ {"ID": "T0bb4860f-2669-49ab-ae5e-dd8908366c8b"}.stringify_keys
53
+ )
54
+ )
55
+
56
+ expect(time_entry.id).to eq('0bb4860f-2669-49ab-ae5e-dd8908366c8b')
57
+ end
58
+ end
59
+ end
60
+
61
+ describe ".get" do
62
+ let(:time_entry_list_api) do
63
+ {
64
+ "TimeEntries": [ time_entry_api_hash ]
65
+ }.stringify_keys
66
+ end
67
+
68
+ before do
69
+ allow(ApiClient).to receive(:get).and_return(time_entry_list_api)
70
+ end
71
+
72
+ it 'calls the API and return an TimeEntry object' do
73
+ time_entry = Dovico::TimeEntry.get('999')
74
+
75
+ expect(ApiClient).to have_received(:get).with("#{Dovico::TimeEntry::URL_PATH}/999")
76
+ expect(time_entry).to be_an(Dovico::TimeEntry)
77
+ expect(time_entry.id).to eq('456')
78
+ end
79
+ end
80
+
81
+ describe ".batch_create!" do
82
+ let(:assignments) do
83
+ [ subject ]
84
+ end
85
+
86
+ before do
87
+ allow(ApiClient).to receive(:post)
88
+ end
89
+
90
+ it 'calls the API and post TimeEntries objects' do
91
+ Dovico::TimeEntry.batch_create!(assignments)
92
+
93
+ expect(ApiClient).to have_received(:post).with(
94
+ "#{Dovico::TimeEntry::URL_PATH}",
95
+ body: [subject.to_api].to_json
96
+ )
97
+ end
98
+ end
99
+
100
+ describe ".submit!" do
101
+ let(:start_date) { Date.parse("2017-01-02") }
102
+ let(:end_date) { Date.parse("2017-01-12") }
103
+ let(:employee_id) { "333" }
104
+
105
+ before do
106
+ allow(ApiClient).to receive(:post)
107
+ end
108
+
109
+ it 'calls the API and submit a time range' do
110
+ Dovico::TimeEntry.submit!(employee_id, start_date, end_date)
111
+
112
+ expect(ApiClient).to have_received(:post).with(
113
+ "#{Dovico::TimeEntry::URL_PATH}/Employee/#{employee_id}/Submit",
114
+ params: {
115
+ daterange: "2017-01-02 2017-01-12"
116
+ },
117
+ body: {}.to_json
118
+ )
119
+ end
120
+ end
121
+
122
+ describe ".create!" do
123
+ before do
124
+ allow(ApiClient).to receive(:post)
125
+ end
126
+
127
+ it 'calls the API and post TimeEntries objects' do
128
+ subject.create!
129
+
130
+ expect(ApiClient).to have_received(:post).with(
131
+ "#{Dovico::TimeEntry::URL_PATH}",
132
+ body: [subject.to_api].to_json
133
+ )
134
+ end
135
+ end
136
+
137
+ describe ".update!" do
138
+ before do
139
+ allow(ApiClient).to receive(:put)
140
+ end
141
+
142
+ it 'calls the API and post TimeEntries objects' do
143
+ subject.update!
144
+
145
+ expect(ApiClient).to have_received(:put).with(
146
+ "#{Dovico::TimeEntry::URL_PATH}",
147
+ body: [subject.to_api].to_json
148
+ )
149
+ end
150
+ end
151
+
152
+ describe ".to_api" do
153
+ it 'serializes the object' do
154
+ expect(subject.to_api).to eq(
155
+ "ID" => "456",
156
+ "EmployeeID" => "333",
157
+ "ProjectID" => "111",
158
+ "TaskID" => "222",
159
+ "Date" => "2017-01-05",
160
+ "StartTime" => "0800",
161
+ "StopTime" => "1100",
162
+ "TotalHours" => "3",
163
+ "Description" => "Unit test",
164
+ )
165
+ end
166
+ end
167
+ end
168
+ end