Skip to content

Commit 278df29

Browse files
authored
[TSD-50] Fix Zendesk URL parameters. (#20)
* [TSD-50] Fix Zendesk URL parameters. * [TSD-50] Fix review comment.
1 parent 0d57a90 commit 278df29

File tree

6 files changed

+112
-36
lines changed

6 files changed

+112
-36
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ wallet-db/
2020
wallet-new-db/
2121
db-*/
2222
wdb-*/
23+
*.db
2324

2425
# Keys
2526
*.key

src/DataSource/DB.hs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,6 @@ getTicketComments ticketId = do
156156
getCommentAttachments commentId = withProdDatabase $ \conn ->
157157
queryNamed conn "SELECT * FROM comment_attachments WHERE comment_id = :id" [":id" := commentId]
158158

159-
160159
getAttachmentContent :: Attachment -> IO (Maybe AttachmentContent)
161160
getAttachmentContent Attachment{..} = withProdDatabase $ \conn ->
162161
safeHead <$> queryNamed conn "SELECT * FROM attachment_content WHERE attachment_id = :id" [":id" := aId]

src/DataSource/Http.hs

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@ import Network.HTTP.Simple (Request, addRequestHeader, getResponseBody
2020

2121
import DataSource.Types (Attachment (..), AttachmentContent (..), Comment (..),
2222
CommentBody (..), CommentId (..), Config (..), IOLayer (..),
23-
Ticket (..), TicketId(..), TicketInfo (..), TicketList (..),
24-
TicketTag (..), User, UserId(..), ZendeskLayer (..),
25-
ZendeskResponse (..), parseComments, parseTickets, parseTicket,
26-
renderTicketStatus)
23+
Ticket (..), TicketId (..), TicketInfo (..), TicketList (..),
24+
TicketTag (..), User, UserId (..), ZendeskAPIUrl (..),
25+
ZendeskLayer (..), ZendeskResponse (..), parseComments,
26+
parseTicket, parseTickets, renderTicketStatus, showURL)
2727

2828

2929
-- | The default configuration.
@@ -80,7 +80,8 @@ getTicketInfo
8080
getTicketInfo ticketId = do
8181
cfg <- ask
8282

83-
let req = apiRequest cfg ("tickets/" <> show (getTicketId ticketId) <> ".json")
83+
let url = showURL $ TicketsURL ticketId
84+
let req = apiRequest cfg url
8485
liftIO $ Just <$> apiCall parseTicket req
8586

8687

@@ -92,8 +93,8 @@ listRequestedTickets
9293
listRequestedTickets userId = do
9394
cfg <- ask
9495

95-
let url = "/users/" <> show (getUserId userId) <> "/tickets/requested.json"
96-
let req = apiRequest cfg url
96+
let url = showURL $ UserRequestedTicketsURL userId
97+
let req = apiRequest cfg url
9798

9899
iterateTicketPages req
99100

@@ -105,8 +106,8 @@ listAssignedTickets
105106
listAssignedTickets userId = do
106107
cfg <- ask
107108

108-
let url = "/users/" <> show (getUserId userId) <> "/tickets/assigned.json"
109-
let req = apiRequest cfg url
109+
let url = showURL $ UserAssignedTicketsURL userId
110+
let req = apiRequest cfg url
110111

111112
iterateTicketPages req
112113

@@ -139,7 +140,8 @@ postTicketComment
139140
postTicketComment ZendeskResponse{..} = do
140141
cfg <- ask
141142

142-
let req1 = apiRequest cfg ("tickets/" <> show zrTicketId <> ".json")
143+
let url = showURL $ TicketsURL zrTicketId
144+
let req1 = apiRequest cfg url
143145
let req2 = addJsonBody
144146
(Ticket
145147
(Comment (CommentId 0) (CommentBody $ "**Log classifier**\n\n" <> zrComment) [] zrIsPublic (cfgAgentId cfg))
@@ -155,7 +157,10 @@ _getUser
155157
=> m User
156158
_getUser = do
157159
cfg <- ask
158-
let req = apiRequest cfg "users/me.json"
160+
161+
let url = showURL UserInfoURL
162+
let req = apiRequest cfg url
163+
159164
liftIO $ apiCall parseJSON req
160165

161166
-- | Given attachmentUrl, return attachment in bytestring
@@ -175,7 +180,10 @@ getTicketComments
175180
-> m [Comment]
176181
getTicketComments tId = do
177182
cfg <- ask
178-
let req = apiRequest cfg ("tickets/" <> show (getTicketId tId) <> "/comments.json")
183+
184+
let url = showURL $ TicketCommentsURL tId
185+
let req = apiRequest cfg url
186+
179187
liftIO $ apiCall parseComments req
180188

181189
------------------------------------------------------------

src/DataSource/Types.hs

Lines changed: 45 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ module DataSource.Types
3939
, assignToPath
4040
, asksZendeskLayer
4141
, asksIOLayer
42+
, ZendeskAPIUrl (..)
43+
, showURL
4244
, App
4345
, runApp
4446
) where
@@ -144,6 +146,43 @@ data IOLayer m = IOLayer
144146
, iolReadFile :: FilePath -> m String
145147
}
146148

