dovico 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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