JobsUnifiedTopCard.purs 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. module Test.JobsUnifiedTopCard where
  2. import LinkedIn.JobsUnifiedTopCard
  3. import Prelude
  4. import Data.Date (Month(..))
  5. import Data.Either (Either(..))
  6. import Data.List (List(..), (:))
  7. import Data.List.NonEmpty (NonEmptyList(..))
  8. import Data.List.NonEmpty as NEL
  9. import Data.Maybe (Maybe(..), isJust)
  10. import Data.NonEmpty (NonEmpty(..))
  11. import Data.Traversable (traverse)
  12. import Effect (Effect)
  13. import LinkedIn (DetachedNode(..), LinkedInUIElement(..), getJobsUnifiedTopCard, toDetached)
  14. import LinkedIn.Profile.WorkExperience (WorkExperience(..))
  15. import LinkedIn.Profile.WorkExperience as PWE
  16. import LinkedIn.QueryRunner (QueryError, runQuery)
  17. import LinkedIn.Types (ParseError(..))
  18. import LinkedIn.UIElements.Types (Duration(..), TimeSpan(..))
  19. import Node.JsDom (jsDomFromFile)
  20. import Partial.Unsafe (unsafePartial)
  21. import Test.Assert (assert, assertEqual)
  22. import Test.Utils (toMonthYear')
  23. testJobsUnifiedTopCard :: Effect Unit
  24. testJobsUnifiedTopCard = do
  25. dom <- jsDomFromFile "test/examples/job_offer.html"
  26. topCard <- getJobsUnifiedTopCard dom
  27. assert $ isJust topCard
  28. headCard <- unsafePartial $ parseHeadCard topCard
  29. assertEqual {
  30. actual: headCard,
  31. expected: Right (JobsUnifiedTopCardElement {
  32. actions: (Just (NonEmptyList
  33. (NonEmpty (TopCardActionApplyButton (DetachedElement {
  34. classes: ("jobs-apply-button" : "artdeco-button" : "artdeco-button--3" : "artdeco-button--primary" : "ember-view" : Nil),
  35. content: "Candidature simplifiée",
  36. id: (Just "ember115"),
  37. tag: "BUTTON"
  38. })) ((TopCardActionApplyButton (DetachedElement {
  39. classes: ("jobs-save-button" : "artdeco-button" : "artdeco-button--3" : "artdeco-button--secondary" : Nil),
  40. content: "Enregistrer Enregistrer Data Engineer H/F - Secteur Energie chez LINCOLN",
  41. id: Nothing,
  42. tag: "BUTTON"
  43. })) : Nil)))),
  44. header: (DetachedElement {
  45. classes: ("t-24" : "t-bold" : "job-details-jobs-unified-top-card__job-title" : Nil),
  46. content: "Data Engineer H/F - Secteur Energie",
  47. id: Nothing,
  48. tag: "H1"
  49. }),
  50. insights: (Just (NonEmptyList
  51. (NonEmpty (TopCardInsight {
  52. content: (TopCardInsightContentSecondary {
  53. primary: (DetachedElement {
  54. classes: ("" : Nil),
  55. content: "Sur site",
  56. id: Nothing,
  57. tag: "SPAN"
  58. }),
  59. secondary: (NonEmptyList (NonEmpty (TopCardSecondaryInsightNested
  60. (DetachedElement {
  61. classes: ("" : Nil),
  62. content: "Temps plein",
  63. id: Nothing,
  64. tag: "SPAN"
  65. })) ((TopCardSecondaryInsightPlain
  66. (DetachedElement {
  67. classes: ("job-details-jobs-unified-top-card__job-insight-view-model-secondary" : Nil),
  68. content: "Confirmé",
  69. id: (Just "undefined"),
  70. tag: "SPAN"
  71. })) : Nil))) }),
  72. icon: (DetachedElement {
  73. classes: ("" : Nil),
  74. content: "",
  75. id: Nothing,
  76. tag: "LI-ICON"
  77. })
  78. }) ((TopCardInsight {
  79. content: (TopCardInsightContentSingle (DetachedElement {
  80. classes: ("" : Nil),
  81. content: "201-500 employés · Technologies et services de l’information",
  82. id: (Just "undefined"),
  83. tag: "SPAN" })),
  84. icon: (DetachedElement {
  85. classes: ("" : Nil),
  86. content: "",
  87. id: Nothing,
  88. tag: "LI-ICON" })
  89. }) : (TopCardInsight {
  90. content: (TopCardInsightContentSingle (DetachedElement {
  91. classes: ("" : Nil),
  92. content: "2 anciens élèves travaillent ici",
  93. id: (Just "undefined"),
  94. tag: "SPAN" })),
  95. icon: (DetachedElement {
  96. classes: ("" : Nil),
  97. content: "",
  98. id: Nothing,
  99. tag: "LI-ICON" })
  100. }) : (TopCardInsight {
  101. content: (TopCardInsightContentSingle (DetachedElement {
  102. classes: ("" : Nil),
  103. content: "Découvrez comment vous vous positionnez par rapport à 87 candidats. Essai Premium pour 0 EUR",
  104. id: (Just "undefined"),
  105. tag: "SPAN" })),
  106. icon: (DetachedElement {
  107. classes: ("" : Nil),
  108. content: "",
  109. id: Nothing,
  110. tag: "svg"
  111. })
  112. }) : (TopCardInsight {
  113. content: (TopCardInsightContentButton (DetachedElement {
  114. classes: ("job-details-jobs-unified-top-card__job-insight-text-button" : Nil),
  115. content: "9 compétences sur 11 correspondent à votre profil, vous pourriez bien convenir pour ce poste",
  116. id: (Just "undefined"),
  117. tag: "BUTTON" })),
  118. icon: (DetachedElement {
  119. classes: ("" : Nil),
  120. content: "",
  121. id: Nothing,
  122. tag: "svg"
  123. })
  124. }) : Nil)))),
  125. primaryDescription: (TopCardPrimaryDescription {
  126. link: (DetachedElement {
  127. classes: ("app-aware-link" : Nil),
  128. content: "LINCOLN",
  129. id: Nothing,
  130. tag: "A" }),
  131. text: (DetachedText "· Boulogne-Billancourt, Île-de-France, France"),
  132. tvmText: (Just (NonEmptyList
  133. (NonEmpty (DetachedElement {
  134. classes: ("tvm__text" : "tvm__text--neutral" : Nil),
  135. content: "il y a 2 semaines",
  136. id: Nothing,
  137. tag: "SPAN"
  138. }) ((DetachedElement {
  139. classes: ("tvm__text" : "tvm__text--neutral" : Nil),
  140. content: "·",
  141. id: Nothing,
  142. tag: "SPAN"
  143. }) : (DetachedElement {
  144. classes: ("tvm__text" : "tvm__text--neutral" : Nil),
  145. content: "87 candidats",
  146. id: Nothing,
  147. tag: "SPAN"
  148. }) : Nil
  149. ))
  150. ))
  151. })
  152. })
  153. }
  154. parseHeadCard ∷ Partial ⇒ Maybe (NonEmptyList LinkedInUIElement) → Effect (Either QueryError (JobsUnifiedTopCardElement DetachedNode))
  155. parseHeadCard (Just l) = do
  156. queried <- (\(LinkedInUIElement _ n) -> runQuery $ queryJobsUnifiedTopCardElement n) $ NEL.head l
  157. case queried of
  158. Left l -> pure $ Left l
  159. Right q -> do
  160. parsed <- traverse toDetached q
  161. pure $ Right parsed