149+
------------------------------------------------------------
150+
-- Class and instances to display in URL
151+
------------------------------------------------------------
152+
153+
-- Let's keep this simple for now. Not much use for it now since
154+
-- we can't simply extend it using @ZendeskAPIUrl@, but let's worry
155+
-- about that later.
156+
class ToURL a where
157+
toURL :: a -> Text
158+
159+
instance ToURL UserId where
160+
toURL (UserId uId) = show uId
161+
162+
instance ToURL TicketId where
163+
toURL (TicketId ticketId) = show ticketId
164+
165+
data ZendeskAPIUrl
166+
= UserRequestedTicketsURL UserId
167+
| UserAssignedTicketsURL UserId
168+
| TicketsURL TicketId
169+
| TicketAgentURL TicketId
170+
| UserInfoURL
171+
| TicketCommentsURL TicketId
172+
deriving (Eq, Generic)
173+
174+
showURL :: ZendeskAPIUrl -> Text
175+
showURL (UserRequestedTicketsURL userId) = "/users/" <> toURL userId <> "/tickets/requested.json"
176+
showURL (UserAssignedTicketsURL userId) = "/users/" <> toURL userId <> "/tickets/assigned.json"
177+
showURL (TicketsURL ticketId) = "/tickets/" <> toURL ticketId <> ".json"
178+
showURL (TicketAgentURL ticketId) = "https://iohk.zendesk.com/agent/tickets/" <> toURL ticketId
179+
showURL (UserInfoURL) = "/users/me.json"
180+
showURL (TicketCommentsURL ticketId) = "/tickets/" <> toURL ticketId <> "/comments.json"
181+
182+
------------------------------------------------------------
183+
-- Types
184+
------------------------------------------------------------
185+
147186
newtype AttachmentId = AttachmentId
148187
{ getAttachmentId :: Int
149188
} deriving (Eq, Show, Ord, Generic, FromJSON, ToJSON)
@@ -279,12 +318,12 @@ newtype TicketStatus = TicketStatus
279318

280319

