• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

source-academy / backend / e0330f2cf38b2d8af12bffd20f4cac2158d607fc-PR-1236

31 Mar 2025 09:12AM UTC coverage: 19.982% (-73.6%) from 93.607%
e0330f2cf38b2d8af12bffd20f4cac2158d607fc-PR-1236

Pull #1236

github

RichDom2185
Redate migrations to maintain total ordering
Pull Request #1236: Added Exam mode

12 of 57 new or added lines in 8 files covered. (21.05%)

2430 existing lines in 97 files now uncovered.

671 of 3358 relevant lines covered (19.98%)

3.03 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

80.95
/lib/cadet/courses/course.ex
1
defmodule Cadet.Courses.Course do
2
  @moduledoc """
3
  The Course entity stores the configuration of a particular course.
4
  """
5
  use Cadet, :model
6

7
  alias Cadet.Courses.AssessmentConfig
8

9
  @type t :: %__MODULE__{
10
          course_name: String.t(),
11
          course_short_name: String.t(),
12
          viewable: boolean(),
13
          enable_game: boolean(),
14
          enable_achievements: boolean(),
15
          enable_sourcecast: boolean(),
16
          enable_stories: boolean(),
17
          enable_exam_mode: boolean(),
18
          resume_code: string(),
19
          is_official_course: boolean(),
20
          source_chapter: integer(),
21
          source_variant: String.t(),
22
          module_help_text: String.t(),
23
          assets_prefix: String.t() | nil
24
        }
25

26
  schema "courses" do
2,351✔
27
    field(:course_name, :string)
28
    field(:course_short_name, :string)
29
    field(:viewable, :boolean, default: true)
30
    field(:enable_game, :boolean, default: true)
31
    field(:enable_achievements, :boolean, default: true)
32
    field(:enable_sourcecast, :boolean, default: true)
33
    field(:enable_stories, :boolean, default: false)
34
    field(:enable_exam_mode, :boolean, default: false)
35
    field(:resume_code, :string)
36
    field(:is_official_course, :boolean, default: false)
37
    field(:source_chapter, :integer)
38
    field(:source_variant, :string)
39
    field(:module_help_text, :string)
40

41
    # for now, only settable from database
42
    field(:assets_prefix, :string, default: nil)
43

44
    has_many(:assessment_config, AssessmentConfig)
45

46
    timestamps()
47
  end
48

49
  @required_fields ~w(course_name viewable enable_game
50
    enable_exam_mode enable_achievements enable_sourcecast enable_stories source_chapter source_variant)a
51
  @optional_fields ~w(course_short_name module_help_text resume_code)a
52

53
  def changeset(course, params) do
54
    course
55
    |> cast(params, @required_fields ++ @optional_fields)
56
    |> validate_required(@required_fields)
57
    |> validate_sublanguage_combination(params)
58
    |> validate_exam_mode(params)
21✔
59
  end
60

61
  # Validates combination of exam mode, resume code, and official course state
62
  defp validate_exam_mode(changeset, params) do
63
    resume_code = Map.get(params, :resume_code, "")
21✔
64
    enable_exam_mode = Map.get(params, :enable_exam_mode, false)
21✔
65
    is_official_course = get_field(changeset, :is_official_course, false)
21✔
66

67
    case {enable_exam_mode, is_official_course, resume_code} do
21✔
68
      {false, _, _} ->
69
        changeset
21✔
70

71
      {true, false, _} ->
NEW
72
        add_error(
×
73
          changeset,
74
          :enable_exam_mode,
75
          "Exam mode is only available for official institution course."
76
        )
77

78
      {true, true, ""} ->
NEW
79
        add_error(
×
80
          changeset,
81
          :resume_code,
82
          "Resume code must be set to non-empty value upon enabling of exam mode."
83
        )
84

85
      {_, _, _} ->
NEW
86
        changeset
×
87
    end
88
  end
89

90
  # Validates combination of Source chapter and variant
91
  defp validate_sublanguage_combination(changeset, params) do
92
    chap = Map.has_key?(params, :source_chapter)
21✔
93
    var = Map.has_key?(params, :source_variant)
21✔
94

95
    # not (chap xor var)
96
    case {chap, var} do
21✔
97
      {true, true} ->
98
        case get_field(changeset, :source_chapter) do
19✔
99
          1 ->
100
            validate_inclusion(changeset, :source_variant, [
11✔
101
              "default",
102
              "lazy",
103
              "wasm",
104
              "native",
105
              "typed"
106
            ])
107

108
          2 ->
109
            validate_inclusion(changeset, :source_variant, ["default", "lazy", "native", "typed"])
3✔
110

111
          3 ->
112
            validate_inclusion(changeset, :source_variant, [
2✔
113
              "default",
114
              "concurrent",
115
              "non-det",
116
              "native",
117
              "typed"
118
            ])
119

120
          4 ->
121
            validate_inclusion(changeset, :source_variant, ["default", "gpu", "native"])
2✔
122

123
          _ ->
124
            add_error(changeset, :source_chapter, "is invalid")
1✔
125
        end
126

127
      {false, false} ->
UNCOV
128
        changeset
×
129

130
      {_, _} ->
131
        add_error(
2✔
132
          changeset,
133
          :source_chapter,
134
          "source chapter and source variant must be present together"
135
        )
136
    end
137
  end
138
end
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc