Skip to content

Commit

Permalink
feat: add utm_source to job offer links (#171)
Browse files Browse the repository at this point in the history
* feat: add utm_source to job offer links

* ci: update go GH action
  • Loading branch information
smoya committed Apr 9, 2024
1 parent 6b06988 commit 0225626
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 45 deletions.
38 changes: 14 additions & 24 deletions .github/workflows/go.yml
Original file line number Diff line number Diff line change
@@ -1,40 +1,30 @@
name: Go

on:
push:
branches: [ master ]
branches: [ main ]
pull_request:

jobs:

build:
name: Build
runs-on: ubuntu-latest
steps:

- name: Set up Go 1.x
uses: actions/setup-go@v4

- name: Check out code into the Go module directory
uses: actions/checkout@v3

- name: Build
run: make build

- uses: actions/checkout@v4
- uses: actions/setup-go@v5
- name: Test
run: make build test

- name: Build
run: make build
check-lint:
name: Lint checks
runs-on: ubuntu-latest
steps:

- name: Set up Go 1.x
uses: actions/setup-go@v4

- name: Check out code into the Go module directory
uses: actions/checkout@v3

- name: golangci-lint
uses: golangci/golangci-lint-action@v3
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: '1.21'
cache: false
- name: golangci-lint
uses: golangci/golangci-lint-action@v4
with:
version: v1.57.2

24 changes: 14 additions & 10 deletions bot/interact.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,11 +197,14 @@ func interactAPIHandler(botContext Context) http.HandlerFunc {
Timestamp: time.Now(),
})
case "job_submission":
messageJobLink := message.Submission["job_link"]
messageMaxSalary := message.Submission["max_salary"]
messageMinSalary := message.Submission["min_salary"]

maxSalary, minSalary, validationErrors := validateSubmission(messageJobLink, messageMaxSalary, messageMinSalary)
link, maxSalary, minSalary, validationErrors := validateSubmission(message.Submission["job_link"], message.Submission["max_salary"], message.Submission["min_salary"])
if link != nil && link.Query().Get("utm_source") == "" {
// Add utm_source to the job link only if doesn't have one already
query := link.Query()
query.Add("utm_source", "bcneng")
link.RawQuery = query.Encode()
message.Submission["job_link"] = link.String()
}

