1+ defmodule Cadet.TokenExchangeTest do
2+ use Cadet.DataCase
3+
4+ alias Cadet.TokenExchange
5+
6+ describe "get_by_code" do
7+ test "returns error when code not found" do
8+ result = TokenExchange . get_by_code ( "nonexistent_code" )
9+ assert { :error , "Not found" } == result
10+ end
11+
12+ test "returns error when code is expired" do
13+ user = insert ( :user )
14+
15+ TokenExchange . insert ( % {
16+ code: "expired_code" ,
17+ generated_at: Timex . shift ( Timex . now ( ) , hours: - 2 ) ,
18+ expires_at: Timex . shift ( Timex . now ( ) , hours: - 1 ) ,
19+ user_id: user . id
20+ } )
21+
22+ result = TokenExchange . get_by_code ( "expired_code" )
23+ assert { :error , "Expired" } == result
24+ end
25+
26+ test "returns ok with user when code is valid and not expired" do
27+ user = insert ( :user )
28+ code = "valid_code_123"
29+
30+ { :ok , token } =
31+ TokenExchange . insert ( % {
32+ code: code ,
33+ generated_at: Timex . now ( ) ,
34+ expires_at: Timex . shift ( Timex . now ( ) , minutes: 5 ) ,
35+ user_id: user . id
36+ } )
37+
38+ assert { :ok , struct } = TokenExchange . get_by_code ( code )
39+ assert struct . code == code
40+ assert struct . user . id == user . id
41+ end
42+
43+ test "deletes the code after successful retrieval" do
44+ user = insert ( :user )
45+ code = "code_to_delete"
46+
47+ TokenExchange . insert ( % {
48+ code: code ,
49+ generated_at: Timex . now ( ) ,
50+ expires_at: Timex . shift ( Timex . now ( ) , minutes: 5 ) ,
51+ user_id: user . id
52+ } )
53+
54+ # First retrieval should succeed
55+ assert { :ok , _struct } = TokenExchange . get_by_code ( code )
56+
57+ # Second retrieval should fail as the code was deleted
58+ assert { :error , "Not found" } = TokenExchange . get_by_code ( code )
59+ end
60+
61+ test "preloads user association" do
62+ user = insert ( :user , name: "Test User" )
63+ code = "code_with_user"
64+
65+ TokenExchange . insert ( % {
66+ code: code ,
67+ generated_at: Timex . now ( ) ,
68+ expires_at: Timex . shift ( Timex . now ( ) , minutes: 5 ) ,
69+ user_id: user . id
70+ } )
71+
72+ { :ok , struct } = TokenExchange . get_by_code ( code )
73+ assert struct . user . name == "Test User"
74+ end
75+ end
76+
77+ describe "delete_expired" do
78+ test "deletes all expired tokens" do
79+ user1 = insert ( :user )
80+ user2 = insert ( :user )
81+
82+ # Insert expired tokens
83+ TokenExchange . insert ( % {
84+ code: "expired_1" ,
85+ generated_at: Timex . shift ( Timex . now ( ) , hours: - 2 ) ,
86+ expires_at: Timex . shift ( Timex . now ( ) , minutes: - 30 ) ,
87+ user_id: user1 . id
88+ } )
89+
90+ TokenExchange . insert ( % {
91+ code: "expired_2" ,
92+ generated_at: Timex . shift ( Timex . now ( ) , hours: - 1 ) ,
93+ expires_at: Timex . shift ( Timex . now ( ) , minutes: - 15 ) ,
94+ user_id: user2 . id
95+ } )
96+
97+ # Insert valid token
98+ TokenExchange . insert ( % {
99+ code: "valid_token" ,
100+ generated_at: Timex . now ( ) ,
101+ expires_at: Timex . shift ( Timex . now ( ) , minutes: 10 ) ,
102+ user_id: user1 . id
103+ } )
104+
105+ # Execute delete_expired
106+ { deleted_count , _ } = TokenExchange . delete_expired ( )
107+
108+ assert deleted_count == 2
109+ # Verify valid token still exists
110+ assert { :ok , _ } = TokenExchange . get_by_code ( "valid_token" )
111+ end
112+ end
113+
114+ describe "insert" do
115+ test "creates a new token exchange record" do
116+ user = insert ( :user )
117+ code = "test_code_insert"
118+
119+ { :ok , token } =
120+ TokenExchange . insert ( % {
121+ code: code ,
122+ generated_at: Timex . now ( ) ,
123+ expires_at: Timex . shift ( Timex . now ( ) , minutes: 5 ) ,
124+ user_id: user . id
125+ } )
126+
127+ assert token . code == code
128+ assert token . user_id == user . id
129+ end
130+
131+ test "fails when required fields are missing" do
132+ user = insert ( :user )
133+
134+ { :error , changeset } =
135+ TokenExchange . insert ( % {
136+ code: "incomplete_code" ,
137+ user_id: user . id
138+ } )
139+
140+ refute changeset . valid?
141+ end
142+ end
143+
144+ describe "changeset" do
145+ test "validates required fields" do
146+ user = insert ( :user )
147+
148+ changeset =
149+ TokenExchange . changeset ( % TokenExchange { } , % {
150+ code: "test_code" ,
151+ generated_at: Timex . now ( ) ,
152+ expires_at: Timex . shift ( Timex . now ( ) , minutes: 5 ) ,
153+ user_id: user . id
154+ } )
155+
156+ assert changeset . valid?
157+ end
158+
159+ test "marks changeset invalid when required fields are missing" do
160+ changeset =
161+ TokenExchange . changeset ( % TokenExchange { } , % {
162+ code: "test_code"
163+ } )
164+
165+ refute changeset . valid?
166+ assert Keyword . has_key? ( changeset . errors , :generated_at )
167+ assert Keyword . has_key? ( changeset . errors , :expires_at )
168+ assert Keyword . has_key? ( changeset . errors , :user_id )
169+ end
170+ end
171+ end
0 commit comments