281320
data TicketInfo = TicketInfo
282-
{ tiId :: !TicketId -- ^ Id of an ticket
283-
, tiRequesterId :: !UserId -- ^ Id of the requester
284-
, tiAssigneeId :: Maybe UserId -- ^ Id of the asignee
285-
, tiUrl :: !TicketURL -- ^ The ticket URL
286-
, tiTags :: !TicketTags -- ^ Tags associated with ticket
287-
, tiStatus :: !TicketStatus -- ^ The status of the ticket
321+
{ tiId :: !TicketId -- ^ Id of an ticket
322+
, tiRequesterId :: !UserId -- ^ Id of the requester
323+
, tiAssigneeId :: !(Maybe UserId) -- ^ Id of the asignee
324+
, tiUrl :: !TicketURL -- ^ The ticket URL
325+
, tiTags :: !TicketTags -- ^ Tags associated with ticket
326+
, tiStatus :: !TicketStatus -- ^ The status of the ticket
288327
} deriving (Eq, Show, Generic)
289328

290329

src/LogAnalysis/Classifier.hs

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ import qualified Data.Map.Strict as Map
1818
import Data.Text (isInfixOf)
1919
import Data.Text.Encoding.Error (ignore)
2020

21+
import DataSource.Types (TicketInfo (..), ZendeskAPIUrl (..), showURL)
2122
import LogAnalysis.Types (Analysis, Knowledge (..), renderErrorCode)
22-
import DataSource.Types (TicketInfo (..))
2323

2424
-- | Number of error texts it should show
2525
numberOfErrorText :: Int
@@ -57,10 +57,6 @@ filterAnalysis as = do
5757
extractErrorCodes :: Analysis -> [ Text ]
5858
extractErrorCodes as = map (\(Knowledge{..}, _) -> renderErrorCode kErrorCode) $ Map.toList as
5959

60-
61-
printTicketUrl :: TicketInfo -> Text
62-
printTicketUrl TicketInfo{..} = "https://iohk.zendesk.com/agent/tickets/" <> show tiId
63-
6460
prettyHeader :: Text
6561
prettyHeader =
6662
"Dear user," <>
@@ -72,7 +68,7 @@ prettyHeader =
7268
prettyFooter :: TicketInfo -> Text
7369
prettyFooter ticketInfo =
7470
"\n\n" <>
75-
"Please be patient since we have a large number of such requests to respond to. We will respond as soon as we can, but in the meantime, if you want to check the status of your ticket you can do so here - " <> printTicketUrl ticketInfo <>
71+
"Please be patient since we have a large number of such requests to respond to. We will respond as soon as we can, but in the meantime, if you want to check the status of your ticket you can do so here - " <> (showURL $ TicketAgentURL $ tiId ticketInfo) <>
7672
"\n\n" <>
7773
"Please let us know if your issue is resolved. If you are still having trouble please reply back to this email and attach a new log file so that we can work with you to fix your problem." <>
7874
"\n\n" <>
@@ -108,13 +104,13 @@ prettyFormatLogReadError ticketInfo =
108104
prettyFormatNoLogs :: Text
109105
prettyFormatNoLogs =
110106
"Dear user," <> "\n\n" <>
111-
"Thank you for contacting the IOHK Technical Support Desk. We apologize for the delay in responding to you." <> "\n\n" <>
107+
"Thank you for contacting the IOHK Technical Support Desk. We apologize for the delay in responding to you." <> "\n\n" <>
112108
"Most of the tickets we get are related to technical issues. If you have a Technical problem with Daedalus wallet please read on. If your request is NOT related to getting technical support you can IGNORE this email." <> "\n\n" <>
113109
"We have recently (May 29th) had a major update to the Daedalus software. You can see more details here https://daedaluswallet.io/release-notes/. If you are experiencing any technical difficulties please make sure you have upgraded to the latest version before submitting a request for support or submitting new logs (more on logs below)." <> "\n\n" <>
114110
"We scan our tickets to check for known issues before responding in person. If you have a technical issue but did not submit a log file we suggest that you reply to this message and attach your log file. Log files are required for helping with the majority of technical issues." <> "\n\n" <>
115-
111+
116112
"Please provide more information so that we can diagnose your issue:" <> "\n\n" <>
117-
113+
118114
"1. What is the Manufacturer and the Model number of your computer?" <> "\n" <>
119115
"2. What is the Type and Version of the Operation System (OS) are you using?" <> "\n" <>
120116
"3. Describe the issue you are experiencing in detail and attach screenshots if needed. Please tell us what you were doing when the error occurred." <> "\n" <>
@@ -123,15 +119,15 @@ prettyFormatNoLogs =
123119
"Please compress and attach your pub folder, it contains technical logs. There is NO sensitive data in your logs:" <> "\n\n" <>
124120

125121
"Windows" <> "\n\n" <>
126-
122+
127123
"1. Go to" <> "\n" <>
128124
"C:\\Users'username\\AppData\\Roaming\\Daedalus\\Logs" <> "\n" <>
129125
"You can access them by typing %appdata% into Windows Explorer search bar." <> "\n" <>
130126
"2. Compress the pub folder into a Zip file." <> "\n" <>
131127
"3. Attach the compressed pub folder to your reply." <> "\n\n" <>
132-
128+
133129
"Mac" <> "\n\n" <>
134-
130+
135131
"1. Open Finder" <> "\n" <>
136132
"2. Go to the Menu Bar and select the 'Go' menu" <> "\n" <>
137133
"3. Select 'Go to Folder...'" <> "\n" <>
@@ -142,4 +138,4 @@ prettyFormatNoLogs =
142138

143139
"Thanks," <> "\n" <>
144140
"The IOHK Technical Support Desk Team"
145-
141+

test/Spec.hs

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,13 @@ import Universum
44

55
import Test.Hspec (Spec, describe, hspec, it, pending)
66
import Test.Hspec.QuickCheck (modifyMaxSuccess)
7-
import Test.QuickCheck (Gen, arbitrary, forAll, listOf1)
7+
import Test.QuickCheck (Gen, arbitrary, forAll, listOf1, property)
88
import Test.QuickCheck.Monadic (assert, monadicIO, pre, run)
99

10-
import DataSource (App, Comment (..), Config (..), IOLayer (..), TicketInfo (..),
11-
ZendeskLayer (..), ZendeskResponse (..), basicIOLayer, defaultConfig,
12-
emptyZendeskLayer, runApp)
10+
import DataSource (App, Comment (..), Config (..), IOLayer (..), TicketId (..),
11+
TicketInfo (..), UserId (..), ZendeskAPIUrl (..), ZendeskLayer (..),
12+
ZendeskResponse (..), basicIOLayer, defaultConfig, emptyZendeskLayer,
13+
runApp, showURL)
1314
import Lib (listAndSortTickets, processTicket)
1415

1516
-- TODO(ks): What we are really missing is a realistic @Gen ZendeskLayer m@.
@@ -21,6 +22,7 @@ main = hspec spec
2122
spec :: Spec
2223
spec =
2324
describe "Zendesk" $ do
25+
validShowURLSpec
2426
listAndSortTicketsSpec
2527
processTicketSpec
2628

@@ -218,3 +220,34 @@ processTicketsSpec =
218220
describe "processTickets" $ do
219221
it "doesn't process tickets" $ do
220222
pending
223+
224+
-- Simple tests to cover it works.
225+
validShowURLSpec :: Spec
226+
validShowURLSpec =
227+
describe "showURL" $ modifyMaxSuccess (const 10000) $ do
228+
it "returns valid UserRequestedTicketsURL" $ do
229+
property $ \userId ->
230+
let typedURL = showURL $ UserRequestedTicketsURL userId
231+
untypedURL = "/users/" <> show (getUserId userId) <> "/tickets/requested.json"
232+
in typedURL == untypedURL
233+
it "returns valid UserAssignedTicketsURL" $ do
234+
property $ \userId ->
235+
let typedURL = showURL $ UserAssignedTicketsURL userId
236+
untypedURL = "/users/" <> show (getUserId userId) <> "/tickets/assigned.json"
237+
in typedURL == untypedURL
238+
it "returns valid TicketsURL" $ do
239+
property $ \ticketId ->
240+
let typedURL = showURL $ TicketsURL ticketId
241+
untypedURL = "/tickets/" <> show (getTicketId ticketId) <> ".json"
242+
in typedURL == untypedURL
243+
it "returns valid TicketAgentURL" $ do
244+
property $ \ticketId ->
245+
let typedURL = showURL $ TicketAgentURL ticketId
246+
untypedURL = "https://iohk.zendesk.com/agent/tickets/" <> show (getTicketId ticketId)
247+
in typedURL == untypedURL
248+
it "returns valid TicketCommentsURL" $ do
249+
property $ \ticketId ->
250+
let typedURL = showURL $ TicketCommentsURL ticketId
251+
untypedURL = "/tickets/" <> show (getTicketId ticketId) <> "/comments.json"
252+
in typedURL == untypedURL
253+

0 commit comments

Comments
 (0)