if len(validationErrors) > 0 {
var errs []slack.DialogInputValidationError
Expand Down Expand Up @@ -295,7 +298,7 @@ func deleteThreadMessages(botContext Context, threadMessages []slack.Message, ch
return nil
},
retry.Attempts(0), // unlimited unless the error is not rate limit reached
retry.OnRetry(func(n uint, err error) {
retry.OnRetry(func(_ uint, err error) {
log.Printf("Retrying thread message %s deletion because of err: %s", threadMessage.Timestamp, err)
}),
)
Expand All @@ -313,13 +316,14 @@ func deleteThreadMessages(botContext Context, threadMessages []slack.Message, ch
//
// Arguments are the strings as read from the submissions (no previous transform/parsing/filter)
// Returns:
// - the parsed URL. Nil if invalid
// - the parsed max salary as int
// - the parsed min salary as int, or -1 if the field was empty (it's an optional field)
// - a map of field name to error message
func validateSubmission(messageJobLink, messageMaxSalary, messageMinSalary string) (int, int, map[string]string) {

func validateSubmission(messageJobLink, messageMaxSalary, messageMinSalary string) (*url.URL, int, int, map[string]string) {
validationErrors := make(map[string]string)
if _, err := url.ParseRequestURI(messageJobLink); err != nil {
link, linkErr := url.ParseRequestURI(messageJobLink)
if linkErr != nil {
validationErrors["job_link"] = "The link to the job spec is invalid."
}

Expand Down Expand Up @@ -349,7 +353,7 @@ func validateSubmission(messageJobLink, messageMaxSalary, messageMinSalary strin
validationErrors["max_salary"] = "The min-max salary range is too wide. Salary is a relevant field; keep it meaningful to increase offer impact."
}
}
return maxSalary, minSalary, validationErrors
return link, maxSalary, minSalary, validationErrors
}

func generateSubmitJobFormDialog() slack.Dialog {
Expand Down
25 changes: 14 additions & 11 deletions bot/interact_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,60 +18,63 @@ func requireHasError(t *testing.T, errorMessage string) {
func TestJobSubmission(t *testing.T) {

t.Run("fields for the salary are properly parsed", func(t *testing.T) {
max, min, _ := validateSubmission("http://foo.com", "12", "10")
link, max, min, _ := validateSubmission("http://foo.com", "12", "10")
require.NotNil(t, link)
require.Equal(t, 12, max)
require.Equal(t, 10, min)
})

t.Run("the job link must be a valid URI", func(t *testing.T) {
_, _, validaterrors := validateSubmission("http://foo.com", "12", "10")
link, _, _, validaterrors := validateSubmission("http://foo.com", "12", "10")
require.Empty(t, validaterrors["job_link"])
require.NotNil(t, link)
})

t.Run("min salary is optional (and function returns -1 when left blank)", func(t *testing.T) {
_, minSalary, _ := validateSubmission("hamburger", "12", "")
_, _, minSalary, _ := validateSubmission("http://foo.com", "12", "")
require.Equal(t, -1, minSalary)
})

// FIXME: The following tests may be rewritten as a table-driven test
// https://github.com/bcneng/candebot/pull/72#pullrequestreview-773870224
t.Run("must reject non-URI links", func(t *testing.T) {
_, _, validaterrors := validateSubmission("hamburger", "12", "10")
link, _, _, validaterrors := validateSubmission("hamburger", "12", "10")
requireHasError(t, validaterrors["job_link"])
require.Nil(t, link)
})

t.Run("must include a max salary", func(t *testing.T) {
_, _, validaterrors := validateSubmission("hamburger", "", "10")
_, _, _, validaterrors := validateSubmission("http://foo.com", "", "10")
requireHasError(t, validaterrors["max_salary"])
})

t.Run("max salary must be a positive number", func(t *testing.T) {
_, _, validaterrors := validateSubmission("hamburger", "-1", "10")
_, _, _, validaterrors := validateSubmission("http://foo.com", "-1", "10")
requireHasError(t, validaterrors["max_salary"])
})

t.Run("max salary must be a number", func(t *testing.T) {
_, _, validaterrors := validateSubmission("hamburger", "-asdf", "10")
_, _, _, validaterrors := validateSubmission("http://foo.com", "-asdf", "10")
requireHasError(t, validaterrors["max_salary"])
})

t.Run("min salary must be a number", func(t *testing.T) {
_, _, validaterrors := validateSubmission("hamburger", "12", "asdf")
_, _, _, validaterrors := validateSubmission("http://foo.com", "12", "asdf")
requireHasError(t, validaterrors["min_salary"])
})

t.Run("min salary must be a positive number", func(t *testing.T) {
_, _, validaterrors := validateSubmission("hamburger", "12", "-5")
_, _, _, validaterrors := validateSubmission("http://foo.com", "12", "-5")
requireHasError(t, validaterrors["min_salary"])
})

t.Run("max salary must be greater than the min salary", func(t *testing.T) {
_, _, validaterrors := validateSubmission("hamburger", "8", "10")
_, _, _, validaterrors := validateSubmission("http://foo.com", "8", "10")
requireHasError(t, validaterrors["min_salary"])
})

t.Run("max salary must not be greater than 2.5x the min salary", func(t *testing.T) {
_, _, validaterrors := validateSubmission("hamburger", "13", "5")
_, _, _, validaterrors := validateSubmission("http://foo.com", "13", "5")
requireHasError(t, validaterrors["max_salary"])
})

Expand Down

0 comments on commit 0225626

Please sign in to comment.